The following code causes an ICE when compiled with the current GCC trunk on x86_64-linux-gnu at -O1 and above in both 32-bit and 64-bit modes. This is a regression from 5.3.x. $ g++-trunk -v Using built-in specs. COLLECT_GCC=g++-trunk COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/6.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/usr/local/gcc-trunk --disable-bootstrap Thread model: posix gcc version 6.0.0 20160321 (experimental) [trunk revision 234361] (GCC) $ $ g++-trunk -O0 -std=c++11 -c small.cpp $ g++-5.3 -O1 -std=c++11 -c small.cpp $ $ g++-trunk -O1 -std=c++11 -c small.cpp small.cpp: In instantiation of ‘constexpr int fn(T) [with T = Z]’: small.cpp:15:18: required from here small.cpp:13:1: internal compiler error: in adjust_temp_type, at cp/constexpr.c:1078 } ^ 0x84505a adjust_temp_type ../../gcc-source-trunk/gcc/cp/constexpr.c:1078 0x84bbfb cxx_bind_parameters_in_call ../../gcc-source-trunk/gcc/cp/constexpr.c:1128 0x84bbfb cxx_eval_call_expression ../../gcc-source-trunk/gcc/cp/constexpr.c:1312 0x84d57b cxx_eval_constant_expression ../../gcc-source-trunk/gcc/cp/constexpr.c:3381 0x853a19 cxx_eval_outermost_constant_expr ../../gcc-source-trunk/gcc/cp/constexpr.c:3946 0x85671c maybe_constant_value_1 ../../gcc-source-trunk/gcc/cp/constexpr.c:4134 0x85671c maybe_constant_value(tree_node*, tree_node*) ../../gcc-source-trunk/gcc/cp/constexpr.c:4155 0x830a9f cp_fold ../../gcc-source-trunk/gcc/cp/cp-gimplify.c:2188 0x830816 cp_fold_rvalue ../../gcc-source-trunk/gcc/cp/cp-gimplify.c:1887 0x830816 cp_fold ../../gcc-source-trunk/gcc/cp/cp-gimplify.c:2072 0x83135e cp_fold_r ../../gcc-source-trunk/gcc/cp/cp-gimplify.c:944 0x1009b64 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*)) ../../gcc-source-trunk/gcc/tree.c:11531 0x65701f finish_function(int) ../../gcc-source-trunk/gcc/cp/decl.c:14688 0x67b622 instantiate_decl(tree_node*, int, bool) ../../gcc-source-trunk/gcc/cp/pt.c:22029 0x7098ea mark_used(tree_node*, int) ../../gcc-source-trunk/gcc/cp/decl2.c:5279 0x612481 build_over_call ../../gcc-source-trunk/gcc/cp/call.c:7706 0x621b3f build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, int) ../../gcc-source-trunk/gcc/cp/call.c:4152 0x7bc4a1 finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int) ../../gcc-source-trunk/gcc/cp/semantics.c:2461 0x736799 cp_parser_postfix_expression ../../gcc-source-trunk/gcc/cp/parser.c:6904 0x73fb0c cp_parser_unary_expression ../../gcc-source-trunk/gcc/cp/parser.c:7988 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. $ --------------------------------- struct Z { Z () = default; Z (Z const &) = default; constexpr Z (Z &&) {} }; template < typename T > constexpr int fn (T v) { return fn (v); } auto t = fn (Z ());
Started with r230365.
fn does not have to be a function template to trigger the ICE: struct Z { Z () = default; Z (Z const &) = default; constexpr Z (Z &&) {} }; constexpr int fn (Z v) { return fn (v); } auto t = fn (Z ());
Problem ultimately seems to be that we're calling cp_fold_function on fn() before we call cp_genericize on it which is responsible for fixing up fn()'s parameter 'v' which is passed by invisible reference. The TREE_TYPE of v is a RECORD_TYPE before the fix-up, but after the fix-up it's a REFERENCE_TYPE to a RECORD_TYPE. The 1st argument to the recursive call to fn() however is a REFERENCE_TYPE. So in cxx_eval_call_expression (called indirectly from cp_fold_function) we see that fn() expects a RECORD_TYPE (because its parms haven't been fixed up yet) but the call passes a REFERENCE_TYPE. This type confusion triggers the ICE.
Author: jason Date: Wed Mar 23 18:23:04 2016 New Revision: 234434 URL: https://gcc.gnu.org/viewcvs?rev=234434&root=gcc&view=rev Log: PR c++/70344 * constexpr.c (cxx_eval_call_expression): Catch invalid recursion. Added: trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c
Fixed.
Author: jason Date: Sat Apr 2 01:35:45 2016 New Revision: 234695 URL: https://gcc.gnu.org/viewcvs?rev=234695&root=gcc&view=rev Log: PR c++/70449 PR c++/70344 * pt.c (instantiate_decl): A function isn't fully defined if DECL_INITIAL is error_mark_node. * constexpr.c (cxx_eval_call_expression): Likewise. Added: trunk/gcc/testsuite/g++.dg/cpp1y/constexpr-recursion1.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c trunk/gcc/cp/pt.c
The same ICE is still triggered with the current GCC trunk: $ g++-trunk -v Using built-in specs. COLLECT_GCC=g++-trunk COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/usr/local/gcc-trunk --disable-bootstrap Thread model: posix gcc version 7.0.0 20160426 (experimental) [trunk revision 235433] (GCC) $ $ g++-trunk -O1 -c pr70344.cpp pr70344.cpp: In instantiation of ‘constexpr int fn(T) [with T = Z]’: pr70344.cpp:15:18: required from here pr70344.cpp:13:1: internal compiler error: in adjust_temp_type, at cp/constexpr.c:1136 } ^ 0x89197a adjust_temp_type ../../gcc-source-trunk/gcc/cp/constexpr.c:1136 0x898797 cxx_bind_parameters_in_call ../../gcc-source-trunk/gcc/cp/constexpr.c:1210 0x898797 cxx_eval_call_expression ../../gcc-source-trunk/gcc/cp/constexpr.c:1397 0x89aa5d cxx_eval_constant_expression ../../gcc-source-trunk/gcc/cp/constexpr.c:3558 0x8a10e9 cxx_eval_outermost_constant_expr ../../gcc-source-trunk/gcc/cp/constexpr.c:4136 0x8a3f78 maybe_constant_value_1 ../../gcc-source-trunk/gcc/cp/constexpr.c:4330 0x8a3f78 maybe_constant_value(tree_node*, tree_node*) ../../gcc-source-trunk/gcc/cp/constexpr.c:4354 0x87fad3 cp_fold ../../gcc-source-trunk/gcc/cp/cp-gimplify.c:2205 0x87f398 cp_fold_rvalue ../../gcc-source-trunk/gcc/cp/cp-gimplify.c:1894 0x87f398 cp_fold ../../gcc-source-trunk/gcc/cp/cp-gimplify.c:2083 0x88037e cp_fold_r ../../gcc-source-trunk/gcc/cp/cp-gimplify.c:940 0x1059734 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*)) ../../gcc-source-trunk/gcc/tree.c:11531 0x6a2587 finish_function(int) ../../gcc-source-trunk/gcc/cp/decl.c:14712 0x70cf2a instantiate_decl(tree_node*, int, bool) ../../gcc-source-trunk/gcc/cp/pt.c:22035 0x75492b mark_used(tree_node*, int) ../../gcc-source-trunk/gcc/cp/decl2.c:5273 0x65d521 build_over_call ../../gcc-source-trunk/gcc/cp/call.c:7724 0x66ccff build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, int) ../../gcc-source-trunk/gcc/cp/call.c:4169 0x808bf1 finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int) ../../gcc-source-trunk/gcc/cp/semantics.c:2461 0x782a99 cp_parser_postfix_expression ../../gcc-source-trunk/gcc/cp/parser.c:6904 0x78bdec cp_parser_unary_expression ../../gcc-source-trunk/gcc/cp/parser.c:7988 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. $
Indeed, r234434 fixed the ICE and r234695 started to ICE again on the #c0 testcase with -O1 -std=c++11.
Author: jason Date: Tue May 24 03:34:55 2016 New Revision: 236625 URL: https://gcc.gnu.org/viewcvs?rev=236625&root=gcc&view=rev Log: PR c++/70344 - ICE with recursive constexpr * constexpr.c (cxx_eval_call_expression): Check for fun == current_function_decl again. Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion2.C
Author: jason Date: Tue May 24 03:37:10 2016 New Revision: 236626 URL: https://gcc.gnu.org/viewcvs?rev=236626&root=gcc&view=rev Log: PR c++/70344 - ICE with recursive constexpr * constexpr.c (cxx_eval_call_expression): Check for fun == current_function_decl again. Modified: branches/gcc-6-branch/gcc/cp/ChangeLog branches/gcc-6-branch/gcc/cp/constexpr.c branches/gcc-6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion2.C