Skip to content

Commit 55d51dd

Browse files
authored
[clang][bytecode] Fix temporary lvalue base expression (#111808)
We need to use the MaterializeTemporaryExpr here so the checks in ExprConstant.cpp do the right thing.
1 parent f8b7a65 commit 55d51dd

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,7 +2728,7 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
27282728

27292729
const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments();
27302730
if (std::optional<unsigned> LocalIndex =
2731-
allocateLocal(Inner, E->getExtendingDecl())) {
2731+
allocateLocal(E, Inner->getType(), E->getExtendingDecl())) {
27322732
InitLinkScope<Emitter> ILS(this, InitLink::Temp(*LocalIndex));
27332733
if (!this->emitGetPtrLocal(*LocalIndex, E))
27342734
return false;
@@ -4029,15 +4029,15 @@ unsigned Compiler<Emitter>::allocateLocalPrimitive(DeclTy &&Src, PrimType Ty,
40294029

40304030
template <class Emitter>
40314031
std::optional<unsigned>
4032-
Compiler<Emitter>::allocateLocal(DeclTy &&Src, const ValueDecl *ExtendingDecl) {
4032+
Compiler<Emitter>::allocateLocal(DeclTy &&Src, QualType Ty,
4033+
const ValueDecl *ExtendingDecl) {
40334034
// Make sure we don't accidentally register the same decl twice.
40344035
if ([[maybe_unused]] const auto *VD =
40354036
dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
40364037
assert(!P.getGlobal(VD));
40374038
assert(!Locals.contains(VD));
40384039
}
40394040

4040-
QualType Ty;
40414041
const ValueDecl *Key = nullptr;
40424042
const Expr *Init = nullptr;
40434043
bool IsTemporary = false;
@@ -4050,7 +4050,8 @@ Compiler<Emitter>::allocateLocal(DeclTy &&Src, const ValueDecl *ExtendingDecl) {
40504050
}
40514051
if (auto *E = Src.dyn_cast<const Expr *>()) {
40524052
IsTemporary = true;
4053-
Ty = E->getType();
4053+
if (Ty.isNull())
4054+
Ty = E->getType();
40544055
}
40554056

40564057
Descriptor *D = P.createDescriptor(

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
302302

303303
/// Allocates a space storing a local given its type.
304304
std::optional<unsigned>
305-
allocateLocal(DeclTy &&Decl, const ValueDecl *ExtendingDecl = nullptr);
305+
allocateLocal(DeclTy &&Decl, QualType Ty = QualType(),
306+
const ValueDecl *ExtendingDecl = nullptr);
306307
unsigned allocateTemporary(const Expr *E);
307308

308309
private:

clang/test/AST/ByteCode/cxx1z.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s
2+
// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s
3+
4+
template<typename T, T val> struct A {};
5+
namespace Temp {
6+
struct S { int n; };
7+
constexpr S &addr(S &&s) { return s; }
8+
A<S &, addr({})> a; // both-error {{reference to temporary object}}
9+
A<S *, &addr({})> b; // both-error {{pointer to temporary object}}
10+
A<int &, addr({}).n> c; // both-error {{reference to subobject of temporary object}}
11+
A<int *, &addr({}).n> d; // both-error {{pointer to subobject of temporary object}}
12+
}

0 commit comments

Comments
 (0)