Skip to content

Commit

Permalink
DSliceValue: Don't cache *extracted* length & ptr (#2997)
Browse files Browse the repository at this point in the history
As they may be extracted earlier in an unrelated basic block.
Fixes #2996.
  • Loading branch information
kinke authored Feb 12, 2019
1 parent 020c96b commit 4b101ba
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 13 deletions.
19 changes: 8 additions & 11 deletions gen/dvalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,29 +80,26 @@ DConstValue::DConstValue(Type *t, LLConstant *con) : DRValue(t, con) {

////////////////////////////////////////////////////////////////////////////////

DSliceValue::DSliceValue(Type *t, LLValue *pair) : DRValue(t, pair) {
DSliceValue::DSliceValue(Type *t, LLValue *pair, LLValue *length, LLValue *ptr)
: DRValue(t, pair), length(length), ptr(ptr) {
assert(t->toBasetype()->ty == Tarray);
// v may be an addrspace qualified pointer so strip it before doing a pointer
// equality check.
assert(stripAddrSpaces(pair->getType()) == DtoType(t));
}

DSliceValue::DSliceValue(Type *t, LLValue *pair)
: DSliceValue(t, pair, nullptr, nullptr) {}

DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
: DSliceValue(t, DtoAggrPair(length, ptr)) {
cachedLength = length;
cachedPtr = ptr;
}
: DSliceValue(t, DtoAggrPair(length, ptr), length, ptr) {}

LLValue *DSliceValue::getLength() {
if (!cachedLength)
cachedLength = DtoExtractValue(val, 0, ".len");
return cachedLength;
return length ? length : DtoExtractValue(val, 0, ".len");
}

LLValue *DSliceValue::getPtr() {
if (!cachedPtr)
cachedPtr = DtoExtractValue(val, 1, ".ptr");
return cachedPtr;
return ptr ? ptr : DtoExtractValue(val, 1, ".ptr");
}

////////////////////////////////////////////////////////////////////////////////
Expand Down
7 changes: 5 additions & 2 deletions gen/dvalue.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,11 @@ class DNullValue : public DConstValue {

/// Represents a D slice (dynamic array).
class DSliceValue : public DRValue {
llvm::Value *cachedLength = nullptr;
llvm::Value *cachedPtr = nullptr;
llvm::Value *const length = nullptr;
llvm::Value *const ptr = nullptr;

DSliceValue(Type *t, llvm::Value *pair, llvm::Value *length,
llvm::Value *ptr);

public:
DSliceValue(Type *t, llvm::Value *pair);
Expand Down
20 changes: 20 additions & 0 deletions tests/compilable/gh2996.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %ldc -c %s

struct Table
{
RCArray _elems;

void update(int x)
{
auto e = _elems[0 .. x][x == 0 ? x : $];
}
}

struct RCArray
{
int[] _arr;

inout opSlice(size_t, size_t) { return _arr; }
const length() { return _arr.length; }
const opDollar() { return length; }
}

0 comments on commit 4b101ba

Please sign in to comment.