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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits