diff options
Diffstat (limited to 'clang/lib/AST/Interp/Pointer.cpp')
-rw-r--r-- | clang/lib/AST/Interp/Pointer.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index ef2638e2a36b..fd8c98fae039 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -16,6 +16,9 @@ using namespace clang::interp; Pointer::Pointer(Block *Pointee) : Pointer(Pointee, 0, 0) {} +Pointer::Pointer(Block *Pointee, unsigned BaseAndOffset) + : Pointer(Pointee, BaseAndOffset, BaseAndOffset) {} + Pointer::Pointer(const Pointer &P) : Pointer(P.Pointee, P.Base, P.Offset) {} Pointer::Pointer(Pointer &&P) @@ -106,7 +109,7 @@ APValue Pointer::toAPValue() const { // Build the path into the object. Pointer Ptr = *this; - while (Ptr.isField()) { + while (Ptr.isField() || Ptr.isArrayElement()) { if (Ptr.isArrayElement()) { Path.push_back(APValue::LValuePathEntry::ArrayIndex(Ptr.getIndex())); Ptr = Ptr.getArray(); @@ -129,14 +132,21 @@ APValue Pointer::toAPValue() const { } } + // We assemble the LValuePath starting from the innermost pointer to the + // outermost one. SO in a.b.c, the first element in Path will refer to + // the field 'c', while later code expects it to refer to 'a'. + // Just invert the order of the elements. + std::reverse(Path.begin(), Path.end()); + return APValue(Base, Offset, Path, IsOnePastEnd, IsNullPtr); } bool Pointer::isInitialized() const { assert(Pointee && "Cannot check if null pointer was initialized"); Descriptor *Desc = getFieldDesc(); + assert(Desc); if (Desc->isPrimitiveArray()) { - if (Pointee->IsStatic) + if (isStatic() && Base == 0) return true; // Primitive array field are stored in a bitset. InitMap *Map = getInitMap(); @@ -154,8 +164,14 @@ bool Pointer::isInitialized() const { void Pointer::initialize() const { assert(Pointee && "Cannot initialize null pointer"); Descriptor *Desc = getFieldDesc(); - if (Desc->isPrimitiveArray()) { - if (!Pointee->IsStatic) { + + assert(Desc); + if (Desc->isArray()) { + if (Desc->isPrimitiveArray()) { + // Primitive global arrays don't have an initmap. + if (isStatic() && Base == 0) + return; + // Primitive array initializer. InitMap *&Map = getInitMap(); if (Map == (InitMap *)-1) @@ -189,5 +205,5 @@ bool Pointer::hasSameBase(const Pointer &A, const Pointer &B) { } bool Pointer::hasSameArray(const Pointer &A, const Pointer &B) { - return A.Base == B.Base && A.getFieldDesc()->IsArray; + return hasSameBase(A, B) && A.Base == B.Base && A.getFieldDesc()->IsArray; } |