[clang] 3b8f9a2 - [clang][bytecode] Loosen assertion This() for array elements (#130399)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 8 04:13:56 PST 2025
Author: Timm Baeder
Date: 2025-03-08T13:13:52+01:00
New Revision: 3b8f9a228c5f12f282778b18117b9a88c07e87cb
URL: https://github.com/llvm/llvm-project/commit/3b8f9a228c5f12f282778b18117b9a88c07e87cb
DIFF: https://github.com/llvm/llvm-project/commit/3b8f9a228c5f12f282778b18117b9a88c07e87cb.diff
LOG: [clang][bytecode] Loosen assertion This() for array elements (#130399)
getRecord() returns null on array elements, even for composite arrays.
The assertion here was overly restrictive and having an array element as
instance pointer should be fine otherwise.
Added:
Modified:
clang/lib/AST/ByteCode/Interp.h
clang/test/AST/ByteCode/placement-new.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 401bbefaf9a92..f2ddeac99cd7e 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2432,9 +2432,12 @@ inline bool This(InterpState &S, CodePtr OpPC) {
// Ensure the This pointer has been cast to the correct base.
if (!This.isDummy()) {
assert(isa<CXXMethodDecl>(S.Current->getFunction()->getDecl()));
- assert(This.getRecord());
+ [[maybe_unused]] const Record *R = This.getRecord();
+ if (!R)
+ R = This.narrow().getRecord();
+ assert(R);
assert(
- This.getRecord()->getDecl() ==
+ R->getDecl() ==
cast<CXXMethodDecl>(S.Current->getFunction()->getDecl())->getParent());
}
diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp
index 7a4fc89a27dac..c353162a7aab0 100644
--- a/clang/test/AST/ByteCode/placement-new.cpp
+++ b/clang/test/AST/ByteCode/placement-new.cpp
@@ -339,6 +339,30 @@ namespace PR48606 {
static_assert(f());
}
+/// This used to crash because of an assertion in the implementation
+/// of the This instruction.
+namespace ExplicitThisOnArrayElement {
+ struct S {
+ int a = 12;
+ constexpr S(int a) {
+ this->a = a;
+ }
+ };
+
+ template <class _Tp, class... _Args>
+ constexpr void construct_at(_Tp *__location, _Args &&...__args) {
+ new (__location) _Tp(__args...);
+ }
+
+ constexpr bool foo() {
+ auto *M = std::allocator<S>().allocate(13); // both-note {{allocation performed here was not deallocated}}
+ construct_at(M, 12);
+ return true;
+ }
+
+ static_assert(foo()); // both-error {{not an integral constant expression}}
+}
+
#ifdef BYTECODE
constexpr int N = [] // expected-error {{must be initialized by a constant expression}} \
// expected-note {{assignment to dereferenced one-past-the-end pointer is not allowed in a constant expression}} \
More information about the cfe-commits
mailing list