Skip to content

Commit 7d65cc9

Browse files
committed
[clangd] Guard against null Attrs in the AST
1 parent 5437f2e commit 7d65cc9

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

clang-tools-extra/clangd/AST.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -488,15 +488,22 @@ std::vector<const Attr *> getAttributes(const DynTypedNode &N) {
488488
if (const auto *TL = N.get<TypeLoc>()) {
489489
for (AttributedTypeLoc ATL = TL->getAs<AttributedTypeLoc>(); !ATL.isNull();
490490
ATL = ATL.getModifiedLoc().getAs<AttributedTypeLoc>()) {
491-
Result.push_back(ATL.getAttr());
491+
if (const Attr *A = ATL.getAttr())
492+
Result.push_back(A);
492493
assert(!ATL.getModifiedLoc().isNull());
493494
}
494495
}
495-
if (const auto *S = N.get<AttributedStmt>())
496+
if (const auto *S = N.get<AttributedStmt>()) {
496497
for (; S != nullptr; S = dyn_cast<AttributedStmt>(S->getSubStmt()))
497-
llvm::copy(S->getAttrs(), std::back_inserter(Result));
498-
if (const auto *D = N.get<Decl>())
499-
llvm::copy(D->attrs(), std::back_inserter(Result));
498+
for (const Attr *A : S->getAttrs())
499+
if (A)
500+
Result.push_back(A);
501+
}
502+
if (const auto *D = N.get<Decl>()) {
503+
for (const Attr *A : D->attrs())
504+
if (A)
505+
Result.push_back(A);
506+
}
500507
return Result;
501508
}
502509

clang-tools-extra/clangd/unittests/SelectionTests.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,15 @@ TEST(SelectionTest, CommonAncestor) {
465465
// Digraph syntax for attributes to avoid accidental annotations.
466466
class <:[gsl::Owner([[in^t]])]:> X{};
467467
)cpp",
468-
"BuiltinTypeLoc"}};
468+
"BuiltinTypeLoc"},
469+
470+
// This case used to crash - AST has a null Attr
471+
{R"cpp(
472+
@interface I
473+
[[@property(retain, nonnull) <:[My^Object2]:> *x]]; // error-ok
474+
@end
475+
)cpp",
476+
"ObjCPropertyDecl"}};
469477

470478
for (const Case &C : Cases) {
471479
trace::TestTracer Tracer;

0 commit comments

Comments
 (0)