Skip to content

Commit 6095053

Browse files
committed
[libSyntax] Explicitly return 0 as length of missing deferred tokens
Previously, we were always accessing the `DeferredTokenNode`’s `Range`, which is not valid if the token is missing, thus causing an assertion failure when asked for its length. Fixes rdar://77391988 [SR-14552]
1 parent c7b383c commit 6095053

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

test/Syntax/Parser/fixed_crashers.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ let x: a[i] & b
66

77
let x2: a & b[1]
88
// CHECK: |x2|
9+
10+
let x3: (A -> B)
11+
// CHECK: |x3|

tools/libSwiftSyntaxParser/libSwiftSyntaxParser.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,16 @@ struct DeferredTokenNode {
111111
: IsMissing(IsMissing), TokenKind(TokenKind),
112112
LeadingTrivia(LeadingTrivia), TrailingTrivia(TrailingTrivia),
113113
Range(Range) {}
114+
115+
/// Returns the length of this token or \c 0 if the token is missing.
116+
size_t getLength() const {
117+
if (IsMissing) {
118+
return 0;
119+
} else {
120+
assert(Range.isValid());
121+
return Range.getByteLength();
122+
}
123+
}
114124
};
115125

116126
struct DeferredLayoutNode {
@@ -272,7 +282,7 @@ class CLibParseActions final : public SyntaxParseActions {
272282
break;
273283
case RecordedOrDeferredNode::Kind::DeferredToken:
274284
length += static_cast<const DeferredTokenNode *>(child.getOpaque())
275-
->Range.getByteLength();
285+
->getLength();
276286
break;
277287
}
278288
}
@@ -373,7 +383,7 @@ class CLibParseActions final : public SyntaxParseActions {
373383
case RecordedOrDeferredNode::Kind::DeferredToken:
374384
StartLoc = StartLoc.getAdvancedLoc(
375385
static_cast<const DeferredTokenNode *>(Child.getOpaque())
376-
->Range.getByteLength());
386+
->getLength());
377387
break;
378388
}
379389
}

0 commit comments

Comments
 (0)