Skip to content

Commit d3e3238

Browse files
committed
Parse: Better error recovery from invalid attributes
1 parent e1f50b2 commit d3e3238

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,9 @@ bool Parser::parseDeclAttributeList(DeclAttributes &Attributes,
18611861
FoundCCToken = false;
18621862
if (Tok.isNot(tok::at_sign))
18631863
return false;
1864+
1865+
bool error = false;
1866+
18641867
SyntaxParsingContext AttrListCtx(SyntaxContext, SyntaxKind::AttributeList);
18651868
do {
18661869
if (peekToken().is(tok::code_complete)) {
@@ -1871,10 +1874,12 @@ bool Parser::parseDeclAttributeList(DeclAttributes &Attributes,
18711874
}
18721875
SyntaxParsingContext AttrCtx(SyntaxContext, SyntaxKind::Attribute);
18731876
SourceLoc AtLoc = consumeToken();
1874-
if (parseDeclAttribute(Attributes, AtLoc))
1875-
return true;
1877+
if (parseDeclAttribute(Attributes, AtLoc)) {
1878+
// Consume any remaining attributes for better error recovery.
1879+
error = true;
1880+
}
18761881
} while (Tok.is(tok::at_sign));
1877-
return false;
1882+
return error;
18781883
}
18791884

18801885
/// \brief This is the internal implementation of \c parseTypeAttributeList,

test/attr/attributes.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,8 @@ class SILStored {
260260

261261
@_show_in_interface protocol _underscored {}
262262
@_show_in_interface class _notapplicable {} // expected-error {{may only be used on 'protocol' declarations}}
263+
264+
// Error recovery after one invalid attribute
265+
@_invalid_attribute_ // expected-error {{unknown attribute '_invalid_attribute_'}}
266+
@inline(__always)
267+
public func sillyFunction() {}

0 commit comments

Comments
 (0)