[clang] e45d199 - [clang][Interp] Handle CXXTemporaryObjectExprs
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 25 22:37:32 PDT 2023
Author: Timm Bäder
Date: 2023-07-26T07:36:26+02:00
New Revision: e45d1997686c6cb0f98c0dc00191d35b3d3e5f95
URL: https://github.com/llvm/llvm-project/commit/e45d1997686c6cb0f98c0dc00191d35b3d3e5f95
DIFF: https://github.com/llvm/llvm-project/commit/e45d1997686c6cb0f98c0dc00191d35b3d3e5f95.diff
LOG: [clang][Interp] Handle CXXTemporaryObjectExprs
This is a CXXConstructExpr, so create a local temporary variable and
initialize it.
Differential Revision: https://reviews.llvm.org/D147591
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/records.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d700a3e9be72bc..40792fa6f4a284 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -886,6 +886,24 @@ bool ByteCodeExprGen<Emitter>::VisitMaterializeTemporaryExpr(
return false;
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitCXXBindTemporaryExpr(
+ const CXXBindTemporaryExpr *E) {
+
+ return this->visit(E->getSubExpr());
+}
+
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitCXXTemporaryObjectExpr(
+ const CXXTemporaryObjectExpr *E) {
+
+ if (std::optional<unsigned> LocalIndex =
+ allocateLocal(E, /*IsExtended=*/false)) {
+ return this->visitLocalInitializer(E, *LocalIndex);
+ }
+ return false;
+}
+
template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 57b0af9459e3ab..a031aaa9fae1dd 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -91,6 +91,8 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E);
bool VisitExprWithCleanups(const ExprWithCleanups *E);
bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
+ bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E);
+ bool VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
bool VisitTypeTraitExpr(const TypeTraitExpr *E);
bool VisitLambdaExpr(const LambdaExpr *E);
diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp
index d315e31a13e525..b708f5f6a00911 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -311,16 +311,36 @@ namespace InitializerTemporaries {
int Pos = 0;
{
- auto T = Test(Arr, Pos);
+ Test(Arr, Pos);
// End of scope, should destroy Test.
}
return Arr[Index];
}
-
static_assert(T(0) == 1);
static_assert(T(1) == 2);
static_assert(T(2) == 3);
+
+ // Invalid destructor.
+ struct S {
+ constexpr S() {}
+ constexpr ~S() noexcept(false) { throw 12; } // expected-error {{cannot use 'throw'}} \
+ // expected-note {{declared here}} \
+ // ref-error {{cannot use 'throw'}} \
+ // ref-error {{never produces a constant expression}} \
+ // ref-note 2{{subexpression not valid}}
+ };
+
+ constexpr int f() {
+ S{}; // ref-note {{in call to 'S{}.~S()'}}
+ return 12; // expected-note {{undefined function '~S'}}
+ }
+ static_assert(f() == 12); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'f()'}} \
+ // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to 'f()'}}
+
+
#endif
}
@@ -572,17 +592,18 @@ namespace Destructors {
constexpr ~S() { // expected-error {{never produces a constant expression}} \
// ref-error {{never produces a constant expression}}
int i = 1 / 0; // expected-warning {{division by zero}} \
- // expected-note {{division by zero}} \
+ // expected-note 2{{division by zero}} \
// ref-warning {{division by zero}} \
// ref-note 2{{division by zero}}
}
};
constexpr int testS() {
S{}; // ref-note {{in call to 'S{}.~S()'}}
- return 1;
+ return 1; // expected-note {{in call to '&S{}->~S()'}}
// FIXME: ^ Wrong line
}
static_assert(testS() == 1); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to 'testS()'}} \
// ref-error {{not an integral constant expression}} \
// ref-note {{in call to 'testS()'}}
}
More information about the cfe-commits
mailing list