forked from OSchip/llvm-project
[c++20] Fix crash when constant-evaluating an assignment with a
reference member access on its left-hand side. llvm-svn: 373276
This commit is contained in:
parent
f18d747107
commit
9a84dc0b36
|
@ -5258,7 +5258,9 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
|
|||
// -- 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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue