File tree Expand file tree Collapse file tree 3 files changed +29
-0
lines changed Expand file tree Collapse file tree 3 files changed +29
-0
lines changed Original file line number Diff line number Diff line change @@ -186,6 +186,17 @@ TEST(DumpASTTests, Arcana) {
186186 EXPECT_THAT (Node.children .front ().arcana , testing::StartsWith (" QualType " ));
187187}
188188
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+
189200} // namespace
190201} // namespace clangd
191202} // namespace clang
Original file line number Diff line number Diff line change @@ -401,6 +401,12 @@ std::string TokenBuffer::Mapping::str() const {
401401
402402std::optional<llvm::ArrayRef<syntax::Token>>
403403TokenBuffer::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+ }
404410 // Mapping an empty range is ambiguous in case of empty mappings at either end
405411 // of the range, bail out in that case.
406412 if (Expanded.empty ())
Original file line number Diff line number Diff line change @@ -816,6 +816,18 @@ TEST_F(TokenBufferTest, SpelledByExpanded) {
816816 EXPECT_EQ (Buffer.spelledForExpanded (findExpanded (" prev good" )), std::nullopt );
817817}
818818
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+
819831TEST_F (TokenBufferTest, ExpandedTokensForRange) {
820832 recordTokens (R"cpp(
821833 #define SIGN(X) X##_washere
You can’t perform that action at this time.
0 commit comments