Loading clang/include/clang/Basic/DiagnosticASTKinds.td +2 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,8 @@ def note_constexpr_depth_limit_exceeded : Note< "constexpr evaluation exceeded maximum depth of %0 calls">; def note_constexpr_call_limit_exceeded : Note< "constexpr evaluation hit maximum call limit">; def note_constexpr_step_limit_exceeded : Note< "constexpr evaluation hit maximum step limit; possible infinite loop?">; def note_constexpr_lifetime_ended : Note< "%select{read of|assignment to|increment of|decrement of}0 " "%select{temporary|variable}1 whose lifetime has ended">; Loading clang/include/clang/Basic/LangOptions.def +2 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,8 @@ BENIGN_LANGOPT(InstantiationDepth, 32, 256, "maximum template instantiation depth") BENIGN_LANGOPT(ConstexprCallDepth, 32, 512, "maximum constexpr call depth") BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576, "maximum constexpr evaluation steps") BENIGN_LANGOPT(BracketDepth, 32, 256, "maximum bracket nesting depth") BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0, Loading clang/include/clang/Driver/CC1Options.td +2 −0 Original line number Diff line number Diff line Loading @@ -434,6 +434,8 @@ def ftemplate_depth : Separate<["-"], "ftemplate-depth">, HelpText<"Maximum depth of recursive template instantiation">; def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">, HelpText<"Maximum depth of recursive constexpr function calls">; def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">, HelpText<"Maximum number of steps in constexpr function evaluation">; def fbracket_depth : Separate<["-"], "fbracket-depth">, HelpText<"Maximum nesting level for parentheses, brackets, and braces">; def fconst_strings : Flag<["-"], "fconst-strings">, Loading clang/include/clang/Driver/Options.td +1 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,7 @@ def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>; def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group<f_Group>; def fconstant_string_class_EQ : Joined<["-"], "fconstant-string-class=">, Group<f_Group>; def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>; def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>; def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">, Group<f_Group>; def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>; Loading clang/lib/AST/ExprConstant.cpp +22 −4 Original line number Diff line number Diff line Loading @@ -380,6 +380,11 @@ namespace { /// NextCallIndex - The next call index to assign. unsigned NextCallIndex; /// StepsLeft - The remaining number of evaluation steps we're permitted /// to perform. This is essentially a limit for the number of statements /// we will evaluate. unsigned StepsLeft; /// BottomFrame - The frame in which evaluation started. This must be /// initialized after CurrentCall and CallStackDepth. CallStackFrame BottomFrame; Loading Loading @@ -407,6 +412,7 @@ namespace { bool OverflowCheckMode = false) : Ctx(const_cast<ASTContext&>(C)), EvalStatus(S), CurrentCall(0), CallStackDepth(0), NextCallIndex(1), StepsLeft(getLangOpts().ConstexprStepLimit), BottomFrame(*this, SourceLocation(), 0, 0, 0), EvaluatingDecl(0), EvaluatingDeclValue(0), HasActiveDiagnostic(false), CheckingPotentialConstantExpression(false), Loading Loading @@ -446,6 +452,15 @@ namespace { return (Frame->Index == CallIndex) ? Frame : 0; } bool nextStep(const Stmt *S) { if (!StepsLeft) { Diag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded); return false; } --StepsLeft; return true; } private: /// Add a diagnostic to the diagnostics list. PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId) { Loading Loading @@ -530,9 +545,9 @@ namespace { bool keepEvaluatingAfterFailure() { // Should return true in IntOverflowCheckMode, so that we check for // overflow even if some subexpressions can't be evaluated as constants. return IntOverflowCheckMode || return StepsLeft && (IntOverflowCheckMode || (CheckingPotentialConstantExpression && EvalStatus.Diag && EvalStatus.Diag->empty()); EvalStatus.Diag && EvalStatus.Diag->empty())); } }; Loading Loading @@ -2794,6 +2809,9 @@ static EvalStmtResult EvaluateLoopBody(APValue &Result, EvalInfo &Info, // Evaluate a statement. static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info, const Stmt *S) { if (!Info.nextStep(S)) return ESR_Failed; // FIXME: Mark all temporaries in the current frame as destroyed at // the end of each full-expression. switch (S->getStmtClass()) { Loading Loading
clang/include/clang/Basic/DiagnosticASTKinds.td +2 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,8 @@ def note_constexpr_depth_limit_exceeded : Note< "constexpr evaluation exceeded maximum depth of %0 calls">; def note_constexpr_call_limit_exceeded : Note< "constexpr evaluation hit maximum call limit">; def note_constexpr_step_limit_exceeded : Note< "constexpr evaluation hit maximum step limit; possible infinite loop?">; def note_constexpr_lifetime_ended : Note< "%select{read of|assignment to|increment of|decrement of}0 " "%select{temporary|variable}1 whose lifetime has ended">; Loading
clang/include/clang/Basic/LangOptions.def +2 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,8 @@ BENIGN_LANGOPT(InstantiationDepth, 32, 256, "maximum template instantiation depth") BENIGN_LANGOPT(ConstexprCallDepth, 32, 512, "maximum constexpr call depth") BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576, "maximum constexpr evaluation steps") BENIGN_LANGOPT(BracketDepth, 32, 256, "maximum bracket nesting depth") BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0, Loading
clang/include/clang/Driver/CC1Options.td +2 −0 Original line number Diff line number Diff line Loading @@ -434,6 +434,8 @@ def ftemplate_depth : Separate<["-"], "ftemplate-depth">, HelpText<"Maximum depth of recursive template instantiation">; def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">, HelpText<"Maximum depth of recursive constexpr function calls">; def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">, HelpText<"Maximum number of steps in constexpr function evaluation">; def fbracket_depth : Separate<["-"], "fbracket-depth">, HelpText<"Maximum nesting level for parentheses, brackets, and braces">; def fconst_strings : Flag<["-"], "fconst-strings">, Loading
clang/include/clang/Driver/Options.td +1 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,7 @@ def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>; def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group<f_Group>; def fconstant_string_class_EQ : Joined<["-"], "fconstant-string-class=">, Group<f_Group>; def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>; def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>; def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">, Group<f_Group>; def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>; Loading
clang/lib/AST/ExprConstant.cpp +22 −4 Original line number Diff line number Diff line Loading @@ -380,6 +380,11 @@ namespace { /// NextCallIndex - The next call index to assign. unsigned NextCallIndex; /// StepsLeft - The remaining number of evaluation steps we're permitted /// to perform. This is essentially a limit for the number of statements /// we will evaluate. unsigned StepsLeft; /// BottomFrame - The frame in which evaluation started. This must be /// initialized after CurrentCall and CallStackDepth. CallStackFrame BottomFrame; Loading Loading @@ -407,6 +412,7 @@ namespace { bool OverflowCheckMode = false) : Ctx(const_cast<ASTContext&>(C)), EvalStatus(S), CurrentCall(0), CallStackDepth(0), NextCallIndex(1), StepsLeft(getLangOpts().ConstexprStepLimit), BottomFrame(*this, SourceLocation(), 0, 0, 0), EvaluatingDecl(0), EvaluatingDeclValue(0), HasActiveDiagnostic(false), CheckingPotentialConstantExpression(false), Loading Loading @@ -446,6 +452,15 @@ namespace { return (Frame->Index == CallIndex) ? Frame : 0; } bool nextStep(const Stmt *S) { if (!StepsLeft) { Diag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded); return false; } --StepsLeft; return true; } private: /// Add a diagnostic to the diagnostics list. PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId) { Loading Loading @@ -530,9 +545,9 @@ namespace { bool keepEvaluatingAfterFailure() { // Should return true in IntOverflowCheckMode, so that we check for // overflow even if some subexpressions can't be evaluated as constants. return IntOverflowCheckMode || return StepsLeft && (IntOverflowCheckMode || (CheckingPotentialConstantExpression && EvalStatus.Diag && EvalStatus.Diag->empty()); EvalStatus.Diag && EvalStatus.Diag->empty())); } }; Loading Loading @@ -2794,6 +2809,9 @@ static EvalStmtResult EvaluateLoopBody(APValue &Result, EvalInfo &Info, // Evaluate a statement. static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info, const Stmt *S) { if (!Info.nextStep(S)) return ESR_Failed; // FIXME: Mark all temporaries in the current frame as destroyed at // the end of each full-expression. switch (S->getStmtClass()) { Loading