aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/Interp/Pointer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Interp/Pointer.cpp')
-rw-r--r--clang/lib/AST/Interp/Pointer.cpp26
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;
}