https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/156658

If we create an implicit local variable for a derived-to-base cast, we still 
should allocate enough space for the entire derived type.

Fixes #156219

>From 5f828f2b002b1d23b7b6577801b296b4b894d7c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Wed, 3 Sep 2025 14:45:20 +0200
Subject: [PATCH] [clang][bytecode] Create implicit variables for wider base
 types

If we create an implicit local variable for a derived-to-base cast,
we still should allocate enough space for the entire derived type.

Fixes #156219
---
 clang/lib/AST/ByteCode/Compiler.cpp | 27 ++++++++++++++-------------
 clang/test/AST/ByteCode/cxx03.cpp   | 11 +++++++++++
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 56552f3969216..2e89a1898bbe0 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4191,6 +4191,19 @@ template <class Emitter> bool 
Compiler<Emitter>::delegate(const Expr *E) {
   return this->Visit(E);
 }
 
+static const Expr *stripDerivedToBaseCasts(const Expr *E) {
+  if (const auto *PE = dyn_cast<ParenExpr>(E))
+    return stripDerivedToBaseCasts(PE->getSubExpr());
+
+  if (const auto *CE = dyn_cast<CastExpr>(E);
+      CE && (CE->getCastKind() == CK_DerivedToBase ||
+             CE->getCastKind() == CK_UncheckedDerivedToBase ||
+             CE->getCastKind() == CK_NoOp))
+    return stripDerivedToBaseCasts(CE->getSubExpr());
+
+  return E;
+}
+
 template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) {
   if (E->getType().isNull())
     return false;
@@ -4201,7 +4214,7 @@ template <class Emitter> bool 
Compiler<Emitter>::visit(const Expr *E) {
   // Create local variable to hold the return value.
   if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
       !canClassify(E->getType())) {
-    UnsignedOrNone LocalIndex = allocateLocal(E);
+    UnsignedOrNone LocalIndex = allocateLocal(stripDerivedToBaseCasts(E));
     if (!LocalIndex)
       return false;
 
@@ -5079,18 +5092,6 @@ bool Compiler<Emitter>::VisitBuiltinCallExpr(const 
CallExpr *E,
   return true;
 }
 
-static const Expr *stripDerivedToBaseCasts(const Expr *E) {
-  if (const auto *PE = dyn_cast<ParenExpr>(E))
-    return stripDerivedToBaseCasts(PE->getSubExpr());
-
-  if (const auto *CE = dyn_cast<CastExpr>(E);
-      CE &&
-      (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp))
-    return stripDerivedToBaseCasts(CE->getSubExpr());
-
-  return E;
-}
-
 template <class Emitter>
 bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
   const FunctionDecl *FuncDecl = E->getDirectCallee();
diff --git a/clang/test/AST/ByteCode/cxx03.cpp 
b/clang/test/AST/ByteCode/cxx03.cpp
index 70ae4134842b5..10e5232b9f873 100644
--- a/clang/test/AST/ByteCode/cxx03.cpp
+++ b/clang/test/AST/ByteCode/cxx03.cpp
@@ -29,3 +29,14 @@ void LambdaAccessingADummy() {
   int d;
   int a9[1] = {[d = 0] = 1}; // both-error {{is not an integral constant 
expression}}
 }
+
+const int p = 10;
+struct B {
+  int a;
+  void *p;
+};
+struct B2 : B {
+  void *q;
+};
+_Static_assert(&(B2().a) == &p, ""); // both-error {{taking the address of a 
temporary object of type 'int'}} \
+                                     // both-error {{not an integral 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