Skip to content

Commit 3b8f9a2

Browse files
authored
[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.
1 parent 73e14de commit 3b8f9a2

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

clang/lib/AST/ByteCode/Interp.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -2432,9 +2432,12 @@ inline bool This(InterpState &S, CodePtr OpPC) {
24322432
// Ensure the This pointer has been cast to the correct base.
24332433
if (!This.isDummy()) {
24342434
assert(isa<CXXMethodDecl>(S.Current->getFunction()->getDecl()));
2435-
assert(This.getRecord());
2435+
[[maybe_unused]] const Record *R = This.getRecord();
2436+
if (!R)
2437+
R = This.narrow().getRecord();
2438+
assert(R);
24362439
assert(
2437-
This.getRecord()->getDecl() ==
2440+
R->getDecl() ==
24382441
cast<CXXMethodDecl>(S.Current->getFunction()->getDecl())->getParent());
24392442
}
24402443

clang/test/AST/ByteCode/placement-new.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,30 @@ namespace PR48606 {
339339
static_assert(f());
340340
}
341341

342+
/// This used to crash because of an assertion in the implementation
343+
/// of the This instruction.
344+
namespace ExplicitThisOnArrayElement {
345+
struct S {
346+
int a = 12;
347+
constexpr S(int a) {
348+
this->a = a;
349+
}
350+
};
351+
352+
template <class _Tp, class... _Args>
353+
constexpr void construct_at(_Tp *__location, _Args &&...__args) {
354+
new (__location) _Tp(__args...);
355+
}
356+
357+
constexpr bool foo() {
358+
auto *M = std::allocator<S>().allocate(13); // both-note {{allocation performed here was not deallocated}}
359+
construct_at(M, 12);
360+
return true;
361+
}
362+
363+
static_assert(foo()); // both-error {{not an integral constant expression}}
364+
}
365+
342366
#ifdef BYTECODE
343367
constexpr int N = [] // expected-error {{must be initialized by a constant expression}} \
344368
// expected-note {{assignment to dereferenced one-past-the-end pointer is not allowed in a constant expression}} \

0 commit comments

Comments
 (0)