[clang] 21e8bb8 - PR48606: The lifetime of a constexpr heap allocation always started
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 8 18:02:55 PST 2021
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());
+}
More information about the cfe-commits
mailing list