Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -397,7 +397,11 @@ const Record *R = getRecord(RD); const Record::Field *F = R->getField(FD); // Leave a pointer to the field on the stack. - return this->emitGetPtrField(F->Offset, E); + if (!this->emitGetPtrField(F->Offset, E)) + return false; + if (F->Decl->getType()->isReferenceType()) + return this->emitLoadPopPtr(E); + return true; } return false; @@ -871,7 +875,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/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, "");