reference member access on its left-hand side.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@373276
91177308-0d34-0410-b5e6-
96231b3b80d8
// -- 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
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 {