Skip to content

[Clang] Increase the default expression nesting limit #132021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ Modified Compiler Flags
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``.
Programs that use ``__aeabi_read_tp`` but do not use the ``TPIDRURO`` register must use ``-mtp=soft``. Fixes #123864

- The compiler flag `-fbracket-depth` default value is increased from 256 to 2048. (#GH94728)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, this is an aggressive change :)


Removed Compiler Flags
-------------------------

Expand Down Expand Up @@ -264,7 +266,7 @@ Improvements to Clang's diagnostics
as function arguments or return value respectively. Note that
:doc:`ThreadSafetyAnalysis` still does not perform alias analysis. The
feature will be default-enabled with ``-Wthread-safety`` in a future release.
- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) and minus(-) as signed integers
- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) and minus(-) as signed integers
except for the case where the operand is an unsigned integer
and throws warning if they are compared with unsigned integers (##18878).
- The ``-Wunnecessary-virtual-specifier`` warning has been added to warn about
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -8161,7 +8161,7 @@ def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-
MarshallingInfoFlag<LangOpts<"SetVisibilityForExternDecls">>;
def fbracket_depth : Separate<["-"], "fbracket-depth">,
HelpText<"Maximum nesting level for parentheses, brackets, and braces">,
MarshallingInfoInt<LangOpts<"BracketDepth">, "256">;
MarshallingInfoInt<LangOpts<"BracketDepth">, "2048">;
defm const_strings : BoolOption<"f", "const-strings",
LangOpts<"ConstStrings">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use">,
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class Parser : public CodeCompletionHandler {

DiagnosticsEngine &Diags;

StackExhaustionHandler StackHandler;

/// ScopeCache - Cache scopes to reduce malloc traffic.
enum { ScopeCacheSize = 16 };
unsigned NumCachedScopes;
Expand Down Expand Up @@ -518,7 +520,7 @@ class Parser : public CodeCompletionHandler {
typedef Sema::FullExprArg FullExprArg;

/// A SmallVector of statements.
typedef SmallVector<Stmt *, 32> StmtVector;
typedef SmallVector<Stmt *, 24> StmtVector;

// Parsing methods.

Expand Down Expand Up @@ -3842,6 +3844,8 @@ class Parser : public CodeCompletionHandler {
DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
DeclaratorContext Context, SourceLocation &DeclEnd,
ParsedAttributes &AccessAttrs, AccessSpecifier AS);
clang::Parser::DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
DeclaratorContext Context, SourceLocation &DeclEnd, AccessSpecifier AS);
DeclGroupPtrTy ParseDeclarationAfterTemplate(
DeclaratorContext Context, ParsedTemplateInfo &TemplateInfo,
ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,
Expand Down
17 changes: 13 additions & 4 deletions clang/include/clang/Sema/ParsedAttr.h
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,14 @@ class ParsedAttributes : public ParsedAttributesView {
pool.takeAllFrom(Other.pool);
}

void takeAllAtEndFrom(ParsedAttributes &Other) {
assert(&Other != this &&
"ParsedAttributes can't take attributes from itself");
addAllAtEnd(Other.begin(), Other.end());
Other.clearListOnly();
pool.takeAllFrom(Other.pool);
}

void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA) {
assert(&Other != this &&
"ParsedAttributes can't take attribute from itself");
Expand Down Expand Up @@ -1067,10 +1075,11 @@ class ParsedAttributes : public ParsedAttributesView {
mutable AttributePool pool;
};

/// Consumes the attributes from `First` and `Second` and concatenates them into
/// `Result`. Sets `Result.Range` to the combined range of `First` and `Second`.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second,
ParsedAttributes &Result);
/// Consumes the attributes from `Second` and concatenates them
/// at the end of `First`. Sets `First.Range`
/// to the combined range of `First` and `Second`.
void takeAndConcatenateAttrs(ParsedAttributes &First,
ParsedAttributes &&Second);

/// These constants match the enumerated choices of
/// err_attribute_argument_n_type and err_attribute_argument_type.
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2076,10 +2076,9 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
ProhibitAttributes(DeclSpecAttrs);
return ParseNamespace(Context, DeclEnd);
case tok::kw_using: {
ParsedAttributes Attrs(AttrFactory);
takeAndConcatenateAttrs(DeclAttrs, DeclSpecAttrs, Attrs);
takeAndConcatenateAttrs(DeclAttrs, std::move(DeclSpecAttrs));
return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
DeclEnd, Attrs);
DeclEnd, DeclAttrs);
}
case tok::kw_static_assert:
case tok::kw__Static_assert:
Expand Down
26 changes: 12 additions & 14 deletions clang/lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,18 +126,15 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
Stmts, StmtCtx, TrailingElseLoc, CXX11Attrs, GNUOrMSAttrs);
MaybeDestroyTemplateIds();

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

assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
assert((CXX11Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
"attributes on empty statement");

if (Attrs.empty() || Res.isInvalid())
if (CXX11Attrs.empty() || Res.isInvalid())
return Res;

return Actions.ActOnAttributedStmt(Attrs, Res.get());
return Actions.ActOnAttributedStmt(CXX11Attrs, Res.get());
}

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

// identifier ':' statement
return ParseLabeledStatement(Attrs, StmtCtx);
return ParseLabeledStatement(CXX11Attrs, StmtCtx);
}

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

case tok::kw_template: {
SourceLocation DeclEnd;
ParsedAttributes Attrs(AttrFactory);
ParseTemplateDeclarationOrSpecialization(DeclaratorContext::Block, DeclEnd,
Attrs,
getAccessSpecifierIfPresent());
return StmtError();
}
Expand Down Expand Up @@ -1057,7 +1051,11 @@ StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
ParseScope CompoundScope(this, ScopeFlags);

// Parse the statements in the body.
return ParseCompoundStatementBody(isStmtExpr);
StmtResult R;
StackHandler.runWithSufficientStackSpace(Tok.getLocation(), [&, this]() {
R = ParseCompoundStatementBody(isStmtExpr);
});
return R;
}

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

SmallVector<Decl *, 8> DeclsInGroup;
SmallVector<Decl *, 4> DeclsInGroup;
while (true) {
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected) << tok::identifier;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Parse/ParseTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(
Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
}

Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(
DeclaratorContext Context, SourceLocation &DeclEnd, AccessSpecifier AS) {
ParsedAttributes AccessAttrs(AttrFactory);
return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
AS);
}

/// Parse a single declaration that declares a template,
/// template specialization, or explicit instantiation of a template.
///
Expand Down
8 changes: 5 additions & 3 deletions clang/lib/Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/DiagnosticParse.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/StackExhaustionHandler.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
Expand Down Expand Up @@ -54,9 +55,10 @@ IdentifierInfo *Parser::getSEHExceptKeyword() {

Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
: PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),
Diags(PP.getDiagnostics()), GreaterThanIsOperator(true),
ColonIsSacred(false), InMessageExpression(false),
TemplateParameterDepth(0), ParsingInObjCContainer(false) {
Diags(PP.getDiagnostics()), StackHandler(Diags),
GreaterThanIsOperator(true), ColonIsSacred(false),
InMessageExpression(false), TemplateParameterDepth(0),
ParsingInObjCContainer(false) {
SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
Tok.startToken();
Tok.setKind(tok::eof);
Expand Down
21 changes: 8 additions & 13 deletions clang/lib/Sema/ParsedAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,18 +310,13 @@ bool ParsedAttr::checkAtMostNumArgs(Sema &S, unsigned Num) const {
}

void clang::takeAndConcatenateAttrs(ParsedAttributes &First,
ParsedAttributes &Second,
ParsedAttributes &Result) {
// Note that takeAllFrom() puts the attributes at the beginning of the list,
// so to obtain the correct ordering, we add `Second`, then `First`.
Result.takeAllFrom(Second);
Result.takeAllFrom(First);
if (First.Range.getBegin().isValid())
Result.Range.setBegin(First.Range.getBegin());
else
Result.Range.setBegin(Second.Range.getBegin());
ParsedAttributes &&Second) {

First.takeAllAtEndFrom(Second);

if (!First.Range.getBegin().isValid())
First.Range.setBegin(Second.Range.getBegin());

if (Second.Range.getEnd().isValid())
Result.Range.setEnd(Second.Range.getEnd());
else
Result.Range.setEnd(First.Range.getEnd());
First.Range.setEnd(Second.Range.getEnd());
}
4 changes: 2 additions & 2 deletions clang/test/Parser/parser_overflow.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: not %clang_cc1 %s -fsyntax-only -DHUGE 2>&1 | FileCheck %s
// RUN: not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s
// RUN: %clang_cc1 %s -fsyntax-only
// RUN: not %clang_cc1 %s -fsyntax-only -fbracket-depth 299 2>&1 | FileCheck %s
// RUN: %clang_cc1 %s -fsyntax-only -fbracket-depth 300
// RUN: not %clang %s -fsyntax-only -fbracket-depth=299 2>&1 | FileCheck %s
Expand All @@ -15,5 +15,5 @@ void foo(void) {
#endif
}

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