<div dir="ltr">It looks like this would only happen for a late-parsed template that the analysis code is checking before it is parsed. Should we really be running these checks at all in that case?<div><br></div><div>Also, it looks like this code doesn't actually want the body at all, and just wants to get the location of the definition. Asking for the body here does not seem like the right approach, because it'll cause the external AST source (if there is one) to fault the body in.<div><br></div><div>The right fix is probably something like:</div><div><br></div><div>  const FunctionDecl *Def;</div><div>  SourceLocation SL = (D->isDefined(Def) ? Def : D)->getLocation();<br></div><div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Aug 19, 2015 at 1:44 PM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The attached patch resolves the null pointer crash I am seeing.<br>
<span class="HOEnZb"><font color="#888888"><br>
~Aaron<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
On Wed, Aug 19, 2015 at 1:24 PM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>> wrote:<br>
> On Wed, Aug 19, 2015 at 11:33 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>> wrote:<br>
>> When I run the following test code through clang-tidy -checks=*, I get<br>
>> a crash from some relatively strange behavior with FunctionDecl.<br>
>><br>
>> template <class T> struct remove_reference      {typedef T type;};<br>
>> template <class T> struct remove_reference<T&>  {typedef T type;};<br>
>> template <class T> struct remove_reference<T&&> {typedef T type;};<br>
>><br>
>> template <typename T><br>
>> typename remove_reference<T>::type&& move(T&& arg) {<br>
>>   return static_cast<typename remove_reference<T>::type&&>(arg);<br>
>> }<br>
>><br>
>> AnalysisConsumer::getModeForDecl() is called, and it has code that<br>
>> does: D->hasBody() ? D->getBody()->stuff : stuff;<br>
>><br>
>> What's strange is that hasBody() returns true, but getBody() returns<br>
>> nullptr. I don't think that this should be possible. I'm wondering<br>
>> whether it's purposeful that hasBody() does not check<br>
>> Definition->Body?<br>
><br>
> Looking into this a bit further, the issue is that hasBody() checks<br>
> for Definition->Body *or* Definition->IsLateTemplateParsed when<br>
> deciding to return true. In my case, Body is null, but<br>
> IsLateTemplateParsed is true, so hasBody() returns true. However,<br>
> getBody() doesn't have any special logic for late template parsed<br>
> function bodies.<br>
><br>
>> Also, the FunctionDecl in question is for move(), which does have a<br>
>> body, so I do not understand why the definition would claim there is<br>
>> no body.<br>
>><br>
>> Ideas, or should I file a bug report?<br>
><br>
> From my further look, I wonder if the correct solution to this is to<br>
> simply call getBody() and handle a nullptr return instead of calling<br>
> hasBody() first. It basically makes the check to ignore late parsed<br>
> template bodies an implicit one.<br>
><br>
> ~Aaron<br>
</div></div></blockquote></div><br></div></div></div></div>