From 005fa4c20da15aede1303138bb0ea0b32f8fb31a Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 10 Oct 2019 22:31:17 +0000 Subject: [PATCH] PR43629: Fix crash evaluating constexpr placement new on a subobject of 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 | 3 ++- lib/AST/ExprConstant.cpp | 2 +- test/SemaCXX/cxx2a-constexpr-dynalloc.cpp | 10 ++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index 63207a0e22..04d767445a 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -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||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< diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 070f784be4..ceee50da30 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -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)) { diff --git a/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp b/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp index 23582f2e30..3647526ff0 100644 --- a/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp +++ b/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp @@ -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); // 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}} -- 2.40.0