Skip to content

Commit 3280596

Browse files
authored
[clang][bytecode] Diagnose placement-new'ing to a temporary (#141099)
... that's been created in a different evaluation.
1 parent 02ed6d8 commit 3280596

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,8 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
17031703
std::optional<uint64_t> ArraySize) {
17041704
const Pointer &Ptr = S.Stk.peek<Pointer>();
17051705

1706+
if (!CheckTemporary(S, OpPC, Ptr, AK_Construct))
1707+
return false;
17061708
if (!CheckStore(S, OpPC, Ptr))
17071709
return false;
17081710

clang/test/AST/ByteCode/placement-new.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ namespace std {
1515
constexpr void construct_at(void *p, Args &&...args) {
1616
new (p) T((Args&&)args...); // both-note {{in call to}} \
1717
// both-note {{placement new would change type of storage from 'int' to 'float'}} \
18-
// both-note {{construction of subobject of member 'x' of union with active member 'a' is not allowed in a constant expression}}
18+
// both-note {{construction of subobject of member 'x' of union with active member 'a' is not allowed in a constant expression}} \
19+
// both-note {{construction of temporary is not allowed}}
1920

2021
}
2122
}
@@ -391,3 +392,9 @@ namespace MemMove {
391392

392393
static_assert(foo() == 123);
393394
}
395+
396+
namespace Temp {
397+
constexpr int &&temporary = 0; // both-note {{created here}}
398+
static_assert((std::construct_at<int>(&temporary, 1), true)); // both-error{{not an integral constant expression}} \
399+
// both-note {{in call}}
400+
}

0 commit comments

Comments
 (0)