[cfe-dev] Endless operator-> chain causing infinite loop

Karen Shaeffer shaeffer at neuralscape.com
Tue Oct 22 14:03:34 PDT 2013


On Tue, Oct 22, 2013 at 12:14:25PM -0700, Richard Smith wrote:
> On Tue, Oct 22, 2013 at 2:45 AM, Rahul Jain <1989.rahuljain at gmail.com>wrote:
> 
> >
> > Hi all,
> >
> > clang version 3.4 (192772)
> >
> > This is with respect to the following gcc testsuite TC:
> >
> > template< int n >
> > struct a {
> >     a< n+1 > operator->()
> >         {
> >         return a< n+1 >();
> >         }
> > };
> >
> > int main() {
> >     a<0>()->x;
> > }
> >
> >
> > This TC goes into an infinite loop when compiled. Ideally it should throw
> > the error
> > recursive template instantiation exceeded maximum depth of 256.
> >
> 
> That's not the right behavior; there's no recursive template instantiation
> here. Each operator-> is instantiated from within the context of 'main',
> not from within some other instantiation.
> 
> If we want to limit this, we should put a limit on the number of times we
> go around the loop looking for an overloaded operator->
> in Sema::ActOnStartCXXMemberReference. However, I've seen people use this
> in practice in template metaprogramming to get around the recursive
> template instantiation depth, so this might break existing code.

Hi Richard,

Just checked, and g++-4.7.2 doesn't give a 'recusive template instantiation' error.
The error is:

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]’

So, g++ agrees with you. They are just limiting the depth of template instantiation, without
relying on the standard definition of recursive template instantiation. If they did not emit
this error, then the compiler would eventually run out of resources and crash. No compiler
can compile that code as written.

In the standard at [temp.inst]

<14.7.1 note d>
There is an implementation-defined quantity that specifies the limit on the total depth
of recursive instantiations, which could involve more than one template. The result of an
infinite recursion in instantiation is undefined.

[Example:
      template<class T> class X {
          X<T>* p;	// OK
          X<T*> a;	// implicit generation of X<T> requires
                        // the implicit instantiation of X<T*> which requires
                        // the implicit instantiation of X<T**> which ...
      };
— end example ]
</14.7.1 note d>

enjoy,
Karen
-- 
Karen Shaeffer                 Be aware: If you see an obstacle in your path,
Neuralscape Services           that obstacle is your path.        Zen proverb



More information about the cfe-dev mailing list