[clang] [clang][bytecode] Fix returne value of array CXXNewExprs (PR #127526)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 17 09:36:57 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
Just like with the __builtin_operator_new version, we need to point to the first array element, not the array element itself.
---
Full diff: https://github.com/llvm/llvm-project/pull/127526.diff
3 Files Affected:
- (modified) clang/lib/AST/ByteCode/Interp.cpp (+2-1)
- (modified) clang/lib/AST/ByteCode/Interp.h (+11-2)
- (modified) clang/test/AST/ByteCode/new-delete.cpp (+14)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index c80be094856b0..0310870f7372e 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1063,7 +1063,8 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
return false;
}
- if (!Ptr.isRoot() || Ptr.isOnePastEnd() || Ptr.isArrayElement()) {
+ if (!Ptr.isRoot() || Ptr.isOnePastEnd() ||
+ (Ptr.isArrayElement() && Ptr.getIndex() != 0)) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_delete_subobject)
<< Ptr.toDiagnosticString(S.getASTContext()) << Ptr.isOnePastEnd();
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 73cc107b7dbff..10cf21e28437c 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2915,13 +2915,17 @@ inline bool AllocN(InterpState &S, CodePtr OpPC, PrimType T, const Expr *Source,
S.Stk.push<Pointer>(0, nullptr);
return true;
}
+ assert(NumElements.isPositive());
DynamicAllocator &Allocator = S.getAllocator();
Block *B =
Allocator.allocate(Source, T, static_cast<size_t>(NumElements),
S.Ctx.getEvalID(), DynamicAllocator::Form::Array);
assert(B);
- S.Stk.push<Pointer>(B);
+ if (NumElements.isZero())
+ S.Stk.push<Pointer>(B);
+ else
+ S.Stk.push<Pointer>(Pointer(B).atIndex(0));
return true;
}
@@ -2941,13 +2945,18 @@ inline bool AllocCN(InterpState &S, CodePtr OpPC, const Descriptor *ElementDesc,
S.Stk.push<Pointer>(0, ElementDesc);
return true;
}
+ assert(NumElements.isPositive());
DynamicAllocator &Allocator = S.getAllocator();
Block *B =
Allocator.allocate(ElementDesc, static_cast<size_t>(NumElements),
S.Ctx.getEvalID(), DynamicAllocator::Form::Array);
assert(B);
- S.Stk.push<Pointer>(B);
+ if (NumElements.isZero())
+ S.Stk.push<Pointer>(B);
+ else
+ S.Stk.push<Pointer>(Pointer(B).atIndex(0));
+
return true;
}
diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp
index e9850d27666e5..7e5f6ab8815ea 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -922,6 +922,20 @@ namespace NonConstexprArrayCtor {
// both-note {{in call to}}
}
+namespace ArrayBaseCast {
+ struct A {};
+ struct B : A {};
+ constexpr bool test() {
+ B *b = new B[2];
+
+ A* a = b;
+
+ delete[] b;
+ return true;
+ }
+ static_assert(test());
+}
+
#else
/// Make sure we reject this prior to C++20
constexpr int a() { // both-error {{never produces a constant expression}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/127526
More information about the cfe-commits
mailing list