Author: Richard Smith Date: 2021-02-08T17:58:05-08:00 New Revision: 21e8bb83253e1a2f4b6fad9b53cafe8c530a38e2
URL: https://github.com/llvm/llvm-project/commit/21e8bb83253e1a2f4b6fad9b53cafe8c530a38e2 DIFF: https://github.com/llvm/llvm-project/commit/21e8bb83253e1a2f4b6fad9b53cafe8c530a38e2.diff LOG: PR48606: The lifetime of a constexpr heap allocation always started during the same evaluation. It looks like the only case for which this matters is determining whether mutable subobjects of a heap allocation can be modified during constant evaluation. Added: Modified: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 1ed9bbea84ee..d27f655011ae 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -3497,8 +3497,8 @@ static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject = false) { - // A temporary we created. - if (Base.getCallIndex()) + // A temporary or transient heap allocation we created. + if (Base.getCallIndex() || Base.is<DynamicAllocLValue>()) return true; switch (Info.IsEvaluatingDecl) { diff --git a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp index 3647526ff0af..097ca00640e9 100644 --- a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp +++ b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp @@ -176,3 +176,37 @@ constexpr bool construct_after_lifetime_2() { return true; } static_assert(construct_after_lifetime_2()); // expected-error {{}} expected-note {{in call}} + +namespace PR48606 { + struct A { mutable int n = 0; }; + + constexpr bool f() { + A a; + A *p = &a; + p->~A(); + std::construct_at<A>(p); + return true; + } + static_assert(f()); + + constexpr bool g() { + A *p = new A; + p->~A(); + std::construct_at<A>(p); + delete p; + return true; + } + static_assert(g()); + + constexpr bool h() { + std::allocator<A> alloc; + A *p = alloc.allocate(1); + std::construct_at<A>(p); + p->~A(); + std::construct_at<A>(p); + p->~A(); + alloc.deallocate(p); + return true; + } + static_assert(h()); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits