etienneb created this revision. etienneb added reviewers: rnk, alexfh, emso, bkramer. etienneb added a subscriber: cfe-commits. Herald added a subscriber: aemerson.
Fix crashes caused by deferencing null pointer when declarations parsing may be delayed. The body of the declarations may be null. The crashes were observed on a Windows build. command-line switches: -fms-compatibility-version=19 -fms-compatibility To reproduce them, run clang-tidy over the following basic file: #include <string> int main() {} Templated functions that aren't used may contains a "null" body even if the decl->hasBody() is returning true. template <typename T> void f() {} FunctionTemplateDecl 0xd06340 <C:\src\llvm\examples\test.cc:1:1, col:34> col:28 f |-TemplateTypeParmDecl 0xd061e8 <col:11, col:20> col:20 typename T `-FunctionDecl 0xd062d0 <col:23, col:34> col:28 f 'void (void)' `-<<<NULL>>> http://reviews.llvm.org/D18238 Files: cppcoreguidelines/ProTypeMemberInitCheck.cpp modernize/RedundantVoidArgCheck.cpp Index: cppcoreguidelines/ProTypeMemberInitCheck.cpp =================================================================== --- cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -179,6 +179,11 @@ const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor"); const auto &MemberFields = Ctor->getParent()->fields(); + // Skip delayed template instantiation declarations. + const auto *Body = Ctor->getBody(); + if (!Body) + return; + SmallPtrSet<const FieldDecl *, 16> FieldsToInit; fieldsRequiringInit(MemberFields, FieldsToInit); if (FieldsToInit.empty()) @@ -193,7 +198,7 @@ continue; FieldsToInit.erase(Init->getMember()); } - removeFieldsInitializedInBody(*Ctor->getBody(), *Result.Context, + removeFieldsInitializedInBody(*Body, *Result.Context, FieldsToInit); if (FieldsToInit.empty()) return; Index: modernize/RedundantVoidArgCheck.cpp =================================================================== --- modernize/RedundantVoidArgCheck.cpp +++ modernize/RedundantVoidArgCheck.cpp @@ -105,8 +105,9 @@ SourceLocation Start = Function->getLocStart(); if (Function->isThisDeclarationADefinition()) { SourceLocation End; - if (Function->hasBody()) - End = Function->getBody()->getLocStart().getLocWithOffset(-1); + const auto *Body = Function->getBody(); + if (Body) + End = Body->getLocStart().getLocWithOffset(-1); else End = Function->getLocEnd(); removeVoidArgumentTokens(Result, SourceRange(Start, End),
Index: cppcoreguidelines/ProTypeMemberInitCheck.cpp =================================================================== --- cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -179,6 +179,11 @@ const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor"); const auto &MemberFields = Ctor->getParent()->fields(); + // Skip delayed template instantiation declarations. + const auto *Body = Ctor->getBody(); + if (!Body) + return; + SmallPtrSet<const FieldDecl *, 16> FieldsToInit; fieldsRequiringInit(MemberFields, FieldsToInit); if (FieldsToInit.empty()) @@ -193,7 +198,7 @@ continue; FieldsToInit.erase(Init->getMember()); } - removeFieldsInitializedInBody(*Ctor->getBody(), *Result.Context, + removeFieldsInitializedInBody(*Body, *Result.Context, FieldsToInit); if (FieldsToInit.empty()) return; Index: modernize/RedundantVoidArgCheck.cpp =================================================================== --- modernize/RedundantVoidArgCheck.cpp +++ modernize/RedundantVoidArgCheck.cpp @@ -105,8 +105,9 @@ SourceLocation Start = Function->getLocStart(); if (Function->isThisDeclarationADefinition()) { SourceLocation End; - if (Function->hasBody()) - End = Function->getBody()->getLocStart().getLocWithOffset(-1); + const auto *Body = Function->getBody(); + if (Body) + End = Body->getLocStart().getLocWithOffset(-1); else End = Function->getLocEnd(); removeVoidArgumentTokens(Result, SourceRange(Start, End),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits