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}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
