https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/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.

>From a4327462a417aebd592dd5b25c2cceb2489286e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Sat, 8 Mar 2025 07:22:59 +0100
Subject: [PATCH] [clang][bytecode] Loosen assertion This() for array elements

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.
---
 clang/lib/AST/ByteCode/Interp.h           |  7 +++++--
 clang/test/AST/ByteCode/placement-new.cpp | 24 +++++++++++++++++++++++
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index d8f90e45b0ced..8a36db1cd84b4 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2431,9 +2431,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}} \

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to