<div dir="ltr"><div><div><div><div><div><div>Hi Richard,<br><br></div>As per your comments, I am now comparing return type from type source info.<br>By this way we are able to catch hold of ' auto ' as return type of declared function.<br>
If the return types from type source info do not match, then error is emitted.<br>
</div>I am doing this only for auto types, as there can be return type of template <br>parameter of the declared template (in which, we do not compare as template parameter can equal actual return type).<br><u><br></u></div>
<div><u>Patch Code highlight:<br><br></u></div> <i>TypeSourceInfo *TI = Function->getTypeSourceInfo();<br>
    QualType FuncReturnType = TI->getType()->castAs<FunctionType>()->getReturnType();<br>    if (isa<FunctionType>(ArgFunctionType)){<br>        QualType ArgFunctionReturnType = ArgFunctionType->getAs<FunctionType>()->getReturnType();</i><br>
<i><i>// We check for auto contained type to eliminate checking template parameter as return type </i>
       <br>         if (FuncReturnType->getContainedAutoType()){       <br>          if (!Context.hasSameType(ArgFunctionReturnType,FuncReturnType))<br>            return TDK_MiscellaneousDeductionFailure;<br>          else<br>
              return TDK_Success;<br>
            }<br>       }</i><br><br></div>Bug 19551 gets resolved with this patch.<br><br></div><u>Test case :</u><br><br><i>template<typename T> auto f(T) { return 0; }<br>int k = f(0); // #1<br>template auto f(int); // #2<br>

template int f(int); // #3</i><br><br></div><u>Output with patch :</u><br><div><div><i><br>suyog@suyog-Inspiron-N5010:~$ llvm/llvm/build/bin/clang bug_19551.C -std=c++1y<br>bug_19551.C:4:14: error: explicit instantiation of 'f' does not refer to a function template, variable template, member function, member class,<br>

      or static data member<br>template int f(int); // #3<br>             ^<br>bug_19551.C:1:27: note: candidate template ignored: failed template argument deduction<br>template<typename T> auto f(T) { return 0; }<br>

                          ^<br>1 error generated.</i><br><br></div><div><br><br>This patch also differentiates between ' auto ' and ' auto* ' and throws error for such case too.<br><br></div><div>However, I am getting 1 regression in file test/SemaCXX/cxx1y-deduced-return-type.cpp.<br>

</div><div>It contains cases where return types are same and we also need to check if Specialization type <br></div><div>matches with ArgFunction Type - which is exactly opposite to our test case <br>(Specialization type doesn't match with ArgFunction Type in our test case 19551). Its like trying to validate true and false<br>
</div><div>at the same time.<br><br></div><div>I am attaching patch for the reference. (test case excluded for a while).<br><br></div><div>Your comment will be a great help to resolve this. Thanks !<br></div><div> <br></div>
</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, May 9, 2014 at 6:02 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 class="">On Thu, May 8, 2014 at 2:20 PM, suyog sarda <span dir="ltr"><<a href="mailto:sardask01@gmail.com" target="_blank">sardask01@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">Thanks Richard for your review. <div><br></div><div>Just to be sure, clarifying things. In our test case :</div>

<div><br></div><div><div><i>template<typename T> auto f(T) { return 0; }   // Line 1</i></div>
<div><i>int k = f(0); // Line 2</i></div><div><i>template auto f(int); // Line 3</i></div><div><i>template int f(int); // Line 4</i></div></div><div><br></div><div>Do you mean that we should compare the declared return type i.e return type declared in </div>


<div>template declaration (i.e the line 1) with declared return type in explicit instantiation(line 3)? </div><div>And those we will get from type source info for both ?</div></div></blockquote><div><br></div></div><div>
What I mean is, we should compare the return type in the type source info (getTypeSourceInfo) not the return type in the type (getType) of the function. The former should have 'auto' in it, the latter will have an actual type. The types in the type source info should be the same; the types in the declaration might not be.</div>
<div class="">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Also is this the right way to compare two auto types - <i>(A->getContainedAutoType<span style="color:rgb(0,0,0)">()</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,0)">&& B-></span>getContainedAutoType<span style="color:rgb(0,0,0)">()) ?</span></i></div>


<div><i>Context.hasSameType</i> for both being auto don't return true, probably because two auto's will not necessarily deduce to same type.  </div></div></blockquote><div><br></div></div><div>hasSameType is the right check, once you get hold of the declared/undeduced type. Note that 'auto *' and 'const auto &' will both have a contained auto type, so your comparison won't do the right thing there.</div>
<div><div class="h5">
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>(If true, ArgFunctionType passed in the function as argument is already from TypeSource info of the instantiation, so we need only return type from type source info of template declaration, and compare them for auto type.)</div>


<div><br></div><div>Thanks again for quick review. </div><div><br></div><div><br></div></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, May 9, 2014 at 2:17 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">The patch isn't correct. It allows a return type of 'auto' to match a return type of 'auto *', for instance.</div>


<div class="gmail_quote">
<br></div><div class="gmail_quote">The right thing to do here is to compare the declared return type (obtained from the type source info on the function declaration), not the actual return type. (If the declared return type is missing the 'auto', that's a bug.)</div>


<div><div>
<div class="gmail_quote"><br></div><div class="gmail_quote">On Thu, May 8, 2014 at 12:12 PM, suyog sarda <span dir="ltr"><<a href="mailto:sardask01@gmail.com" target="_blank">sardask01@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><div><div dir="ltr"><br><div class="gmail_quote"><div dir="ltr"><div><div><div>Hi,<br><br>
</div>Attaching Patch for bug 19551. Please help in reviewing it. <br><br></div>I am checking for return type as auto in template declaration and explicit template instantiation. This patch resolves bug 19551 and has no regressions. I am not sure though if this is the correct approach. <br>





<br></div>Please help in reviewing and corrections.<br><div><div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, May 7, 2014 at 10:32 PM, suyog sarda <span dir="ltr"><<a href="mailto:sardask01@gmail.com" target="_blank">sardask01@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><font face="arial, helvetica, sans-serif">Hi,<br><br></font></div><font face="arial, helvetica, sans-serif">I was looking at Bug 19551.<br>





</font></div><font face="arial, helvetica, sans-serif"><br>
The test case is as follows :<br><br></font><pre><i><font face="arial, helvetica, sans-serif">template<typename T> auto f(T) { return 0; }
int k = f(0); // #1
template auto f(int); // #2
template int f(int); // #3</font></i></pre><pre><font face="arial, helvetica, sans-serif">Without line #1, clang accept #2 and reject #3.
With line #1, clang reject #2 and accept #3.<br><br></font></pre><pre><font face="arial, helvetica, sans-serif">I debug this code and found following :<br><br></font></pre><pre><font face="arial, helvetica, sans-serif">1. When the function template is instantiated (#1), clang visits functions<br>






   <br>
   <i>Sema::AddTemplateOverloadCandidate  <br>       Sema::DeduceTemplateArguments          <br>           Sema::FinishTemplateArgumentDeduction</i><br><br></font></pre><pre><font face="arial, helvetica, sans-serif">In <i>Sema::FinishTemplateArgumentDeduction</i> function, it creates a Specialization of the functiontemplate :<br>






<br><i>          Specialization = cast_or_null<FunctionDecl>(<br>                      SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner,<br>                         MultiLevelTemplateArgumentList(*DeducedArgumentList)));</i><br>







</font></pre><pre><font face="arial, helvetica, sans-serif">The return type of the created Specialization is 'auto' at this point. After this, <br>it completes deduction of TemplateArguments and adds this Specialization as overloaded <br>






candidate. The return type still remains 'auto'.<br>
<br></font></pre><pre><font face="arial, helvetica, sans-serif">2. When clang process #2 (explicit instantiation), clang visits following function :<br><br>     <i>Sema::ActOnExplicitInstantiation<br>          Sema::DeduceTemplateArguments</i><br>






<i>               Sema::FinishTemplateArgumentDeduction   </i><br>
<br></font></pre><pre><font face="arial, helvetica, sans-serif">Again clang creates Specialization as in point 1 above, but strangely, <br>this time the return type of Specialization is 'int' though the return type of <br>






FunctionTemplate remains 'auto'. Since this return type 'int' does not match with <br>return type of explicit instantiation i.e. 'auto', the DeduceTemplateArguments return <br>failure.<br><br><br>





        <br>
<i>    Sema::DeduceTemplateArguments{<br>          .................<br>          ................<br>
          ..................<br><br>         </i> <i>else if(!InOverloadResolution && !AT &&<br>            !Context.hasSameType(Specialization->getType(), ArgFunctionType)) //ArgFunctionType - auto <br>







                                                                              // SpecializationType - int<br>      return TDK_MiscellaneousDeductionFailure;<br><br>}<br><br></i></font></pre><pre><font face="arial, helvetica, sans-serif">Hence, we get error for line #2. For Line #3, the Specialization Type and ArgFunctionType <br>







both are 'int'<i>, </i>hence we get no error for Line #3.<br><br></font></pre><pre><font face="arial, helvetica, sans-serif">If there is no prior instantiation, Line #2 will succeed while Line #3 will throw error.<br>






<br></font></pre><pre><font face="arial, helvetica, sans-serif">Do we deduce return type during function template instantiation along with template parameters?</font></pre><pre><font face="arial, helvetica, sans-serif">( Which i guess we should not but we are probably doing it as evident as the return type of second Specialization becomes 'int')</font></pre>






<pre><font face="arial, helvetica, sans-serif"><br></font></pre><pre><font face="arial, helvetica, sans-serif">How should we prevent deduction of return type for second Specialization? (I tried a lot but couldn't find a way).</font></pre>






<pre><font face="arial, helvetica, sans-serif">GCC 4.8.2 is also behaving same as clang as described in the bug. <br></font></pre><pre><font face="arial, helvetica, sans-serif">Richard, any comment/help ? This bug was filed by you :)<span><font color="#888888"><br>






</font></span></font></pre><span><font color="#888888"><pre><font face="arial, helvetica, sans-serif">
</font></pre><span><font color="#888888"><div><div><div><div><font face="arial, helvetica, sans-serif"><br>-- <br>With regards,<br>Suyog Sarda</font><span></span></div></div></div></div></font></span></font></span></div>




</blockquote></div><span></span></div></div></div></div></div></div></div><br clear="all"><br>-- <br>With regards,<br>Suyog Sarda<br>
</div>
</div></div></blockquote></div><br></div></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>With regards,<br>Suyog Sarda<br>
</div>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div><br><br clear="all"><br>-- <br>With regards,<br>Suyog Sarda<br>
</div>