[clang] [clang][bytecode] Fix temporary lvalue base expression (PR #111808)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 10 03:11:05 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
We need to use the MaterializeTemporaryExpr here so the checks in ExprConstant.cpp do the right thing.
---
Full diff: https://github.com/llvm/llvm-project/pull/111808.diff
3 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+5-4)
- (modified) clang/lib/AST/ByteCode/Compiler.h (+2-1)
- (added) clang/test/AST/ByteCode/cxx1z.cpp (+12)
``````````diff
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}}
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/111808
More information about the cfe-commits
mailing list