Skip to content

Commit 319feac

Browse files
authored
[clang][bytecode] Fix AccessKinds in placement new CheckStore() call (#141123)
CheckStore is for assignments, but we're constructing something here, so pass AK_Construct instead. We already diagnosed the test case, but as an assignment.
1 parent 0240129 commit 319feac

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1703,9 +1703,25 @@ 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+
// Similar to CheckStore(), but with the additional CheckTemporary() call and
1707+
// the AccessKinds are different.
17061708
if (!CheckTemporary(S, OpPC, Ptr, AK_Construct))
17071709
return false;
1708-
if (!CheckStore(S, OpPC, Ptr))
1710+
if (!CheckLive(S, OpPC, Ptr, AK_Construct))
1711+
return false;
1712+
if (!CheckDummy(S, OpPC, Ptr, AK_Construct))
1713+
return false;
1714+
if (!CheckLifetime(S, OpPC, Ptr, AK_Construct))
1715+
return false;
1716+
if (!CheckExtern(S, OpPC, Ptr))
1717+
return false;
1718+
if (!CheckRange(S, OpPC, Ptr, AK_Construct))
1719+
return false;
1720+
if (!CheckGlobal(S, OpPC, Ptr))
1721+
return false;
1722+
if (!CheckConst(S, OpPC, Ptr))
1723+
return false;
1724+
if (!S.inConstantContext() && isConstexprUnknown(Ptr))
17091725
return false;
17101726

17111727
if (!InvalidNewDeleteExpr(S, OpPC, E))

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ namespace std {
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'}} \
1818
// 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}}
20-
19+
// both-note {{construction of temporary is not allowed}} \
20+
// both-note {{construction of heap allocated object that has been deleted}}
2121
}
2222
}
2323

@@ -398,3 +398,14 @@ namespace Temp {
398398
static_assert((std::construct_at<int>(&temporary, 1), true)); // both-error{{not an integral constant expression}} \
399399
// both-note {{in call}}
400400
}
401+
402+
namespace PlacementNewAfterDelete {
403+
constexpr bool construct_after_lifetime() {
404+
int *p = new int;
405+
delete p;
406+
std::construct_at<int>(p); // both-note {{in call}}
407+
return true;
408+
}
409+
static_assert(construct_after_lifetime()); // both-error {{}} \
410+
// both-note {{in call}}
411+
}

0 commit comments

Comments
 (0)