Skip to content

Commit 876d1ef

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents ddaea41 + 469a0f3 commit 876d1ef

File tree

9 files changed

+321
-36
lines changed

9 files changed

+321
-36
lines changed

include/swift/Parse/Parser.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -306,30 +306,34 @@ class Parser {
306306

307307
/// An RAII object that notes when we have seen a structure marker.
308308
class StructureMarkerRAII {
309-
Parser &P;
309+
Parser *const P;
310310

311311
/// Max nesting level
312312
// TODO: customizable.
313313
enum { MaxDepth = 256 };
314314

315-
void diagnoseOverflow();
315+
StructureMarkerRAII(Parser *parser) : P(parser) {}
316+
317+
/// Have the parser start the new Structure or fail if already too deep.
318+
bool pushStructureMarker(Parser &parser, SourceLoc loc,
319+
StructureMarkerKind kind);
316320

317321
public:
318-
StructureMarkerRAII(Parser &parser, SourceLoc loc,
319-
StructureMarkerKind kind)
320-
: P(parser) {
321-
P.StructureMarkers.push_back({loc, kind, None});
322-
323-
if (P.StructureMarkers.size() >= MaxDepth) {
324-
diagnoseOverflow();
325-
P.cutOffParsing();
326-
}
327-
}
322+
StructureMarkerRAII(Parser &parser, SourceLoc loc, StructureMarkerKind kind)
323+
: StructureMarkerRAII(
324+
pushStructureMarker(parser, loc, kind) ? &parser : nullptr) {}
328325

329326
StructureMarkerRAII(Parser &parser, const Token &tok);
330327

328+
/// Did we fail to push the new structure?
329+
bool isFailed() {
330+
return P == nullptr;
331+
}
332+
331333
~StructureMarkerRAII() {
332-
P.StructureMarkers.pop_back();
334+
if (P != nullptr) {
335+
P->StructureMarkers.pop_back();
336+
}
333337
}
334338
};
335339
friend class StructureMarkerRAII;

lib/Parse/ParseExpr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2888,6 +2888,10 @@ ParserStatus Parser::parseExprList(tok leftTok, tok rightTok,
28882888
trailingClosure = nullptr;
28892889

28902890
StructureMarkerRAII ParsingExprList(*this, Tok);
2891+
2892+
if (ParsingExprList.isFailed()) {
2893+
return makeParserError();
2894+
}
28912895

28922896
leftLoc = consumeToken(leftTok);
28932897
ParserStatus status = parseList(rightTok, leftLoc, rightLoc,

lib/Parse/ParseGeneric.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ Parser::parseGenericParametersBeforeWhere(SourceLoc LAngleLoc,
5555
// Note that we're parsing a declaration.
5656
StructureMarkerRAII ParsingDecl(*this, Tok.getLoc(),
5757
StructureMarkerKind::Declaration);
58+
59+
if (ParsingDecl.isFailed()) {
60+
return makeParserError();
61+
}
5862

5963
// Parse attributes.
6064
DeclAttributes attributes;

lib/Parse/ParsePattern.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,9 @@ ParserResult<Pattern> Parser::parsePatternTuple() {
10381038
SyntaxParsingContext TuplePatternCtxt(SyntaxContext,
10391039
SyntaxKind::TuplePattern);
10401040
StructureMarkerRAII ParsingPatternTuple(*this, Tok);
1041+
if (ParsingPatternTuple.isFailed()) {
1042+
return makeParserError();
1043+
}
10411044
SourceLoc LPLoc = consumeToken(tok::l_paren);
10421045
SourceLoc RPLoc;
10431046

lib/Parse/ParseStmt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,11 @@ ParserResult<PoundAvailableInfo> Parser::parseStmtConditionPoundAvailable() {
12501250
}
12511251

12521252
StructureMarkerRAII ParsingAvailabilitySpecList(*this, Tok);
1253+
1254+
if (ParsingAvailabilitySpecList.isFailed()) {
1255+
return makeParserError();
1256+
}
1257+
12531258
SourceLoc LParenLoc = consumeToken(tok::l_paren);
12541259

12551260
SmallVector<AvailabilitySpec *, 5> Specs;

lib/Parse/ParseType.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,11 @@ ParserResult<TypeRepr> Parser::parseOldStyleProtocolComposition() {
852852
ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
853853
SyntaxParsingContext TypeContext(SyntaxContext, SyntaxKind::TupleType);
854854
Parser::StructureMarkerRAII ParsingTypeTuple(*this, Tok);
855+
856+
if (ParsingTypeTuple.isFailed()) {
857+
return makeParserError();
858+
}
859+
855860
SourceLoc RPLoc, LPLoc = consumeToken(tok::l_paren);
856861
SourceLoc EllipsisLoc;
857862
unsigned EllipsisIdx;

lib/Parse/Parser.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -757,39 +757,42 @@ bool Parser::parseEndIfDirective(SourceLoc &Loc) {
757757
return false;
758758
}
759759

760-
Parser::StructureMarkerRAII::StructureMarkerRAII(Parser &parser,
761-
const Token &tok)
762-
: P(parser)
763-
{
760+
static Parser::StructureMarkerKind
761+
getStructureMarkerKindForToken(const Token &tok) {
764762
switch (tok.getKind()) {
765763
case tok::l_brace:
766-
P.StructureMarkers.push_back({tok.getLoc(),
767-
StructureMarkerKind::OpenBrace,
768-
None});
769-
break;
770-
764+
return Parser::StructureMarkerKind::OpenBrace;
771765
case tok::l_paren:
772-
P.StructureMarkers.push_back({tok.getLoc(),
773-
StructureMarkerKind::OpenParen,
774-
None});
775-
break;
776-
766+
return Parser::StructureMarkerKind::OpenParen;
777767
case tok::l_square:
778-
P.StructureMarkers.push_back({tok.getLoc(),
779-
StructureMarkerKind::OpenSquare,
780-
None});
781-
break;
782-
768+
return Parser::StructureMarkerKind::OpenSquare;
783769
default:
784770
llvm_unreachable("Not a matched token");
785771
}
786772
}
787773

788-
void Parser::StructureMarkerRAII::diagnoseOverflow() {
789-
auto Loc = P.StructureMarkers.back().Loc;
790-
P.diagnose(Loc, diag::structure_overflow, MaxDepth);
791-
}
774+
Parser::StructureMarkerRAII::StructureMarkerRAII(Parser &parser,
775+
const Token &tok)
776+
: StructureMarkerRAII(parser, tok.getLoc(),
777+
getStructureMarkerKindForToken(tok)) {}
792778

779+
bool Parser::StructureMarkerRAII::pushStructureMarker(
780+
Parser &parser, SourceLoc loc,
781+
StructureMarkerKind kind) {
782+
783+
if (parser.StructureMarkers.size() < MaxDepth) {
784+
parser.StructureMarkers.push_back({loc, kind, None});
785+
return true;
786+
} else {
787+
parser.diagnose(loc, diag::structure_overflow, MaxDepth);
788+
// We need to cut off parsing or we will stack-overflow.
789+
// But `cutOffParsing` changes the current token to eof, and we may be in
790+
// a place where `consumeToken()` will be expecting e.g. '[',
791+
// since we need that to get to the callsite, so this can cause an assert.
792+
parser.cutOffParsing();
793+
return false;
794+
}
795+
}
793796
//===----------------------------------------------------------------------===//
794797
// Primitive Parsing
795798
//===----------------------------------------------------------------------===//
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %target-swift-frontend -parse %s 2>&1 | %FileCheck -allow-empty %s
2+
3+
// Test that we can have the allowed # of parens.
4+
// CHECK-NOT: error
5+
let a = (((((((((((((((((((((((((((((((( ((((((((((((((((((((((((((((((((
6+
(((((((((((((((((((((((((((((((( ((((((((((((((((((((((((((((((((
7+
(((((((((((((((((((((((((((((((( ((((((((((((((((((((((((((((((((
8+
(((((((((((((((((((((((((((((((( ((((((((((((((((((((((((((((((
9+
1
10+
)))))))))))))))))))))))))))))) ))))))))))))))))))))))))))))))))
11+
)))))))))))))))))))))))))))))))) ))))))))))))))))))))))))))))))))
12+
)))))))))))))))))))))))))))))))) ))))))))))))))))))))))))))))))))
13+
)))))))))))))))))))))))))))))))) ))))))))))))))))))))))))))))))))
14+
15+
// Test that we can have the allowed # of curly braces.
16+
/// CHECK-NOT: error
17+
let b = {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
18+
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
19+
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
20+
{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
21+
1
22+
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
23+
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
24+
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
25+
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
26+
27+
// Test that we can have the allowed # of mixed brackets.
28+
// CHECK-NOT: error
29+
let c = ({({({({ ({({({([ ({({({({ ({({({([ ({({({({ ({({({([ ({({({({ ({({({({
30+
({({({({ ({({({([ ({({({({ ({({({([ ({({({({ ({({({([ ({({({({ ({({({({
31+
({({({({ ({({({([ ({({({({ ({({({([ ({({({({ ({({({([ ({({({({ ({({({({
32+
({({({({ ({({({([ ({({({({ ({({({([ ({({({({ ({({({([ ({({({({ ({({({
33+
1
34+
})})}) })})})}) ])})})}) })})})}) ])})})}) })})})}) ])})})}) })})})})
35+
})})})}) })})})}) ])})})}) })})})}) ])})})}) })})})}) ])})})}) })})})})
36+
})})})}) })})})}) ])})})}) })})})}) ])})})}) })})})}) ])})})}) })})})})
37+
})})})}) })})})}) ])})})}) })})})}) ])})})}) })})})}) ])})})}) })})})})

0 commit comments

Comments
 (0)