<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Jul 18, 2014 at 12:17 AM, Abramo Bagnara <span dir="ltr"><<a href="mailto:abramo.bagnara@bugseng.com" target="_blank">abramo.bagnara@bugseng.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ping.<br>
<br>
Il 15/07/2014 12:58, Abramo Bagnara ha scritto:<br>
<div class="HOEnZb"><div class="h5">><br>
> Tracking down a failure in one of our applications I've obtained the<br>
> following testcase:<br>
><br>
> template<typename T><br>
> int operator+(T&);<br>
><br>
> template<><br>
> int operator+(class c&);<br>
><br>
> As far as I can see clang first produce an instantiation for function<br>
> template, then produces the explicit specialization as a redecl of the<br>
> former one.<br>
><br>
> The first decl is not attached to visitable AST, but only available as<br>
> redeclaration of explicit specialization (as its canonical decl).<br>
><br>
> In SemaTemplate.cpp near line 6706 we have:<br>
><br>
>   // Note: do not overwrite location info if previous template<br>
>   // specialization kind was explicit.<br>
>   TemplateSpecializationKind TSK =<br>
> SpecInfo->getTemplateSpecializationKind();<br>
>   if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation) {<br>
>     Specialization->setLocation(FD->getLocation());<br>
>     // C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr<br>
>     // function can differ from the template declaration with respect to<br>
>     // the constexpr specifier.<br>
>     Specialization->setConstexpr(FD->isConstexpr());<br>
>   }<br>
><br>
> The problem is that setLocation copy only a part of name info locations,<br>
> so the canonical decl ends up having a name range that starts from token<br>
> `operator' of specialization and ends at token `+' of template (i.e. a<br>
> negative/broken range).<br>
><br>
> Likely this is easily fixable copying both edges of range (I'm guessing,<br>
> please confirm that) but I'd like also to understand why we need to have<br>
> *two* declarations (with one of them not reachable with ordinary visits).</div></div></blockquote><div><br></div><div>We really shouldn't, but it's convenient for checking an explicit instantiation (most of the checks we perform are just 'check that this function is a valid redeclaration of the relevant implicit specialization'). The template argument deduction mechanism is currently a little too keen to build a specialization of the template from the deduced arguments.</div>
<div><br></div><div>This seems fixable if you're prepared to put the effort into doing so, but otherwise just copying across more locations would plug the immediate issue.</div></div></div></div>