https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/156658
>From f5221110b55a8c23beaf4b4d33f857238faa0de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> 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 | 41 +++++++++++++++++++---------- clang/test/AST/ByteCode/cxx03.cpp | 11 ++++++++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 89ff5d27a4143..3f30e524ab179 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -4191,6 +4191,31 @@ template <class Emitter> bool Compiler<Emitter>::delegate(const Expr *E) { return this->Visit(E); } +static const Expr *stripCheckedDerivedToBaseCasts(const Expr *E) { + if (const auto *PE = dyn_cast<ParenExpr>(E)) + return stripCheckedDerivedToBaseCasts(PE->getSubExpr()); + + if (const auto *CE = dyn_cast<CastExpr>(E); + CE && + (CE->getCastKind() == CK_DerivedToBase || CE->getCastKind() == CK_NoOp)) + return stripCheckedDerivedToBaseCasts(CE->getSubExpr()); + + return 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; @@ -4200,7 +4225,7 @@ template <class Emitter> bool Compiler<Emitter>::visit(const Expr *E) { // Create local variable to hold the return value. if (!E->isGLValue() && !canClassify(E->getType())) { - UnsignedOrNone LocalIndex = allocateLocal(E); + UnsignedOrNone LocalIndex = allocateLocal(stripDerivedToBaseCasts(E)); if (!LocalIndex) return false; @@ -5078,18 +5103,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(); @@ -5194,7 +5207,7 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) { const auto *InstancePtr = MC->getImplicitObjectArgument(); if (isa_and_nonnull<CXXDestructorDecl>(CompilingFunction) || isa_and_nonnull<CXXConstructorDecl>(CompilingFunction)) { - const auto *Stripped = stripDerivedToBaseCasts(InstancePtr); + const auto *Stripped = stripCheckedDerivedToBaseCasts(InstancePtr); if (isa<CXXThisExpr>(Stripped)) { FuncDecl = cast<CXXMethodDecl>(FuncDecl)->getCorrespondingMethodInClass( 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 [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
