[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