[clang] 56a636f - [clang][Interp] Implement StmtExprs
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Sun Jun 30 00:29:22 PDT 2024
Author: Timm Bäder
Date: 2024-06-30T09:28:56+02:00
New Revision: 56a636f2d22890cc71f358ddc50d3e0f2b60bd9c
URL: https://github.com/llvm/llvm-project/commit/56a636f2d22890cc71f358ddc50d3e0f2b60bd9c
DIFF: https://github.com/llvm/llvm-project/commit/56a636f2d22890cc71f358ddc50d3e0f2b60bd9c.diff
LOG: [clang][Interp] Implement StmtExprs
Added:
Modified:
clang/lib/AST/Interp/Compiler.cpp
clang/lib/AST/Interp/Compiler.h
clang/test/AST/Interp/literals.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index 8b6f7f644a778..424f4f84a0167 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -3025,6 +3025,32 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr(
return this->emitInitFieldPtr(R->getField(1u)->Offset, E);
}
+template <class Emitter>
+bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) {
+ BlockScope<Emitter> BS(this);
+
+ const CompoundStmt *CS = E->getSubStmt();
+ const Stmt *Result = CS->getStmtExprResult();
+ for (const Stmt *S : CS->body()) {
+ if (S != Result) {
+ if (!this->visitStmt(S))
+ return false;
+ continue;
+ }
+
+ assert(S == Result);
+ // This better produces a value (i.e. is an expression).
+ if (const Expr *ResultExpr = dyn_cast<Expr>(S)) {
+ if (DiscardResult)
+ return this->discard(ResultExpr);
+ return this->delegate(ResultExpr);
+ }
+ return false;
+ }
+
+ return true;
+}
+
template <class Emitter> bool Compiler<Emitter>::discard(const Expr *E) {
OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true,
/*NewInitializing=*/false);
diff --git a/clang/lib/AST/Interp/Compiler.h b/clang/lib/AST/Interp/Compiler.h
index 89e36f9201a41..d188ce2200664 100644
--- a/clang/lib/AST/Interp/Compiler.h
+++ b/clang/lib/AST/Interp/Compiler.h
@@ -183,6 +183,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E);
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);
+ bool VisitStmtExpr(const StmtExpr *E);
// Statements.
bool visitCompoundStmt(const CompoundStmt *S);
diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index ef98b4947e64f..a7a602ec355d5 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -1213,6 +1213,18 @@ constexpr int externvar1() { // both-error {{never produces a constant expressio
return arr[0]; // ref-note {{read of non-constexpr variable 'arr'}} \
// expected-note {{indexing of array without known bound}}
}
+
+namespace StmtExprs {
+ constexpr int foo() {
+ ({
+ int i;
+ for (i = 0; i < 76; i++) {}
+ i; // both-warning {{expression result unused}}
+ });
+ return 76;
+ }
+ static_assert(foo() == 76, "");
+}
#endif
namespace Extern {
More information about the cfe-commits
mailing list