Skip to content

Commit 9a84dc0

Browse files
committed
[c++20] Fix crash when constant-evaluating an assignment with a
reference member access on its left-hand side. llvm-svn: 373276
1 parent f18d747 commit 9a84dc0

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5258,7 +5258,9 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
52585258
// -- If E is of the form A.B, S(E) contains the elements of S(A)...
52595259
if (auto *ME = dyn_cast<MemberExpr>(E)) {
52605260
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
5261-
if (!FD)
5261+
// Note that we can't implicitly start the lifetime of a reference,
5262+
// so we don't need to proceed any further if we reach one.
5263+
if (!FD || FD->getType()->isReferenceType())
52625264
break;
52635265

52645266
// ... and also contains A.B if B names a union member

clang/test/SemaCXX/constant-expression-cxx2a.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,29 @@ namespace Union {
561561
S3 s;
562562
s.n = 0;
563563
}
564+
565+
union ref_member_1 {
566+
int a;
567+
int b;
568+
};
569+
struct ref_member_2 {
570+
ref_member_1 &&r;
571+
};
572+
union ref_member_3 {
573+
ref_member_2 a, b;
574+
};
575+
constexpr int ref_member_test_1() {
576+
ref_member_3 r = {.a = {.r = {.a = 1}}};
577+
r.a.r.b = 2;
578+
return r.a.r.b;
579+
}
580+
static_assert(ref_member_test_1() == 2);
581+
constexpr int ref_member_test_2() { // expected-error {{never produces a constant}}
582+
ref_member_3 r = {.a = {.r = {.a = 1}}};
583+
// FIXME: This note isn't great. The 'read' here is reading the referent of the reference.
584+
r.b.r.b = 2; // expected-note {{read of member 'b' of union with active member 'a'}}
585+
return r.b.r.b;
586+
}
564587
}
565588

566589
namespace TwosComplementShifts {

0 commit comments

Comments
 (0)