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

Reply via email to