]> granicus.if.org Git - clang/commitdiff
[c++20] Fix crash when constant-evaluating an assignment with a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 1 Oct 2019 00:07:14 +0000 (00:07 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 1 Oct 2019 00:07:14 +0000 (00:07 +0000)
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

lib/AST/ExprConstant.cpp
test/SemaCXX/constant-expression-cxx2a.cpp

index f91e0782b89ca4dd4116024aafa2213c0ee48469..5659a0eced67c4fb7c4069965329b5140cfeae70 100644 (file)
@@ -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
index 08fcfdd281362d22512405f819daf0ff075c8bcc..2f23975e2e9661eae14ce3390badfe6b2bcbe012 100644 (file)
@@ -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 {