Author: Timm Bäder Date: 2024-07-02T12:15:24+02:00 New Revision: c49c386caaf7132908995749fed4894cfa1b62d1
URL: https://github.com/llvm/llvm-project/commit/c49c386caaf7132908995749fed4894cfa1b62d1 DIFF: https://github.com/llvm/llvm-project/commit/c49c386caaf7132908995749fed4894cfa1b62d1.diff LOG: [clang][Interp] Reject StmtExprs containing return statements Added: Modified: clang/lib/AST/Interp/Compiler.cpp clang/lib/AST/Interp/Compiler.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/literals.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp index 3d9c72e2b6dee..739a65070b21d 100644 --- a/clang/lib/AST/Interp/Compiler.cpp +++ b/clang/lib/AST/Interp/Compiler.cpp @@ -154,6 +154,19 @@ template <class Emitter> class SwitchScope final : public LabelScope<Emitter> { CaseMap OldCaseLabels; }; +template <class Emitter> class StmtExprScope final { +public: + StmtExprScope(Compiler<Emitter> *Ctx) : Ctx(Ctx), OldFlag(Ctx->InStmtExpr) { + Ctx->InStmtExpr = true; + } + + ~StmtExprScope() { Ctx->InStmtExpr = OldFlag; } + +private: + Compiler<Emitter> *Ctx; + bool OldFlag; +}; + } // namespace interp } // namespace clang @@ -3028,6 +3041,7 @@ bool Compiler<Emitter>::VisitCXXStdInitializerListExpr( template <class Emitter> bool Compiler<Emitter>::VisitStmtExpr(const StmtExpr *E) { BlockScope<Emitter> BS(this); + StmtExprScope<Emitter> SS(this); const CompoundStmt *CS = E->getSubStmt(); const Stmt *Result = CS->getStmtExprResult(); @@ -4056,6 +4070,9 @@ bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS) { template <class Emitter> bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) { + if (this->InStmtExpr) + return this->emitUnsupported(RS); + if (const Expr *RE = RS->getRetValue()) { ExprScope<Emitter> RetScope(this); if (ReturnType) { diff --git a/clang/lib/AST/Interp/Compiler.h b/clang/lib/AST/Interp/Compiler.h index 67bd7efb3b091..d28526c76fe13 100644 --- a/clang/lib/AST/Interp/Compiler.h +++ b/clang/lib/AST/Interp/Compiler.h @@ -39,6 +39,7 @@ template <class Emitter> class SourceLocScope; template <class Emitter> class LoopScope; template <class Emitter> class LabelScope; template <class Emitter> class SwitchScope; +template <class Emitter> class StmtExprScope; template <class Emitter> class Compiler; struct InitLink { @@ -334,6 +335,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, friend class LoopScope<Emitter>; friend class LabelScope<Emitter>; friend class SwitchScope<Emitter>; + friend class StmtExprScope<Emitter>; /// Emits a zero initializer. bool visitZeroInitializer(PrimType T, QualType QT, const Expr *E); @@ -398,6 +400,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, /// Flag indicating if return value is to be discarded. bool DiscardResult = false; + bool InStmtExpr = false; + /// Flag inidicating if we're initializing an already created /// variable. This is set in visitInitializer(). bool Initializing = false; diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index ff6d50ab9b6f8..328db219ca628 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -2618,6 +2618,13 @@ inline bool Invalid(InterpState &S, CodePtr OpPC) { return false; } +inline bool Unsupported(InterpState &S, CodePtr OpPC) { + const SourceLocation &Loc = S.Current->getLocation(OpPC); + S.FFDiag(Loc, diag::note_constexpr_stmt_expr_unsupported) + << S.Current->getRange(OpPC); + return false; +} + /// Do nothing and just abort execution. inline bool Error(InterpState &S, CodePtr OpPC) { return false; } diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 81e7b812da237..8d01fe1ac2bd1 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -714,6 +714,7 @@ def Dup : Opcode { // [] -> [] def Invalid : Opcode {} +def Unsupported : Opcode {} def Error : Opcode {} def InvalidCast : Opcode { let Args = [ArgCastKind]; diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 3abaf89e8bd01..f70ca79e216da 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -1255,4 +1255,14 @@ constexpr int StmtExprEval() { return 1; } static_assert(StmtExprEval() == 2, ""); + +constexpr int ReturnInStmtExpr() { // both-error {{never produces a constant expression}} + return ({ + return 1; // both-note 2{{this use of statement expressions is not supported in a constant expression}} + 2; + }); +} +static_assert(ReturnInStmtExpr() == 1, ""); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits