diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 32c6edc77168..8b7b9e04db1f 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -166,14 +166,14 @@ template static void FilterAttributeList(ArrayRef Attrs, SmallVectorImpl &FilteredAttrs) { - llvm::transform(Attrs, std::back_inserter(FilteredAttrs), [](const Attr *A) { - if (const auto *Cast = dyn_cast_or_null(A)) - return Cast->isDependent() ? nullptr : Cast; - return static_cast(nullptr); - }); + llvm::transform(Attrs, std::back_inserter(FilteredAttrs), + [](const Attr *A) -> const T * { + if (const auto *Cast = dyn_cast(A)) + return Cast->isDependent() ? nullptr : Cast; + return nullptr; + }); FilteredAttrs.erase( - std::remove(FilteredAttrs.begin(), FilteredAttrs.end(), - static_cast(nullptr)), + std::remove(FilteredAttrs.begin(), FilteredAttrs.end(), nullptr), FilteredAttrs.end()); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 0e865671f2a6..40e7d97d3748 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7321,7 +7321,8 @@ TreeTransform::TransformAttributedStmt(AttributedStmt *S, for (const auto *I : S->getAttrs()) { const Attr *R = getDerived().TransformAttr(I); AttrsChanged |= (I != R); - Attrs.push_back(R); + if (R) + Attrs.push_back(R); } StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK); @@ -7331,6 +7332,11 @@ TreeTransform::TransformAttributedStmt(AttributedStmt *S, if (SubStmt.get() == S->getSubStmt() && !AttrsChanged) return S; + // If transforming the attributes failed for all of the attributes in the + // statement, don't make an AttributedStmt without attributes. + if (Attrs.empty()) + return SubStmt; + return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs, SubStmt.get()); } diff --git a/clang/test/SemaSYCL/attr-instantiate.cpp b/clang/test/SemaSYCL/attr-instantiate.cpp new file mode 100644 index 000000000000..4e904e941f25 --- /dev/null +++ b/clang/test/SemaSYCL/attr-instantiate.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsycl-is-device -verify -fsyntax-only %s + +// Test to ensure that template instantiation of an invalid attribute argument +// does not result in a null pointer crash when rebuilding the attributed +// statement. +template void bar() { + // expected-error@+1 {{'loop_unroll' attribute requires a positive integral compile time constant expression}} + [[clang::loop_unroll(A)]] for (int i = 0; i < 10; ++i); +} + +void foo() { + bar<-1>(); // expected-note {{in instantiation of function template specialization 'bar<-1>' requested here}} +}