Add -fbracket-depth=N, analogous to -ftemplate-depth= and -fconstexpr-depth=,

to control the check for the C 5.2.4.1 / C++ [implimits] restriction on nesting
levels for parentheses, brackets and braces.

Some code with heavy macro use exceeds the default limit of 256, but we don't
want to increase it generally to avoid stack overflow on stack-constrained
systems.

llvm-svn: 175855
This commit is contained in:
Richard Smith
2013-02-22 01:59:51 +00:00
parent 5772f82d1e
commit b3a145293d
10 changed files with 37 additions and 5 deletions

View File

@@ -1178,6 +1178,11 @@ features <http://clang.llvm.org/cxx_status.html>`_ are also implemented.
Controlling implementation limits
---------------------------------
.. option:: -fbracket-depth=N
Sets the limit for nested parentheses, brackets, and braces to N. The
default is 256.
.. option:: -fconstexpr-depth=N
Sets the limit for recursive constexpr function invocations to N. The

View File

@@ -465,8 +465,10 @@ def err_destructor_template_id : Error<
"destructor name %0 does not refer to a template">;
def err_default_arg_unparsed : Error<
"unexpected end of default argument expression">;
def err_parser_impl_limit_overflow : Error<
"parser recursion limit reached, program too complex">, DefaultFatal;
def err_bracket_depth_exceeded : Error<
"bracket nesting level exceeded maximum of %0">, DefaultFatal;
def note_bracket_depth : Note<
"use -fbracket-depth=N to increase maximum nesting level">;
def err_misplaced_ellipsis_in_declaration : Error<
"'...' must %select{immediately precede declared identifier|"
"be innermost component of anonymous pack declaration}0">;

View File

@@ -160,6 +160,8 @@ BENIGN_LANGOPT(InstantiationDepth, 32, 512,
"maximum template instantiation depth")
BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
"maximum constexpr call depth")
BENIGN_LANGOPT(BracketDepth, 32, 256,
"maximum bracket nesting depth")
BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
"if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
VALUE_LANGOPT(MSCVersion, 32, 0,

View File

@@ -422,6 +422,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 fbracket_depth : Separate<["-"], "fbracket-depth">,
HelpText<"Maximum nesting level for parentheses, brackets, and braces">;
def fconst_strings : Flag<["-"], "fconst-strings">,
HelpText<"Use a const qualified type for string literals in C and ObjC">;
def fno_const_strings : Flag<["-"], "fno-const-strings">,

View File

@@ -389,6 +389,7 @@ def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>;
def fmath_errno : Flag<["-"], "fmath-errno">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Require math functions to indicate errors by setting errno">;
def fno_math_errno : Flag<["-"], "fno-math-errno">, Group<f_Group>;
def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>;
def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>;
def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>;
def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,

View File

@@ -2520,6 +2520,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue());
}
if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
CmdArgs.push_back("-fbracket-depth");
CmdArgs.push_back(A->getValue());
}
if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
options::OPT_Wlarge_by_value_copy_def)) {
if (A->getNumValues()) {

View File

@@ -1221,6 +1221,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Diags);
Opts.ConstexprCallDepth = Args.getLastArgIntValue(OPT_fconstexpr_depth, 512,
Diags);
Opts.BracketDepth = Args.getLastArgIntValue(OPT_fbracket_depth, 256, Diags);
Opts.DelayedTemplateParsing = Args.hasArg(OPT_fdelayed_template_parsing);
Opts.NumLargeByValueCopy = Args.getLastArgIntValue(OPT_Wlarge_by_value_copy_EQ,
0, Diags);

View File

@@ -1878,7 +1878,9 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) {
}
bool BalancedDelimiterTracker::diagnoseOverflow() {
P.Diag(P.Tok, diag::err_parser_impl_limit_overflow);
P.Diag(P.Tok, diag::err_bracket_depth_exceeded)
<< P.getLangOpts().BracketDepth;
P.Diag(P.Tok, diag::note_bracket_depth);
P.SkipUntil(tok::eof);
return true;
}

View File

@@ -407,7 +407,7 @@ namespace clang {
if (!P.Tok.is(Kind))
return true;
if (getDepth() < MaxDepth) {
if (getDepth() < P.getLangOpts().BracketDepth) {
LOpen = (P.*Consumer)();
return false;
}

File diff suppressed because one or more lines are too long