Skip to content

Commit baef6fa

Browse files
authored
[Clang] Increase the default expression nesting limit (#132021)
This iterates on #104717 (which we had to revert) In a bid to increase our chances of success, we try to avoid blowing up the stack by - Using `runWithSufficientStackSpace` in ParseCompoundStatement - Reducing the size of `StmtVector` a bit - Reducing the size of `DeclsInGroup` a bit - Removing a few `ParsedAttributes` from the stacks in places where they are not strictly necessary. `ParsedAttributes` is a _huge_ object On a 64 bits system, the following stack size reductions are observed ``` ParseStatementOrDeclarationAfterAttributes: 344 -> 264 ParseStatementOrDeclaration: 520 -> 376 ParseCompoundStatementBody: 1080 -> 1016 ParseDeclaration: 264 -> 120 ``` Fixes #94728
1 parent 0cb9c50 commit baef6fa

File tree

10 files changed

+58
-42
lines changed

10 files changed

+58
-42
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ Modified Compiler Flags
174174
the behavior of ``-mtp`` in gcc. This changes the default behavior for ARM targets that provide the ``TPIDRURO`` register as this will be used instead of a call to the ``__aeabi_read_tp``.
175175
Programs that use ``__aeabi_read_tp`` but do not use the ``TPIDRURO`` register must use ``-mtp=soft``. Fixes #123864
176176

177+
- The compiler flag `-fbracket-depth` default value is increased from 256 to 2048. (#GH94728)
178+
177179
Removed Compiler Flags
178180
-------------------------
179181

@@ -269,7 +271,7 @@ Improvements to Clang's diagnostics
269271
as function arguments or return value respectively. Note that
270272
:doc:`ThreadSafetyAnalysis` still does not perform alias analysis. The
271273
feature will be default-enabled with ``-Wthread-safety`` in a future release.
272-
- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) and minus(-) as signed integers
274+
- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) and minus(-) as signed integers
273275
except for the case where the operand is an unsigned integer
274276
and throws warning if they are compared with unsigned integers (##18878).
275277
- The ``-Wunnecessary-virtual-specifier`` warning has been added to warn about

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8161,7 +8161,7 @@ def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-
81618161
MarshallingInfoFlag<LangOpts<"SetVisibilityForExternDecls">>;
81628162
def fbracket_depth : Separate<["-"], "fbracket-depth">,
81638163
HelpText<"Maximum nesting level for parentheses, brackets, and braces">,
8164-
MarshallingInfoInt<LangOpts<"BracketDepth">, "256">;
8164+
MarshallingInfoInt<LangOpts<"BracketDepth">, "2048">;
81658165
defm const_strings : BoolOption<"f", "const-strings",
81668166
LangOpts<"ConstStrings">, DefaultFalse,
81678167
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use">,

clang/include/clang/Parse/Parser.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ class Parser : public CodeCompletionHandler {
9191

9292
DiagnosticsEngine &Diags;
9393

94+
StackExhaustionHandler StackHandler;
95+
9496
/// ScopeCache - Cache scopes to reduce malloc traffic.
9597
enum { ScopeCacheSize = 16 };
9698
unsigned NumCachedScopes;
@@ -518,7 +520,7 @@ class Parser : public CodeCompletionHandler {
518520
typedef Sema::FullExprArg FullExprArg;
519521

520522
/// A SmallVector of statements.
521-
typedef SmallVector<Stmt *, 32> StmtVector;
523+
typedef SmallVector<Stmt *, 24> StmtVector;
522524

523525
// Parsing methods.
524526

@@ -3842,6 +3844,8 @@ class Parser : public CodeCompletionHandler {
38423844
DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
38433845
DeclaratorContext Context, SourceLocation &DeclEnd,
38443846
ParsedAttributes &AccessAttrs, AccessSpecifier AS);
3847+
clang::Parser::DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
3848+
DeclaratorContext Context, SourceLocation &DeclEnd, AccessSpecifier AS);
38453849
DeclGroupPtrTy ParseDeclarationAfterTemplate(
38463850
DeclaratorContext Context, ParsedTemplateInfo &TemplateInfo,
38473851
ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,

clang/include/clang/Sema/ParsedAttr.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,14 @@ class ParsedAttributes : public ParsedAttributesView {
970970
pool.takeAllFrom(Other.pool);
971971
}
972972

973+
void takeAllAtEndFrom(ParsedAttributes &Other) {
974+
assert(&Other != this &&
975+
"ParsedAttributes can't take attributes from itself");
976+
addAllAtEnd(Other.begin(), Other.end());
977+
Other.clearListOnly();
978+
pool.takeAllFrom(Other.pool);
979+
}
980+
973981
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA) {
974982
assert(&Other != this &&
975983
"ParsedAttributes can't take attribute from itself");
@@ -1067,10 +1075,11 @@ class ParsedAttributes : public ParsedAttributesView {
10671075
mutable AttributePool pool;
10681076
};
10691077

1070-
/// Consumes the attributes from `First` and `Second` and concatenates them into
1071-
/// `Result`. Sets `Result.Range` to the combined range of `First` and `Second`.
1072-
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second,
1073-
ParsedAttributes &Result);
1078+
/// Consumes the attributes from `Second` and concatenates them
1079+
/// at the end of `First`. Sets `First.Range`
1080+
/// to the combined range of `First` and `Second`.
1081+
void takeAndConcatenateAttrs(ParsedAttributes &First,
1082+
ParsedAttributes &&Second);
10741083

10751084
/// These constants match the enumerated choices of
10761085
/// err_attribute_argument_n_type and err_attribute_argument_type.

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,10 +2076,9 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
20762076
ProhibitAttributes(DeclSpecAttrs);
20772077
return ParseNamespace(Context, DeclEnd);
20782078
case tok::kw_using: {
2079-
ParsedAttributes Attrs(AttrFactory);
2080-
takeAndConcatenateAttrs(DeclAttrs, DeclSpecAttrs, Attrs);
2079+
takeAndConcatenateAttrs(DeclAttrs, std::move(DeclSpecAttrs));
20812080
return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
2082-
DeclEnd, Attrs);
2081+
DeclEnd, DeclAttrs);
20832082
}
20842083
case tok::kw_static_assert:
20852084
case tok::kw__Static_assert:

clang/lib/Parse/ParseStmt.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -126,18 +126,15 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
126126
Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs);
127127
MaybeDestroyTemplateIds();
128128

129-
// Attributes that are left should all go on the statement, so concatenate the
130-
// two lists.
131-
ParsedAttributes Attrs(AttrFactory);
132-
takeAndConcatenateAttrs(CXX11Attrs, GNUOrMSAttrs, Attrs);
129+
takeAndConcatenateAttrs(CXX11Attrs, std::move(GNUOrMSAttrs));
133130

134-
assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
131+
assert((CXX11Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
135132
"attributes on empty statement");
136133

137-
if (Attrs.empty() || Res.isInvalid())
134+
if (CXX11Attrs.empty() || Res.isInvalid())
138135
return Res;
139136

140-
return Actions.ActOnAttributedStmt(Attrs, Res.get());
137+
return Actions.ActOnAttributedStmt(CXX11Attrs, Res.get());
141138
}
142139

143140
namespace {
@@ -207,11 +204,10 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
207204
// Both C++11 and GNU attributes preceding the label appertain to the
208205
// label, so put them in a single list to pass on to
209206
// ParseLabeledStatement().
210-
ParsedAttributes Attrs(AttrFactory);
211-
takeAndConcatenateAttrs(CXX11Attrs, GNUAttrs, Attrs);
207+
takeAndConcatenateAttrs(CXX11Attrs, std::move(GNUAttrs));
212208

213209
// identifier ':' statement
214-
return ParseLabeledStatement(Attrs, StmtCtx);
210+
return ParseLabeledStatement(CXX11Attrs, StmtCtx);
215211
}
216212

217213
// Look up the identifier, and typo-correct it to a keyword if it's not
@@ -302,9 +298,7 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
302298

303299
case tok::kw_template: {
304300
SourceLocation DeclEnd;
305-
ParsedAttributes Attrs(AttrFactory);
306301
ParseTemplateDeclarationOrSpecialization(DeclaratorContext::Block, DeclEnd,
307-
Attrs,
308302
getAccessSpecifierIfPresent());
309303
return StmtError();
310304
}
@@ -1057,7 +1051,11 @@ StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
10571051
ParseScope CompoundScope(this, ScopeFlags);
10581052

10591053
// Parse the statements in the body.
1060-
return ParseCompoundStatementBody(isStmtExpr);
1054+
StmtResult R;
1055+
StackHandler.runWithSufficientStackSpace(Tok.getLocation(), [&, this]() {
1056+
R = ParseCompoundStatementBody(isStmtExpr);
1057+
});
1058+
return R;
10611059
}
10621060

10631061
/// Parse any pragmas at the start of the compound expression. We handle these
@@ -1222,7 +1220,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
12221220
while (Tok.is(tok::kw___label__)) {
12231221
SourceLocation LabelLoc = ConsumeToken();
12241222

1225-
SmallVector<Decl *, 8> DeclsInGroup;
1223+
SmallVector<Decl *, 4> DeclsInGroup;
12261224
while (true) {
12271225
if (Tok.isNot(tok::identifier)) {
12281226
Diag(Tok, diag::err_expected) << tok::identifier;

clang/lib/Parse/ParseTemplate.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(
179179
Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
180180
}
181181

182+
Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(
183+
DeclaratorContext Context, SourceLocation &DeclEnd, AccessSpecifier AS) {
184+
ParsedAttributes AccessAttrs(AttrFactory);
185+
return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
186+
AS);
187+
}
188+
182189
/// Parse a single declaration that declares a template,
183190
/// template specialization, or explicit instantiation of a template.
184191
///

clang/lib/Parse/Parser.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "clang/AST/DeclTemplate.h"
1818
#include "clang/Basic/DiagnosticParse.h"
1919
#include "clang/Basic/FileManager.h"
20+
#include "clang/Basic/StackExhaustionHandler.h"
2021
#include "clang/Parse/RAIIObjectsForParser.h"
2122
#include "clang/Sema/DeclSpec.h"
2223
#include "clang/Sema/EnterExpressionEvaluationContext.h"
@@ -54,9 +55,10 @@ IdentifierInfo *Parser::getSEHExceptKeyword() {
5455

5556
Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
5657
: PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),
57-
Diags(PP.getDiagnostics()), GreaterThanIsOperator(true),
58-
ColonIsSacred(false), InMessageExpression(false),
59-
TemplateParameterDepth(0), ParsingInObjCContainer(false) {
58+
Diags(PP.getDiagnostics()), StackHandler(Diags),
59+
GreaterThanIsOperator(true), ColonIsSacred(false),
60+
InMessageExpression(false), TemplateParameterDepth(0),
61+
ParsingInObjCContainer(false) {
6062
SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
6163
Tok.startToken();
6264
Tok.setKind(tok::eof);

clang/lib/Sema/ParsedAttr.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -310,18 +310,13 @@ bool ParsedAttr::checkAtMostNumArgs(Sema &S, unsigned Num) const {
310310
}
311311

312312
void clang::takeAndConcatenateAttrs(ParsedAttributes &First,
313-
ParsedAttributes &Second,
314-
ParsedAttributes &Result) {
315-
// Note that takeAllFrom() puts the attributes at the beginning of the list,
316-
// so to obtain the correct ordering, we add `Second`, then `First`.
317-
Result.takeAllFrom(Second);
318-
Result.takeAllFrom(First);
319-
if (First.Range.getBegin().isValid())
320-
Result.Range.setBegin(First.Range.getBegin());
321-
else
322-
Result.Range.setBegin(Second.Range.getBegin());
313+
ParsedAttributes &&Second) {
314+
315+
First.takeAllAtEndFrom(Second);
316+
317+
if (!First.Range.getBegin().isValid())
318+
First.Range.setBegin(Second.Range.getBegin());
319+
323320
if (Second.Range.getEnd().isValid())
324-
Result.Range.setEnd(Second.Range.getEnd());
325-
else
326-
Result.Range.setEnd(First.Range.getEnd());
321+
First.Range.setEnd(Second.Range.getEnd());
327322
}

clang/test/Parser/parser_overflow.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: not %clang_cc1 %s -fsyntax-only -DHUGE 2>&1 | FileCheck %s
2-
// RUN: not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s
2+
// RUN: %clang_cc1 %s -fsyntax-only
33
// RUN: not %clang_cc1 %s -fsyntax-only -fbracket-depth 299 2>&1 | FileCheck %s
44
// RUN: %clang_cc1 %s -fsyntax-only -fbracket-depth 300
55
// RUN: not %clang %s -fsyntax-only -fbracket-depth=299 2>&1 | FileCheck %s
@@ -15,5 +15,5 @@ void foo(void) {
1515
#endif
1616
}
1717

18-
// CHECK: fatal error: bracket nesting level exceeded maximum of {{256|299}}
18+
// CHECK: fatal error: bracket nesting level exceeded maximum of {{2048|299}}
1919
// CHECK: note: use -fbracket-depth=N to increase maximum nesting level

0 commit comments

Comments
 (0)