Index: clang/lib/AST/Interp/Pointer.cpp =================================================================== --- clang/lib/AST/Interp/Pointer.cpp +++ clang/lib/AST/Interp/Pointer.cpp @@ -148,7 +148,16 @@ } } - return APValue(Base, Offset, Path, IsOnePastEnd, IsNullPtr); + // 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. + decltype(Path) RealPath; + RealPath.resize(Path.size()); + for (unsigned I = 0, N = Path.size(); I != N; ++I) + RealPath[N - 1 - I] = Path[I]; + + return APValue(Base, Offset, RealPath, IsOnePastEnd, IsNullPtr); } bool Pointer::isInitialized() const { Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -153,11 +153,7 @@ constexpr FourBoolPairs LT; // Copy ctor constexpr FourBoolPairs LT2 = LT; -// FIXME: The copy constructor call above -// works, but APValue we generate for it is -// not sufficiently correct, so the lvalue-to-rvalue -// conversion in ExprConstant.c runs into an assertion. -//static_assert(LT2.v[0].first == false, ""); -//static_assert(LT2.v[0].second == false, ""); -//static_assert(LT2.v[2].first == true, ""); -//static_assert(LT2.v[2].second == false, ""); +static_assert(LT2.v[0].first == false, ""); +static_assert(LT2.v[0].second == false, ""); +static_assert(LT2.v[2].first == true, ""); +static_assert(LT2.v[2].second == false, "");