r373276 - [c++20] Fix crash when constant-evaluating an assignment with a
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 30 17:07:14 PDT 2019
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 {
More information about the cfe-commits
mailing list