Skip to content

Commit 87b6ec3

Browse files
authored
[clang][bytecode] Diagnose placement-new construction to inactive field (#114047)
We can reuse CheckActive() for this.
1 parent f490697 commit 87b6ec3

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,11 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
14511451
<< StorageType << AllocType;
14521452
return false;
14531453
}
1454+
1455+
// Can't activate fields in a union, unless the direct base is the union.
1456+
if (Ptr.inUnion() && !Ptr.isActive() && !Ptr.getBase().getRecord()->isUnion())
1457+
return CheckActive(S, OpPC, Ptr, AK_Construct);
1458+
14541459
return true;
14551460
}
14561461

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ namespace std {
1414
template<typename T, typename ...Args>
1515
constexpr void construct_at(void *p, Args &&...args) {
1616
new (p) T((Args&&)args...); // both-note {{in call to}} \
17-
// both-note {{placement new would change type of storage from 'int' to 'float'}}
17+
// 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}}
19+
1820
}
1921
}
2022

@@ -284,6 +286,18 @@ namespace ConstructAt {
284286
static_assert(bad_construct_at_type()); // both-error {{not an integral constant expression}} \
285287
// both-note {{in call}}
286288

289+
constexpr bool bad_construct_at_subobject() {
290+
struct X { int a, b; };
291+
union A {
292+
int a;
293+
X x;
294+
};
295+
A a = {1};
296+
std::construct_at<int>(&a.x.a, 1); // both-note {{in call}}
297+
return true;
298+
}
299+
static_assert(bad_construct_at_subobject()); // both-error{{not an integral constant expression}} \
300+
// both-note {{in call}}
287301
}
288302

289303
namespace UsedToCrash {

0 commit comments

Comments
 (0)