File tree 3 files changed +29
-0
lines changed
3 files changed +29
-0
lines changed Original file line number Diff line number Diff line change @@ -186,6 +186,17 @@ TEST(DumpASTTests, Arcana) {
186
186
EXPECT_THAT (Node.children .front ().arcana , testing::StartsWith (" QualType " ));
187
187
}
188
188
189
+ TEST (DumpASTTests, UnbalancedBraces) {
190
+ // Test that we don't crash while trying to compute a source range for the
191
+ // node whose ending brace is missing, and also that the source range is
192
+ // not empty.
193
+ Annotations Case (" /*error-ok*/ $func[[int main() {]]" );
194
+ ParsedAST AST = TestTU::withCode (Case.code ()).build ();
195
+ auto Node = dumpAST (DynTypedNode::create (findDecl (AST, " main" )),
196
+ AST.getTokens (), AST.getASTContext ());
197
+ ASSERT_EQ (Node.range , Case.range (" func" ));
198
+ }
199
+
189
200
} // namespace
190
201
} // namespace clangd
191
202
} // namespace clang
Original file line number Diff line number Diff line change @@ -401,6 +401,12 @@ std::string TokenBuffer::Mapping::str() const {
401
401
402
402
std::optional<llvm::ArrayRef<syntax::Token>>
403
403
TokenBuffer::spelledForExpanded (llvm::ArrayRef<syntax::Token> Expanded) const {
404
+ // In cases of invalid code, AST nodes can have source ranges that include
405
+ // the `eof` token. As there's no spelling for this token, exclude it from
406
+ // the range.
407
+ if (!Expanded.empty () && Expanded.back ().kind () == tok::eof) {
408
+ Expanded = Expanded.drop_back ();
409
+ }
404
410
// Mapping an empty range is ambiguous in case of empty mappings at either end
405
411
// of the range, bail out in that case.
406
412
if (Expanded.empty ())
Original file line number Diff line number Diff line change @@ -816,6 +816,18 @@ TEST_F(TokenBufferTest, SpelledByExpanded) {
816
816
EXPECT_EQ (Buffer.spelledForExpanded (findExpanded (" prev good" )), std::nullopt);
817
817
}
818
818
819
+ TEST_F (TokenBufferTest, NoCrashForEofToken) {
820
+ recordTokens (R"cpp(
821
+ int main() {
822
+ )cpp" );
823
+ ASSERT_TRUE (!Buffer.expandedTokens ().empty ());
824
+ ASSERT_EQ (Buffer.expandedTokens ().back ().kind (), tok::eof);
825
+ // Expanded range including `eof` is handled gracefully (`eof` is ignored).
826
+ EXPECT_THAT (
827
+ Buffer.spelledForExpanded (Buffer.expandedTokens ()),
828
+ ValueIs (SameRange (Buffer.spelledTokens (SourceMgr->getMainFileID ()))));
829
+ }
830
+
819
831
TEST_F (TokenBufferTest, ExpandedTokensForRange) {
820
832
recordTokens (R"cpp(
821
833
#define SIGN(X) X##_washere
You can’t perform that action at this time.
0 commit comments