-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][bytecode] Fix temporary lvalue base expression #111808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
We need to use the MaterializeTemporaryExpr here so the checks in ExprConstant.cpp do the right thing.
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesWe 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:
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}}
+}
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/6365 Here is the relevant piece of the build log for the reference
|
We need to use the MaterializeTemporaryExpr here so the checks in ExprConstant.cpp do the right thing.
We need to use the MaterializeTemporaryExpr here so the checks in ExprConstant.cpp do the right thing.