https://github.com/keinflue updated https://github.com/llvm/llvm-project/pull/174132
>From f925d36a27650e755c6ede3da6e989e10ef2884b Mon Sep 17 00:00:00 2001 From: keinflue <[email protected]> Date: Thu, 1 Jan 2026 07:49:21 +0100 Subject: [PATCH 1/2] [Clang][Bytecode] Fix void*-to-ptr casts originating from new/new[] In void*-to-ptr casts, the type of the pointed-to object in the source operand needs to be compared to the target pointee type. If a block was created for a `new`/`new[]`/`std::allocator` expression, then a pointer needs to be stripped from the type of the expression (which points to the single-object allocation or first element of the allocation) to get the former. `Descriptor::getType` did not do this and `Descriptor::getDataType` returns an array type for array allocations. Therefore this introduces a new function `Descriptor::getDataElemType` with the same behavior as `Descriptor::getDataType`, except that it always produces the element type in the array case and avoids the need for an `ASTContext` reference. Make `Pointer::getType` use this function instead. Fixes #174131 --- clang/lib/AST/ByteCode/Descriptor.cpp | 16 ++++++++++++++++ clang/lib/AST/ByteCode/Descriptor.h | 1 + clang/lib/AST/ByteCode/Pointer.h | 3 ++- clang/test/AST/ByteCode/cxx26.cpp | 11 +++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 2864be8115637..a3cee034191d2 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -433,6 +433,22 @@ QualType Descriptor::getDataType(const ASTContext &Ctx) const { return getType(); } +QualType Descriptor::getDataElemType() const { + if (const auto *E = asExpr()) { + if (isa<CXXNewExpr>(E)) + return E->getType()->getPointeeType(); + + // std::allocator.allocate() call. + if (const auto *ME = dyn_cast<CXXMemberCallExpr>(E); + ME && ME->getRecordDecl()->getName() == "allocator" && + ME->getMethodDecl()->getName() == "allocate") + return E->getType()->getPointeeType(); + return E->getType(); + } + + return getType(); +} + SourceLocation Descriptor::getLocation() const { if (auto *D = dyn_cast<const Decl *>(Source)) return D->getLocation(); diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h index 057f40f8f1f69..5bf550ffe1172 100644 --- a/clang/lib/AST/ByteCode/Descriptor.h +++ b/clang/lib/AST/ByteCode/Descriptor.h @@ -203,6 +203,7 @@ struct Descriptor final { QualType getType() const; QualType getElemQualType() const; QualType getDataType(const ASTContext &Ctx) const; + QualType getDataElemType() const; SourceLocation getLocation() const; SourceInfo getLoc() const; diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index 9032bdade850f..202508cb71e5a 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -354,7 +354,8 @@ class Pointer { if (const auto *CT = getFieldDesc()->getType()->getAs<VectorType>()) return CT->getElementType(); } - return getFieldDesc()->getType(); + + return getFieldDesc()->getDataElemType(); } [[nodiscard]] Pointer getDeclPtr() const { return Pointer(BS.Pointee); } diff --git a/clang/test/AST/ByteCode/cxx26.cpp b/clang/test/AST/ByteCode/cxx26.cpp index cd786b17ca9ab..bc000c0d8b178 100644 --- a/clang/test/AST/ByteCode/cxx26.cpp +++ b/clang/test/AST/ByteCode/cxx26.cpp @@ -9,6 +9,17 @@ namespace VoidCast { constexpr void* p = nullptr; constexpr int* q = static_cast<int*>(p); static_assert(q == nullptr); + + static_assert((delete (int*)(void*)new int, true)); + static_assert((delete[] (int*)(void*)new int[2], true)); + + // both-error@+2 {{not an integral constant expression}} + // both-note@+1 {{cast from 'void *' is not allowed in a constant expression because the pointed object type 'int' is not similar to the target type 'float'}} + static_assert((delete (float*)(void*)new int, true)); + + // both-error@+2 {{not an integral constant expression}} + // both-note@+1 {{cast from 'void *' is not allowed in a constant expression because the pointed object type 'int' is not similar to the target type 'float'}} + static_assert((delete[] (float*)(void*)new int[2], true)); } namespace ReplaceableAlloc { >From 947c87d6561a250b5d945d1266cf94d6fac3f155 Mon Sep 17 00:00:00 2001 From: keinflue <[email protected]> Date: Fri, 2 Jan 2026 17:35:06 +0100 Subject: [PATCH 2/2] Fix review comments --- clang/test/AST/ByteCode/cxx26.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/clang/test/AST/ByteCode/cxx26.cpp b/clang/test/AST/ByteCode/cxx26.cpp index bc000c0d8b178..64461ee9e12cd 100644 --- a/clang/test/AST/ByteCode/cxx26.cpp +++ b/clang/test/AST/ByteCode/cxx26.cpp @@ -13,13 +13,11 @@ namespace VoidCast { static_assert((delete (int*)(void*)new int, true)); static_assert((delete[] (int*)(void*)new int[2], true)); - // both-error@+2 {{not an integral constant expression}} - // both-note@+1 {{cast from 'void *' is not allowed in a constant expression because the pointed object type 'int' is not similar to the target type 'float'}} - static_assert((delete (float*)(void*)new int, true)); + static_assert((delete (float*)(void*)new int, true)); // both-error {{not an integral constant expression}} \ + // both-note {{cast from 'void *' is not allowed in a constant expression because the pointed object type 'int' is not similar to the target type 'float'}} - // both-error@+2 {{not an integral constant expression}} - // both-note@+1 {{cast from 'void *' is not allowed in a constant expression because the pointed object type 'int' is not similar to the target type 'float'}} - static_assert((delete[] (float*)(void*)new int[2], true)); + static_assert((delete[] (float*)(void*)new int[2], true)); // both-error {{not an integral constant expression}} \ + // both-note {{cast from 'void *' is not allowed in a constant expression because the pointed object type 'int' is not similar to the target type 'float'}} } namespace ReplaceableAlloc { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
