Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -397,6 +397,8 @@ const Record *R = getRecord(RD); const Record::Field *F = R->getField(FD); // Leave a pointer to the field on the stack. + if (F->Decl->getType()->isReferenceType()) + return this->emitGetField(PT_Ptr, F->Offset, E); return this->emitGetPtrField(F->Offset, E); } @@ -871,7 +873,7 @@ if (!this->emitDupPtr(Initializer)) return false; - if (Optional T = classify(Init->getType())) { + if (Optional T = classify(Init)) { if (!this->visit(Init)) return false; Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -104,7 +104,7 @@ if (const FieldDecl *Member = Init->getMember()) { const Record::Field *F = R->getField(Member); - if (Optional T = this->classify(InitExpr->getType())) { + if (Optional T = this->classify(InitExpr)) { if (!this->emitThis(InitExpr)) return false; Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -478,9 +478,11 @@ return true; } +/// 1) Pops a pointer from the stack +/// 2) Pushes the value of the pointer's field on the stack template ::T> bool GetField(InterpState &S, CodePtr OpPC, uint32_t I) { - const Pointer &Obj = S.Stk.peek(); + const Pointer &Obj = S.Stk.pop(); if (!CheckNull(S, OpPC, Obj, CSK_Field)) return false; if (!CheckRange(S, OpPC, Obj, CSK_Field)) Index: clang/test/AST/Interp/references.cpp =================================================================== --- clang/test/AST/Interp/references.cpp +++ clang/test/AST/Interp/references.cpp @@ -88,3 +88,29 @@ return j; } static_assert(RefToMemberExpr() == 11, ""); + +struct Ref { + int &a; +}; + +constexpr int RecordWithRef() { + int m = 100; + Ref r{m}; + m = 200; + return r.a; +} +static_assert(RecordWithRef() == 200, ""); + + +struct Ref2 { + int &a; + constexpr Ref2(int &a) : a(a) {} +}; + +constexpr int RecordWithRef2() { + int m = 100; + Ref2 r(m); + m = 200; + return r.a; +} +static_assert(RecordWithRef2() == 200, "");