tbaeder created this revision. tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik. Herald added a project: All. tbaeder requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
When assigning to them, we can't classify the expression type, because that doesn't contain the right information. And when reading from them, we need to do the extra deref, just like we do when reading from a DeclRefExpr. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D136012 Files: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeStmtGen.cpp clang/test/AST/Interp/references.cpp 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, ""); 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<PrimType> T = this->classify(InitExpr->getType())) { + if (Optional<PrimType> T = this->classify(InitExpr)) { if (!this->emitThis(InitExpr)) return false; 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<PrimType> T = classify(Init->getType())) { + if (Optional<PrimType> T = classify(Init)) { if (!this->visit(Init)) 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, ""); 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<PrimType> T = this->classify(InitExpr->getType())) { + if (Optional<PrimType> T = this->classify(InitExpr)) { if (!this->emitThis(InitExpr)) return false; 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<PrimType> T = classify(Init->getType())) { + if (Optional<PrimType> T = classify(Init)) { if (!this->visit(Init)) return false;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits