https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/111808
We need to use the MaterializeTemporaryExpr here so the checks in ExprConstant.cpp do the right thing. >From d06e3aab6e01050db6ceaa43b2659623fc8f1f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Thu, 10 Oct 2024 11:21:46 +0200 Subject: [PATCH] [clang][bytecode] Fix temporary lvalue base expression We need to use the MaterializeTemporaryExpr here so the checks in ExprConstant.cpp do the right thing. --- clang/lib/AST/ByteCode/Compiler.cpp | 9 +++++---- clang/lib/AST/ByteCode/Compiler.h | 3 ++- clang/test/AST/ByteCode/cxx1z.cpp | 12 ++++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 clang/test/AST/ByteCode/cxx1z.cpp diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index fe44238ea11869..ba4c5600d613b0 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -2728,7 +2728,7 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr( const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments(); if (std::optional<unsigned> LocalIndex = - allocateLocal(Inner, E->getExtendingDecl())) { + allocateLocal(E, Inner->getType(), E->getExtendingDecl())) { InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex)); if (!this->emitGetPtrLocal(*LocalIndex, E)) return false; @@ -4029,7 +4029,8 @@ unsigned Compiler<Emitter>::allocateLocalPrimitive(DeclTy &&Src, PrimType Ty, template <class Emitter> std::optional<unsigned> -Compiler<Emitter>::allocateLocal(DeclTy &&Src, const ValueDecl *ExtendingDecl) { +Compiler<Emitter>::allocateLocal(DeclTy &&Src, QualType Ty, + const ValueDecl *ExtendingDecl) { // Make sure we don't accidentally register the same decl twice. if ([[maybe_unused]] const auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) { @@ -4037,7 +4038,6 @@ Compiler<Emitter>::allocateLocal(DeclTy &&Src, const ValueDecl *ExtendingDecl) { assert(!Locals.contains(VD)); } - QualType Ty; const ValueDecl *Key = nullptr; const Expr *Init = nullptr; bool IsTemporary = false; @@ -4050,7 +4050,8 @@ Compiler<Emitter>::allocateLocal(DeclTy &&Src, const ValueDecl *ExtendingDecl) { } if (auto *E = Src.dyn_cast<const Expr *>()) { IsTemporary = true; - Ty = E->getType(); + if (Ty.isNull()) + Ty = E->getType(); } Descriptor *D = P.createDescriptor( diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 22e078f3fe546f..4253e7b3248c9f 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -302,7 +302,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, /// Allocates a space storing a local given its type. std::optional<unsigned> - allocateLocal(DeclTy &&Decl, const ValueDecl *ExtendingDecl = nullptr); + allocateLocal(DeclTy &&Decl, QualType Ty = QualType(), + const ValueDecl *ExtendingDecl = nullptr); unsigned allocateTemporary(const Expr *E); private: diff --git a/clang/test/AST/ByteCode/cxx1z.cpp b/clang/test/AST/ByteCode/cxx1z.cpp new file mode 100644 index 00000000000000..2b5d215f016548 --- /dev/null +++ b/clang/test/AST/ByteCode/cxx1z.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s +// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s + +template<typename T, T val> struct A {}; +namespace Temp { + struct S { int n; }; + constexpr S &addr(S &&s) { return s; } + A<S &, addr({})> a; // both-error {{reference to temporary object}} + A<S *, &addr({})> b; // both-error {{pointer to temporary object}} + A<int &, addr({}).n> c; // both-error {{reference to subobject of temporary object}} + A<int *, &addr({}).n> d; // both-error {{pointer to subobject of temporary object}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits