Bug 49118

Summary: Endless operator-> chain causes infinite loop
Product: gcc Reporter: David Krauss <potswa>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: basil, jason
Priority: P3    
Version: 4.5.1   
Target Milestone: 4.7.0   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55581
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2011-05-23 10:58:00
Attachments: Patch fixes behavior but error message repeats twice.
replace crufty previous patch

Description David Krauss 2011-05-23 00:23:59 UTC
When the "drill-down" behavior is used to chain operator-> calls, a cycle in the chain causes an immediate error message, but an endless acyclic chain causes the compiler to hang, very slowly consuming memory.

Minimal case:

template< int n >
struct a { 
    a< n+1 > operator->() { return a< n+1 >(); }
};
 
int main() {
    a<0>()->x;
}

Suggested fix: If operator-> returns a template specialization, consider its instantiation to be nested. This existing error message and limit-mechanism would be appropriate:

error: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating ‘struct a<500>’
Comment 1 Paolo Carlini 2011-05-23 07:44:01 UTC
For the record, ICC (EDG that is) misbehaves the same way, at least the versions to which I have access. Maybe clang does something different?
Comment 2 Jonathan Wakely 2011-05-23 08:22:00 UTC
nope, same behaviour for clang 2.8
Comment 3 Richard Biener 2011-05-23 10:58:00 UTC
Confirmed at least.
Comment 4 David Krauss 2011-05-26 03:37:44 UTC
Created attachment 24359 [details]
Patch fixes behavior but error message repeats twice.

I implemented the suggested fix, but the resulting error message repeats the part about "template instantiation depth exceeds maximum" twice. The template backtrace appears after the error, not before as with a usual nesting problem. Is there something I'm obviously doing wrong here?

Here are the most relevant lines from the attached patch.

/* For diagnostic purposes, pretend that the chain is nested. */
if (CLASS_TYPE_P (chain_type) && CLASSTYPE_TEMPLATE_INFO (chain_type))
  push_tinst_level (chain_type);
Comment 5 David Krauss 2011-05-26 03:43:41 UTC
Created attachment 24360 [details]
replace crufty previous patch

See this patch instead. Previous unintentionally captured unrelated development.
Comment 6 Paolo Carlini 2011-05-26 09:41:10 UTC
Maybe Jason can give you some tips, better sending the patch to the mailing list for that, though, Bugzilla isn't meant for patches. CC Jason.
Comment 7 David Krauss 2011-05-26 11:05:12 UTC
Yes, I'll likely do that in a few days… just wanted to put the code in "safe holding," just in case.
Comment 8 Jason Merrill 2011-06-10 05:18:40 UTC
Author: jason
Date: Fri Jun 10 05:18:36 2011
New Revision: 174889

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=174889
Log:
	PR c++/49118
	* typeck2.c (build_x_arrow): Push fake template context
	to produce diagnostic on acyclic endless operator-> drill-down.
	* call.c (build_new_op): Change Boolean overload status
	value to a pointer to the overload function.
	* cp-tree.h: Likewise.
	* typeck.c: Likewise.
	* parser.c: Likewise.
	* decl2.c: Likewise.
	* pt.c: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/template/arrow1.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/call.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl2.c
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/cp/typeck2.c
    trunk/gcc/testsuite/ChangeLog
Comment 9 David Krauss 2011-06-10 05:25:08 UTC
Thanks!

On Jun 9, 2011, at 10:18 PM, jason at gcc dot gnu.org wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49118
Comment 10 Jason Merrill 2011-07-01 00:55:36 UTC
Fixed for 4.7.
Comment 11 Jakub Jelinek 2013-02-25 22:45:10 UTC
*** Bug 56449 has been marked as a duplicate of this bug. ***