Skip to content

Commit 3976aca

Browse files
committed
[SourceKit] Fix crash in getUIDForDecl() with invalid operator
We may know syntactically that we have an operator without being able to find the associated operator decl when the input is invalid/incomplete. Don't crash when that happens, and just fallback to a "free function" decl kind. rdar://problem/25196625
1 parent 88c1065 commit 3976aca

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

test/SourceKit/SourceDocInfo/cursor_invalid.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ class C {
1313
class MyCoolClass: Undeclared {}
1414
}
1515

16+
func resyncParser1() {}
17+
18+
func ==
19+
func ==()
20+
func ==(x: C)
21+
func ==(x: C, y: C)
22+
23+
func resyncParser2() {}
24+
1625
// RUN: %sourcekitd-test -req=cursor -pos=4:13 %s -- %s | FileCheck -check-prefix=CHECK1 %s
1726
// CHECK1: source.lang.swift.decl.var.local (4:13-4:14)
1827
// CHECK1: c
@@ -38,3 +47,15 @@ class C {
3847
// RUN: %sourcekitd-test -req=cursor -pos=7:12 %s -- %s | FileCheck -check-prefix=EMPTY %s
3948
// RUN: %sourcekitd-test -req=cursor -pos=9:7 %s -- %s | FileCheck -check-prefix=EMPTY %s
4049
// EMPTY: <empty cursor info>
50+
51+
// RUN: %sourcekitd-test -req=cursor -pos=18:6 %s -- %s | FileCheck -check-prefix=EQEQ1 %s
52+
// RUN: %sourcekitd-test -req=cursor -pos=19:6 %s -- %s | FileCheck -check-prefix=EQEQ1 %s
53+
// Note: we can't find the operator decl so the decl kind is a fallback.
54+
// EQEQ1: <decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>==</decl.name>()
55+
56+
// RUN: %sourcekitd-test -req=cursor -pos=20:6 %s -- %s | FileCheck -check-prefix=EQEQ2 %s
57+
// Note: we can't find the operator decl so the decl kind is a fallback.
58+
// EQEQ2: <decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>==</decl.name>(<decl.var.parameter><decl.var.parameter.name>x</decl.var.parameter.name>: <decl.var.parameter.type><ref.class usr="s:C14cursor_invalid1C">C</ref.class></decl.var.parameter.type></decl.var.parameter>)</decl.function.free>
59+
60+
// RUN: %sourcekitd-test -req=cursor -pos=21:6 %s -- %s | FileCheck -check-prefix=EQEQ3 %s
61+
// EQEQ3: <decl.function.operator.infix><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>==</decl.name>(<decl.var.parameter><decl.var.parameter.name>x</decl.var.parameter.name>: <decl.var.parameter.type><ref.class usr="s:C14cursor_invalid1C">C</ref.class></decl.var.parameter.type></decl.var.parameter>, <decl.var.parameter><decl.var.parameter.name>y</decl.var.parameter.name>: <decl.var.parameter.type><ref.class usr="s:C14cursor_invalid1C">C</ref.class></decl.var.parameter.type></decl.var.parameter>)</decl.function.operator.infix>

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ UIdent UIdentVisitor::visitFuncDecl(const FuncDecl *D) {
197197
IsRef);
198198
}
199199

200-
if (D->isOperator()) {
201-
switch (D->getOperatorDecl()->getKind()) {
200+
if (auto *Op = D->getOperatorDecl()) {
201+
switch (Op->getKind()) {
202202
case DeclKind::PrefixOperator:
203203
return IsRef ? KindRefFunctionPrefixOperator : KindDeclFunctionPrefixOperator;
204204
case DeclKind::PostfixOperator:

0 commit comments

Comments
 (0)