<div dir="ltr">On Tue, Oct 22, 2013 at 2:03 PM, Karen Shaeffer <span dir="ltr"><<a href="mailto:shaeffer@neuralscape.com" target="_blank">shaeffer@neuralscape.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<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 class="im">On Tue, Oct 22, 2013 at 12:14:25PM -0700, Richard Smith wrote:<br>

> On Tue, Oct 22, 2013 at 2:45 AM, Rahul Jain <<a href="mailto:1989.rahuljain@gmail.com">1989.rahuljain@gmail.com</a>>wrote:<br>
><br>
> ><br>
> > Hi all,<br>
> ><br>
> > clang version 3.4 (192772)<br>
> ><br>
> > This is with respect to the following gcc testsuite TC:<br>
> ><br>
> > template< int n ><br>
> > struct a {<br>
> >     a< n+1 > operator->()<br>
> >         {<br>
> >         return a< n+1 >();<br>
> >         }<br>
> > };<br>
> ><br>
> > int main() {<br>
> >     a<0>()->x;<br>
> > }<br>
> ><br>
> ><br>
> > This TC goes into an infinite loop when compiled. Ideally it should throw<br>
> > the error<br>
> > recursive template instantiation exceeded maximum depth of 256.<br>
> ><br>
><br>
> That's not the right behavior; there's no recursive template instantiation<br>
> here. Each operator-> is instantiated from within the context of 'main',<br>
> not from within some other instantiation.<br>
><br>
> If we want to limit this, we should put a limit on the number of times we<br>
> go around the loop looking for an overloaded operator-><br>
> in Sema::ActOnStartCXXMemberReference. However, I've seen people use this<br>
> in practice in template metaprogramming to get around the recursive<br>
> template instantiation depth, so this might break existing code.<br>
<br>
</div>Hi Richard,<br>
<br>
Just checked, and g++-4.7.2 doesn't give a 'recusive template instantiation' error.<br>
The error is:<br>
<br>
error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) instantiating ‘a<(n + 1)> a<n>::operator->() [with int n = 900]’<br></blockquote><div><br></div><div>
This is their recursive template instantiation error. I'm not sure why they chose to diagnose this problem in that way; there is no recursive instantiation here. The loop is in [over.ref](13.5.6)p1:</div><div><br></div>
<div>"An expression x->m is interpreted as (x.operator->())->m for a class object x of type T if T::operator->() exists and if the operator is selected as the best match function by the overload resolution mechanism."</div>
<div><br></div><div>This rule gets applied repeatedly, outside of any template instantiation.</div><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">
In the standard at [temp.inst]<br></blockquote><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">
<br>
<14.7.1 note d><br>
There is an implementation-defined quantity that specifies the limit on the total depth<br>
of recursive instantiations, which could involve more than one template. The result of an<br>
infinite recursion in instantiation is undefined.<br></blockquote><div><br></div><div>This is not what's happening in this case. Templates are mainly relevant to this problem because they make it much more likely to happen (although, since we already catch operator-> cycles, templates are the only way we can have a genuinely infinite sequence of operator-> calls). If we had generated code that looked like this:</div>
<div><br></div><div>struct T { int n; };</div><div>struct A0 { T *operator->(); };</div><div>struct A1 { A0 operator->(); };</div><div>struct A2 { A1 operator->(); };</div><div>// ...</div><div><br></div><div>A1000 a;</div>
<div>int k = a->n;</div><div><br></div><div>... we'd hit into exactly the same resource limitations as with the templated code, and the same limit should presumably apply here, whatever it is. (GCC strangely accepts this code while rejecting the corresponding templated code.)</div>
</div></div></div>