Skip to content

Commit 7b3dce1

Browse files
committed
[C++ parser] Make sure break out of a parser loop on ill-formed macro expansion of members
The condition to make sure that the parser makes progress when there is an ill-formed macro expansion to members was incorrect, causing an infinite loop if there was at least one well-formed declaration followed by ill-formed code (in this case, a `}`). Fix the condition. Fixes rdar://137828917.
1 parent af036fe commit 7b3dce1

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8320,8 +8320,8 @@ void Parser::parseExpandedMemberList(SmallVectorImpl<ASTNode> &items) {
83208320

83218321
bool previousHadSemi = true;
83228322

8323-
SourceLoc startingLoc = Tok.getLoc();
83248323
while (!Tok.is(tok::eof)) {
8324+
SourceLoc startingLoc = Tok.getLoc();
83258325
parseDeclItem(previousHadSemi, [&](Decl *d) { items.push_back(d); });
83268326

83278327
if (Tok.getLoc() == startingLoc)

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2704,3 +2704,30 @@ public struct AddGetterMacro: AccessorMacro {
27042704
return ["get { 0 }"]
27052705
}
27062706
}
2707+
2708+
public struct HangingMacro: PeerMacro {
2709+
public static func expansion(
2710+
of node: AttributeSyntax,
2711+
providingPeersOf declaration: some DeclSyntaxProtocol,
2712+
in context: some MacroExpansionContext
2713+
) throws -> [DeclSyntax] {
2714+
guard let variableDecl = declaration.as(VariableDeclSyntax.self) else {
2715+
return []
2716+
}
2717+
2718+
guard let binding: PatternBindingSyntax = variableDecl.bindings.first else {
2719+
return []
2720+
}
2721+
2722+
guard let typeAnnotation = binding.typeAnnotation else {
2723+
return []
2724+
}
2725+
2726+
let mockProperty = try VariableDeclSyntax("var BadThing: \(typeAnnotation.type)") {
2727+
}
2728+
2729+
return [
2730+
DeclSyntax(mockProperty)
2731+
]
2732+
}
2733+
}

test/Macros/expand_peers_hang.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// REQUIRES: swift_swift_parser, executable_test
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -parse-as-library -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
5+
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking
6+
7+
@attached(peer, names: named(BadThing))
8+
macro HangingMacro() = #externalMacro(module: "MacroDefinition", type: "HangingMacro")
9+
10+
// expected-note@+1{{in declaration of 'Foo'}}
11+
class Foo {
12+
init() {}
13+
14+
// expected-note@+1 2{{in expansion of macro 'HangingMacro' on property 'result' here}}
15+
@HangingMacro var result: Int // This comment makes it hang.
16+
}

0 commit comments

Comments
 (0)