Author: rsmith Date: Mon Sep 30 17:07:14 2019 New Revision: 373276 URL: http://llvm.org/viewvc/llvm-project?rev=373276&view=rev Log: [c++20] Fix crash when constant-evaluating an assignment with a reference member access on its left-hand side.
Modified: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=373276&r1=373275&r2=373276&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Sep 30 17:07:14 2019 @@ -5258,7 +5258,9 @@ static bool HandleUnionActiveMemberChang // -- If E is of the form A.B, S(E) contains the elements of S(A)... if (auto *ME = dyn_cast<MemberExpr>(E)) { auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()); - if (!FD) + // Note that we can't implicitly start the lifetime of a reference, + // so we don't need to proceed any further if we reach one. + if (!FD || FD->getType()->isReferenceType()) break; // ... and also contains A.B if B names a union member Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp?rev=373276&r1=373275&r2=373276&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp (original) +++ cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp Mon Sep 30 17:07:14 2019 @@ -561,6 +561,29 @@ namespace Union { S3 s; s.n = 0; } + + union ref_member_1 { + int a; + int b; + }; + struct ref_member_2 { + ref_member_1 &&r; + }; + union ref_member_3 { + ref_member_2 a, b; + }; + constexpr int ref_member_test_1() { + ref_member_3 r = {.a = {.r = {.a = 1}}}; + r.a.r.b = 2; + return r.a.r.b; + } + static_assert(ref_member_test_1() == 2); + constexpr int ref_member_test_2() { // expected-error {{never produces a constant}} + ref_member_3 r = {.a = {.r = {.a = 1}}}; + // FIXME: This note isn't great. The 'read' here is reading the referent of the reference. + r.b.r.b = 2; // expected-note {{read of member 'b' of union with active member 'a'}} + return r.b.r.b; + } } namespace TwosComplementShifts { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits