]> granicus.if.org Git - clang/commitdiff
PR43629: Fix crash evaluating constexpr placement new on a subobject of
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 10 Oct 2019 22:31:17 +0000 (22:31 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 10 Oct 2019 22:31:17 +0000 (22:31 +0000)
an out-of-lifetime object.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374465 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticASTKinds.td
lib/AST/ExprConstant.cpp
test/SemaCXX/cxx2a-constexpr-dynalloc.cpp

index 63207a0e2254a9c8522786d124c44c09dc7215cd..04d767445a8f4359b9563adf7c60cb9a557d1858 100644 (file)
@@ -126,7 +126,8 @@ def note_constexpr_lifetime_ended : Note<
   "%plural{8:storage duration|:lifetime}0 has ended">;
 def note_constexpr_access_uninit : Note<
   "%select{read of|read of|assignment to|increment of|decrement of|"
-  "member call on|dynamic_cast of|typeid applied to|<ERRPR>|destruction of}0 "
+  "member call on|dynamic_cast of|typeid applied to|"
+  "construction of subobject of|destruction of}0 "
   "%select{object outside its lifetime|uninitialized object}1 "
   "is not allowed in a constant expression">;
 def note_constexpr_use_uninit_reference : Note<
index 070f784be45c8109eee5d14e8222cd1cdbdd9557..ceee50da30937816ed8197634c2d3ac9a91665f8 100644 (file)
@@ -3178,7 +3178,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
   // Walk the designator's path to find the subobject.
   for (unsigned I = 0, N = Sub.Entries.size(); /**/; ++I) {
     // Reading an indeterminate value is undefined, but assigning over one is OK.
-    if ((O->isAbsent() && handler.AccessKind != AK_Construct) ||
+    if ((O->isAbsent() && !(handler.AccessKind == AK_Construct && I == N)) ||
         (O->isIndeterminate() && handler.AccessKind != AK_Construct &&
          handler.AccessKind != AK_Assign &&
          handler.AccessKind != AK_ReadObjectRepresentation)) {
index 23582f2e3026eeadf48f43ac9389846fb88d4068..3647526ff0af715001a5c6e940c9dc1f72a057c7 100644 (file)
@@ -166,3 +166,13 @@ constexpr bool construct_after_lifetime() {
   return true;
 }
 static_assert(construct_after_lifetime()); // expected-error {{}} expected-note {{in call}}
+
+constexpr bool construct_after_lifetime_2() {
+  struct A { struct B {} b; };
+  A a;
+  a.~A();
+  std::construct_at<A::B>(&a.b); // expected-note {{in call}}
+  // expected-note@#new {{construction of subobject of object outside its lifetime is not allowed in a constant expression}}
+  return true;
+}
+static_assert(construct_after_lifetime_2()); // expected-error {{}} expected-note {{in call}}