diff --git a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp @@ -108,7 +108,9 @@ bool CastSucceeds, bool IsKnownCast) { std::string CastToName = CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString() - : CastToTy->getPointeeCXXRecordDecl()->getNameAsString(); + : (CastToTy->getPointeeCXXRecordDecl() != nullptr) + ? CastToTy->getPointeeCXXRecordDecl()->getNameAsString() + : "(nil)"; Object = Object->IgnoreParenImpCasts(); return C.getNoteTag( @@ -163,9 +165,11 @@ bool First = true; for (QualType CastToTy: CastToTyVec) { std::string CastToName = - CastToTy->getAsCXXRecordDecl() ? - CastToTy->getAsCXXRecordDecl()->getNameAsString() : - CastToTy->getPointeeCXXRecordDecl()->getNameAsString(); + CastToTy->getAsCXXRecordDecl() + ? CastToTy->getAsCXXRecordDecl()->getNameAsString() + : (CastToTy->getPointeeCXXRecordDecl() != nullptr) + ? CastToTy->getPointeeCXXRecordDecl()->getNameAsString() + : "(nil)"; Out << ' ' << ((CastToTyVec.size() == 1) ? "not" : (First ? "neither" : "nor")) << " a '" << CastToName << '\''; diff --git a/clang/test/Analysis/cast-value-notes.cpp b/clang/test/Analysis/cast-value-notes.cpp --- a/clang/test/Analysis/cast-value-notes.cpp +++ b/clang/test/Analysis/cast-value-notes.cpp @@ -302,3 +302,17 @@ // expected-note@-1 {{Division by zero}} // expected-warning@-2 {{Division by zero}} } + +// don't crash +namespace llvm { +template void isa(a &); +template class PointerUnion { +public: + template void b() { isa(*this); } +}; +class LLVMContext { + PointerUnion c; + void d() { c.b(); } +}; +} // namespace llvm +