[clang] 923340b - [clang][bytecode] Fix placement new on multidimensional array elements (#191766)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 13 01:37:30 PDT 2026
Author: Timm Baeder
Date: 2026-04-13T10:37:26+02:00
New Revision: 923340b3786470c140598fa7203050786957c484
URL: https://github.com/llvm/llvm-project/commit/923340b3786470c140598fa7203050786957c484
DIFF: https://github.com/llvm/llvm-project/commit/923340b3786470c140598fa7203050786957c484.diff
LOG: [clang][bytecode] Fix placement new on multidimensional array elements (#191766)
The direct base of those pointers is not a union, i.e. `getRecord()`
returns `nullptr`.
Added:
Modified:
clang/lib/AST/ByteCode/Interp.cpp
clang/test/AST/ByteCode/placement-new.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 3d75d5c857cf1..f4d6ef4dc8bd6 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1990,7 +1990,12 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
std::optional<uint64_t> ArraySize) {
const Pointer &Ptr = S.Stk.peek<Pointer>();
- if (Ptr.inUnion() && Ptr.getBase().getRecord()->isUnion())
+ auto directBaseIsUnion = [](const Pointer &Ptr) -> bool {
+ const Record *R = Ptr.getBase().getRecord();
+ return R && R->isUnion();
+ };
+
+ if (Ptr.inUnion() && directBaseIsUnion(Ptr))
Ptr.activate();
if (Ptr.isZero()) {
@@ -2071,7 +2076,7 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
}
// Can't activate fields in a union, unless the direct base is the union.
- if (Ptr.inUnion() && !Ptr.isActive() && !Ptr.getBase().getRecord()->isUnion())
+ if (Ptr.inUnion() && !Ptr.isActive() && !directBaseIsUnion(Ptr))
return CheckActive(S, OpPC, Ptr, AK_Construct);
return true;
diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp
index 2c302ef7a8e7b..6091ab5602121 100644
--- a/clang/test/AST/ByteCode/placement-new.cpp
+++ b/clang/test/AST/ByteCode/placement-new.cpp
@@ -524,3 +524,18 @@ static_assert(intDestArray() == 0); // both-error {{not an integral constant exp
constexpr void invalidDest() { new (undefinedfunction()) int; } // both-error {{use of undeclared identifier 'undefinedfunction'}}
static_assert((invalidDest(), true)); // both-error {{not an integral constant expression}}
+
+namespace DirectBaseHasNoRecord {
+ constexpr int test_multidim_single_start() {
+ struct S {
+ union {
+ int storage[2][3];
+ };
+ };
+ S s;
+ new (&s.storage[0][0]) int(1); // both-note {{construction of subobject of member 'storage' of union with no active member is not allowed in a constant expression}}
+ return 13;
+ }
+ static_assert(test_multidim_single_start() == 13); // both-error {{not an integral constant expression}} \
+ // both-note {{in call to}}
+}
More information about the cfe-commits
mailing list