File tree Expand file tree Collapse file tree 2 files changed +21
-6
lines changed Expand file tree Collapse file tree 2 files changed +21
-6
lines changed Original file line number Diff line number Diff line change @@ -488,15 +488,22 @@ std::vector<const Attr *> getAttributes(const DynTypedNode &N) {
488
488
if (const auto *TL = N.get <TypeLoc>()) {
489
489
for (AttributedTypeLoc ATL = TL->getAs <AttributedTypeLoc>(); !ATL.isNull ();
490
490
ATL = ATL.getModifiedLoc ().getAs <AttributedTypeLoc>()) {
491
- Result.push_back (ATL.getAttr ());
491
+ if (const Attr *A = ATL.getAttr ())
492
+ Result.push_back (A);
492
493
assert (!ATL.getModifiedLoc ().isNull ());
493
494
}
494
495
}
495
- if (const auto *S = N.get <AttributedStmt>())
496
+ if (const auto *S = N.get <AttributedStmt>()) {
496
497
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
+ }
500
507
return Result;
501
508
}
502
509
Original file line number Diff line number Diff line change @@ -465,7 +465,15 @@ TEST(SelectionTest, CommonAncestor) {
465
465
// Digraph syntax for attributes to avoid accidental annotations.
466
466
class <:[gsl::Owner([[in^t]])]:> X{};
467
467
)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" }};
469
477
470
478
for (const Case &C : Cases) {
471
479
trace::TestTracer Tracer;
You can’t perform that action at this time.
0 commit comments