<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Apr 14, 2016 at 11:57 AM, Akira Hatanaka via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thanks, I was about to send an update.<div><br></div><div><div class="gmail_quote">I made a few changes to make sure the lambda class gets the right parent DeclContext, which I think is the translation unit (type Decl::TranslationUnit) in my example. Currently, when the variable template is instantiated (fn<char>), function "func" is passed as the DeclContext to CXXRecordDecl::CreateLambda, which is causing CXXRecordDecl::isDependentType() to return true.</div><div class="gmail_quote"><br></div><div class="gmail_quote">With this change, clang doesn't crash anymore.</div><div class="gmail_quote"><br></div><div class="gmail_quote">Does it sound like I'm headed in the right direction? I can send my WIP patch for review to cfe-commits if that makes it easier to discuss my current approach.</div></div></div></blockquote><div><br></div><div>Yes, that sounds like you've found the root cause and are heading in the right direction.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><div class="gmail_quote">On Thu, Apr 14, 2016 at 11:52 AM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div>On Wed, Apr 13, 2016 at 3:19 PM, Akira Hatanaka <span dir="ltr"><<a href="mailto:ahatanak@gmail.com" target="_blank">ahatanak@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div class="gmail_extra"><div class="gmail_quote">On Tue, Apr 12, 2016 at 5:34 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Tue, Apr 12, 2016 at 5:22 PM, Akira Hatanaka via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>I was wondering whether someone could answer a few questions about variable templates. I'm trying to come up with a patch that fixes the crash described in PR27015.</div><div><br></div><div><a href="https://llvm.org/bugs/show_bug.cgi?id=27015" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=27015</a><br></div><div><br></div><div>The crash happens when clang compiles a code that has a variable template initialized with a generic lambda. For example,</div><div><br></div><div>$ cat test1.c</div><div><br></div>template<typename T> auto fn = [](auto a) { return a + T(1); };<br><br><div>template <typename X><br>int func() {<br>  X a = 0x61;<br>  fn<char>(a);<br>  return 0;<br>}<br><br></div><div>int main() {<br>  func<int>();<div>}<p></p><p></p></div></div><div>First question, is this legal c++14 code? I didn't find anything that suggests it isn't legal, but I haven't found any code that uses variable templates like this either other than the provided test case.</div></div></blockquote><div><br></div></span><div>Yes, sadly, this is valid C++14 code.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Second question, what would the closure type look like in this case? My understanding is that the closure type for generic lambda without template parameters looks like this:</div><div><br></div><div>class Class {</div><div>template<typename AT></div><div>  AT operator()(AT a) { ... }</div><div>  ...</div><div>};</div><div><br></div><div>With template parameter, would it look like this?</div><div><br></div><div>template<typename T></div><div><div>class Class {</div><div>template<typename AT></div><div>  AT operator()(AT a) { return a + T(1); }</div><div>  ...</div><div>};</div></div></div></blockquote><div><br></div></span><div>No. Each instantiation of 'fn' gets its own closure type. The closure type from the template itself should be treated as being in a dependent context, even though there is no dependent DeclContext to contain it. </div></div></div></div>
</blockquote></div><br></div></div></div><div class="gmail_extra">After the template declaration for func is parsed, VarTemplateSpecialization for fn looks like this in the AST:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><span>`-</span><span><b>VarTemplateSpecializationDecl</b></span><span> 0x10d001a00</span><span> <</span><span>line:23:22</span><span>, </span><span>col:62</span><span>> </span><span>col:27</span><span> referenced</span><span><b> fn</b></span><span> </span><span>'auto'</span><span> cinit</span><br></div><div class="gmail_extra"><span><br></span></div><div class="gmail_extra"><span>I think this is not correct as the type of the VarTemplateSpecializationDecl at this point should be the closure type for fn<char> instead of 'auto'. Is that correct?</span></div></div></blockquote><div><br></div></div></div><div>Yes.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><span>I'm still trying to understand how instantiation of variable templates works, but it seems like one of the problem is that Sema::createLambdaClosureType is returning a type that is dependent (CXXRecordDecl::isDependentType() returns true</span>), which looks like is preventing the type of VarTemplateSpecialization from being replaced.</div></div>
</blockquote></span></div><br></div><div class="gmail_extra">The closure type created in the instantiation should not be considered dependent. If it is, that's a bug.</div></div>
</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div></div>