Bug 69222 - [5 Regression] C++14 template code working in GCC 5.1 stops working in 5.2 and 5.3
Summary: [5 Regression] C++14 template code working in GCC 5.1 stops working in 5.2 an...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 5.2.0
: P3 normal
Target Milestone: 5.4
Assignee: Jonathan Wakely
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2016-01-11 02:48 UTC by Yongwei Wu
Modified: 2016-01-12 14:59 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 5.1.0, 6.0
Known to fail: 5.2.0, 5.3.0
Last reconfirmed: 2016-01-11 00:00:00


Attachments
Test C++ file (649 bytes, text/plain)
2016-01-11 02:48 UTC, Yongwei Wu
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Yongwei Wu 2016-01-11 02:48:51 UTC
Created attachment 37299 [details]
Test C++ file

I have an implementation of Y Combinator in C++, which works in GCC 4.9 to 5.1 as well as Clang 3.5 (in C++14 mode). It stops working in GCC 5.2 and 5.3, so I think it is regression. I think GCC is being too eager in template instantiation. As I also tried using the GCC 5.1 C++ header files with GCC 5.2 and got the same errors, I guess it is a C++ front end problem.

The test program is supposed to apply the Y combinator to a non-recursive function almost_fac to get a factorial function. It should compile well and output two lines of "120", but now it fails the compilation at the "fix_curry(almost_fac)" line.

I tested on Windows and OS X. The Windows error output is:

In file included from test_gcc.cpp:1:0:
C:/mingw64/x86_64-w64-mingw32/include/c++/functional: In substitution of 'template<class _Functor, class> std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = std::function<std::function<int(int)>(self_ref_func<std::function<int(int)> >)>; <template-parameter-1-2> = <missing>]':
C:/mingw64/x86_64-w64-mingw32/include/c++/functional:1981:45:   recursively required by substitution of 'template<class _Functor, class> std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = std::function<std::function<int(int)>(self_ref_func<std::function<int(int)> >)>; <template-parameter-1-2> = <missing>]'
C:/mingw64/x86_64-w64-mingw32/include/c++/functional:1981:45:   required by substitution of 'template<class _Functor, class> std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = std::function<std::function<int(int)>(self_ref_func<std::function<int(int)> >)>; <template-parameter-1-2> = <missing>]'
test_gcc.cpp:47:51:   required from 'fix_curry(std::function<std::function<_Rs(_Tp)>(std::function<_Rs(_Tp)>)>)::<lambda(fn_self_ref)>::<lambda(_Tp&&)> [with _Rs = int; _Tp = int]'
test_gcc.cpp:45:34:   required from 'struct fix_curry(std::function<std::function<_Rs(_Tp)>(std::function<_Rs(_Tp)>)>)::<lambda(fn_self_ref)> [with _Rs = int; _Tp = int; fn_self_ref = self_ref_func<std::function<int(int)> >]::<lambda(int&&)>'
test_gcc.cpp:45:21:   required from 'fix_curry(std::function<std::function<_Rs(_Tp)>(std::function<_Rs(_Tp)>)>)::<lambda(fn_self_ref)> [with _Rs = int; _Tp = int; fn_self_ref = self_ref_func<std::function<int(int)> >]'
test_gcc.cpp:43:10:   required from 'struct fix_curry(std::function<std::function<_Rs(_Tp)>(std::function<_Rs(_Tp)>)>) [with _Rs = int; _Tp = int]::<lambda(fn_self_ref)>'
test_gcc.cpp:50:5:   required from 'std::function<_Rs(_Tp)> fix_curry(std::function<std::function<_Rs(_Tp)>(std::function<_Rs(_Tp)>)>) [with _Rs = int; _Tp = int]'
test_gcc.cpp:69:43:   required from here
C:/mingw64/x86_64-w64-mingw32/include/c++/functional:1981:69: fatal error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
  using _Invoke = decltype(__callable_functor(std::declval<_Functor&>())
                                                                     ^
compilation terminated.
Comment 1 Jonathan Wakely 2016-01-11 09:57:05 UTC
This is PR 69005 which I still have a pending patch for, in addition to Jason's front-end change.
Comment 2 Jonathan Wakely 2016-01-11 17:13:10 UTC
Not a 6 regression, it was already fixed on trunk for PR 69005.
Comment 3 Jonathan Wakely 2016-01-12 14:55:05 UTC
Author: redi
Date: Tue Jan 12 14:54:33 2016
New Revision: 232273

URL: https://gcc.gnu.org/viewcvs?rev=232273&root=gcc&view=rev
Log:
Prevent recursive instantiation in std::function

	PR libstdc++/69005
	PR libstdc++/69222
	* include/std/functional (function::_Invoke): Remove, use result_of.
	(function::_Callable): Replace alias template with class template
	and use partial specialization instead of _NotSelf alias template.
	(function(_Functor)): Add "not self" constraint so that _Callable is
	not used while type is incomplete.
	* testsuite/20_util/function/69222.cc: New.

Added:
    trunk/libstdc++-v3/testsuite/20_util/function/69222.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/functional
Comment 4 Jonathan Wakely 2016-01-12 14:55:33 UTC
Author: redi
Date: Tue Jan 12 14:55:00 2016
New Revision: 232274

URL: https://gcc.gnu.org/viewcvs?rev=232274&root=gcc&view=rev
Log:
Prevent recursive instantiation in std::function

	PR libstdc++/69005
	PR libstdc++/69222
	* include/std/functional (function::_Invoke): Remove, use result_of.
	(function::_Callable): Replace alias template with class template
	and use partial specialization instead of _NotSelf alias template.
	(function(_Functor)): Add "not self" constraint so that _Callable is
	not used while type is incomplete.
	* testsuite/20_util/function/69222.cc: New.

Added:
    branches/gcc-5-branch/libstdc++-v3/testsuite/20_util/function/69222.cc
Modified:
    branches/gcc-5-branch/libstdc++-v3/ChangeLog
    branches/gcc-5-branch/libstdc++-v3/include/std/functional
Comment 5 Jonathan Wakely 2016-01-12 14:59:34 UTC
Fixed for 5.4