[C++/58583] ICE instantiating NSDMIs
This patch fixes 58582, a set of ICEs that happen instantiating NSDMIs. There are a couple of causes, both fixed. 1) instantiating the template while parsing an NSDMI of the template itself. We see a DEFAULT_ARG in get_nsdmi. Fixed by jumping to the existing error handling for the non-template case. 2) recursive instantiation of the NSDMI itself. As we instantiate lazily, we end up running out of stack. Fixed by creating a temporary DEFAULT_ARG and then detecting it on a subsequent recursion. I did contemplate having this direct to the same error as above, but decided against it, because this really is an instantiation problem not a parsing problem. built & tested on x86_64-linux, ok? nathan 2015-06-05 Nathan Sidwell cp/ PR c++/58583 * init.c (get_nsdmi): Check for DEFAULT_ARG in template case and protect it from recursive instantiation. testsuite/ PR c++/58583 * g++.dg/cpp0x/nsdmi-template14.C: New test. Index: cp/init.c === --- cp/init.c (revision 224152) +++ cp/init.c (working copy) @@ -544,6 +544,7 @@ get_nsdmi (tree member, bool in_ctor) tree init; tree save_ccp = current_class_ptr; tree save_ccr = current_class_ref; + if (!in_ctor) { /* Use a PLACEHOLDER_EXPR when we don't have a 'this' parameter to @@ -551,22 +552,41 @@ get_nsdmi (tree member, bool in_ctor) current_class_ref = build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (member)); current_class_ptr = build_address (current_class_ref); } + if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member)) { - /* Do deferred instantiation of the NSDMI. */ - init = (tsubst_copy_and_build - (DECL_INITIAL (DECL_TI_TEMPLATE (member)), - DECL_TI_ARGS (member), - tf_warning_or_error, member, /*function_p=*/false, - /*integral_constant_expression_p=*/false)); + init = DECL_INITIAL (DECL_TI_TEMPLATE (member)); + if (TREE_CODE (init) == DEFAULT_ARG) + goto unparsed; - init = digest_nsdmi_init (member, init); + /* Check recursive instantiation. */ + if (TREE_CODE (DECL_INITIAL (member)) == DEFAULT_ARG) + { + error ("recursive instantiation of non-static data member " + "initializer for %qD", member); + init = error_mark_node; + } + else + { + DECL_INITIAL (member) = make_node (DEFAULT_ARG); + + /* Do deferred instantiation of the NSDMI. */ + init = (tsubst_copy_and_build + (init, DECL_TI_ARGS (member), + tf_warning_or_error, member, /*function_p=*/false, + /*integral_constant_expression_p=*/false)); + init = digest_nsdmi_init (member, init); + + if (TREE_CODE (DECL_INITIAL (member)) == DEFAULT_ARG) + DECL_INITIAL (member) = void_node; + } } else { init = DECL_INITIAL (member); if (init && TREE_CODE (init) == DEFAULT_ARG) { + unparsed: error ("constructor required before non-static data member " "for %qD has been parsed", member); DECL_INITIAL (member) = error_mark_node; Index: testsuite/g++.dg/cpp0x/nsdmi-template14.C === --- testsuite/g++.dg/cpp0x/nsdmi-template14.C (revision 0) +++ testsuite/g++.dg/cpp0x/nsdmi-template14.C (working copy) @@ -0,0 +1,23 @@ +// PR c++/58583 +// { dg-do compile { target c++11 } } + +template struct A // {dg-error "non-static data member initializer" } +{ + int i = (A<0>(), 0); // { dg-error "non-static data member initializer required before parsing" } { dg-error "synthesized method" } +}; + +template struct B +{ + B* p = new B; +}; + +B<1> x; // { dg-error "constructor required before non-static data member" } + +struct C +{ + template struct D + { +D* p = new D<0>; + }; +}; +
Re: [C++/58583] ICE instantiating NSDMIs
How about using a DECL_LANG_FLAG instead of creating a garbage DEFAULT_ARG? Jason
Re: [C++/58583] ICE instantiating NSDMIs
On 06/08/15 13:47, Jason Merrill wrote: How about using a DECL_LANG_FLAG instead of creating a garbage DEFAULT_ARG? good idea, I'll go look for an available one. nathan
Re: [C++/58583] ICE instantiating NSDMIs
On 06/08/15 13:47, Jason Merrill wrote: How about using a DECL_LANG_FLAG instead of creating a garbage DEFAULT_ARG? This patch uses DECL_LANG_FLAG_2 on the FIELD_DECL to mark that its NSDMI is being instantiated. I also discovered I'd flubbed the markup on the testcase, not sure why I didn't notice that in the test results. I've double checked this time, and all looks good. built & tested on x86_64-linux-gnu nathan 2015-06-09 Nathan Sidwell cp/ PR c++/58583 * cp-tree.h (DECL_INSTANTIATING_NSDMI_P): New. * init.c (get_nsdmi): Check for DEFAULT_ARG in template case and protect it from recursive instantiation. testsuite/ PR c++/58583 * g++.dg/cpp0x/nsdmi-template14.C: New test. Index: cp/cp-tree.h === --- cp/cp-tree.h (revision 224198) +++ cp/cp-tree.h (working copy) @@ -160,6 +160,7 @@ c-common.h, not after. LABEL_DECL_CONTINUE (in LABEL_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL) + DECL_INSTANTIATING_NSDMI_P (in a FIELD_DECL) 3: DECL_IN_AGGR_P. 4: DECL_C_BIT_FIELD (in a FIELD_DECL) DECL_ANON_UNION_VAR_P (in a VAR_DECL) @@ -3785,6 +3786,11 @@ more_aggr_init_expr_args_p (const aggr_i #define DECL_ARRAY_PARAMETER_P(NODE) \ DECL_LANG_FLAG_1 (PARM_DECL_CHECK (NODE)) +/* Nonzero for a FIELD_DECL who's NSMDI is currently being + instantiated. */ +#define DECL_INSTANTIATING_NSDMI_P(NODE) \ + DECL_LANG_FLAG_2 (FIELD_DECL_CHECK (NODE)) + /* Nonzero for FIELD_DECL node means that this field is a base class of the parent object, as opposed to a member field. */ #define DECL_FIELD_IS_BASE(NODE) \ Index: cp/init.c === --- cp/init.c (revision 224198) +++ cp/init.c (working copy) @@ -544,6 +544,7 @@ get_nsdmi (tree member, bool in_ctor) tree init; tree save_ccp = current_class_ptr; tree save_ccr = current_class_ref; + if (!in_ctor) { /* Use a PLACEHOLDER_EXPR when we don't have a 'this' parameter to @@ -551,22 +552,40 @@ get_nsdmi (tree member, bool in_ctor) current_class_ref = build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (member)); current_class_ptr = build_address (current_class_ref); } + if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member)) { - /* Do deferred instantiation of the NSDMI. */ - init = (tsubst_copy_and_build - (DECL_INITIAL (DECL_TI_TEMPLATE (member)), - DECL_TI_ARGS (member), - tf_warning_or_error, member, /*function_p=*/false, - /*integral_constant_expression_p=*/false)); + init = DECL_INITIAL (DECL_TI_TEMPLATE (member)); + if (TREE_CODE (init) == DEFAULT_ARG) + goto unparsed; - init = digest_nsdmi_init (member, init); + /* Check recursive instantiation. */ + if (DECL_INSTANTIATING_NSDMI_P (member)) + { + error ("recursive instantiation of non-static data member " + "initializer for %qD", member); + init = error_mark_node; + } + else + { + DECL_INSTANTIATING_NSDMI_P (member) = 1; + + /* Do deferred instantiation of the NSDMI. */ + init = (tsubst_copy_and_build + (init, DECL_TI_ARGS (member), + tf_warning_or_error, member, /*function_p=*/false, + /*integral_constant_expression_p=*/false)); + init = digest_nsdmi_init (member, init); + + DECL_INSTANTIATING_NSDMI_P (member) = 0; + } } else { init = DECL_INITIAL (member); if (init && TREE_CODE (init) == DEFAULT_ARG) { + unparsed: error ("constructor required before non-static data member " "for %qD has been parsed", member); DECL_INITIAL (member) = error_mark_node; Index: testsuite/g++.dg/cpp0x/nsdmi-template14.C === --- testsuite/g++.dg/cpp0x/nsdmi-template14.C (revision 0) +++ testsuite/g++.dg/cpp0x/nsdmi-template14.C (working copy) @@ -0,0 +1,22 @@ +// PR c++/58583 +// { dg-do compile { target c++11 } } + +template struct A // { dg-error "has been parsed" } +{ + int i = (A<0>(), 0); // { dg-error "has been parsed" } +}; + +template struct B +{ + B* p = new B; +}; + +B<1> x; // { dg-error "recursive instantiation of non-static data" } + +struct C +{ + template struct D + { +D* p = new D<0>; + }; +};
Re: [C++/58583] ICE instantiating NSDMIs
Ping? https://gcc.gnu.org/ml/gcc-patches/2015-06/msg00674.html #On 06/09/15 09:46, Nathan Sidwell wrote: On 06/08/15 13:47, Jason Merrill wrote: How about using a DECL_LANG_FLAG instead of creating a garbage DEFAULT_ARG? This patch uses DECL_LANG_FLAG_2 on the FIELD_DECL to mark that its NSDMI is being instantiated. I also discovered I'd flubbed the markup on the testcase, not sure why I didn't notice that in the test results. I've double checked this time, and all looks good. built & tested on x86_64-linux-gnu nathan
Re: [C++/58583] ICE instantiating NSDMIs
OK, thanks. Jason
Re: [C++/58583] ICE instantiating NSDMIs
Nathan Sidwell writes: > PR c++/58583 > * g++.dg/cpp0x/nsdmi-template14.C: New test. spawn -ignore SIGHUP /usr/local/gcc/gcc-20150616/Build/gcc/testsuite/g++2/../../xg++ -B/usr/local/gcc/gcc-20150616/Build/gcc/testsuite/g++2/../../ /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C -fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++ -I/usr/local/gcc/gcc-20150616/Build/ia64-suse-linux/libstdc++-v3/include/ia64-suse-linux -I/usr/local/gcc/gcc-20150616/Build/ia64-suse-linux/libstdc++-v3/include -I/usr/local/gcc/gcc-20150616/libstdc++-v3/libsupc++ -I/usr/local/gcc/gcc-20150616/libstdc++-v3/include/backward -I/usr/local/gcc/gcc-20150616/libstdc++-v3/testsuite/util -fmessage-length=0 -std=c++11 -pedantic-errors -Wno-long-long -S -o nsdmi-template14.s. /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C:14:6: error: recursive instantiation of non-static data member initializer for 'B<1>::p'. compiler exited with status 1 output is: /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C:14:6: error: recursive instantiation of non-static data member initializer for 'B<1>::p'. FAIL: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 4) FAIL: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 6) PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 14) PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for excess errors) Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: [C++/58583] ICE instantiating NSDMIs
On 06/16/15 03:47, Andreas Schwab wrote: Nathan Sidwell writes: PR c++/58583 * g++.dg/cpp0x/nsdmi-template14.C: New test. spawn -ignore SIGHUP /usr/local/gcc/gcc-20150616/Build/gcc/testsuite/g++2/../../xg++ -B/usr/local/gcc/gcc-20150616/Build/gcc/testsuite/g++2/../../ /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C -fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++ -I/usr/local/gcc/gcc-20150616/Build/ia64-suse-linux/libstdc++-v3/include/ia64-suse-linux -I/usr/local/gcc/gcc-20150616/Build/ia64-suse-linux/libstdc++-v3/include -I/usr/local/gcc/gcc-20150616/libstdc++-v3/libsupc++ -I/usr/local/gcc/gcc-20150616/libstdc++-v3/include/backward -I/usr/local/gcc/gcc-20150616/libstdc++-v3/testsuite/util -fmessage-length=0 -std=c++11 -pedantic-errors -Wno-long-long -S -o nsdmi-template14.s. /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C:14:6: error: recursive instantiation of non-static data member initializer for 'B<1>::p'. compiler exited with status 1 output is: /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C:14:6: error: recursive instantiation of non-static data member initializer for 'B<1>::p'. FAIL: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 4) FAIL: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 6) PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 14) PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for excess errors) strange. This is what I got on x86_64-linux (fedora21, FWIW) spawn -ignore SIGHUP /home/nathan/egcs/head/x86_64-linux/gcc/testsuite/g++3/../../xg++ -B/home/nathan/egcs/head/x86_64-linux/gcc/testsuite/g++3/../../ /home/nathan/egcs/head/src/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C -fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++ -I/home/nathan/egcs/head/x86_64-linux/x86_64-unknown-linux-gnu/libstdc++-v3/include/x86_64-unknown-linux-gnu -I/home/nathan/egcs/head/x86_64-linux/x86_64-unknown-linux-gnu/libstdc++-v3/include -I/home/nathan/egcs/head/src/libstdc++-v3/libsupc++ -I/home/nathan/egcs/head/src/libstdc++-v3/include/backward -I/home/nathan/egcs/head/src/libstdc++-v3/testsuite/util -fmessage-length=0 -std=c++11 -pedantic-errors -Wno-long-long -S -o nsdmi-template14.s PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 4) PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 6) PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 14) PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for excess errors) The missing errors are here: template struct A // { dg-error "has been parsed" } { int i = (A<0>(), 0); // { dg-error "has been parsed" } }; It's almost as if the initializer isn't being parsed at all. (prior to my patch, it should end up ICEing instantiating DEFARG) nathan
Re: [C++/58583] ICE instantiating NSDMIs
On Tue, Jun 16, 2015 at 05:44:49PM +0100, Nathan Sidwell wrote: > On 06/16/15 03:47, Andreas Schwab wrote: > > Nathan Sidwell writes: > > > >>PR c++/58583 > >>* g++.dg/cpp0x/nsdmi-template14.C: New test. > > > > spawn -ignore SIGHUP > > /usr/local/gcc/gcc-20150616/Build/gcc/testsuite/g++2/../../xg++ > > -B/usr/local/gcc/gcc-20150616/Build/gcc/testsuite/g++2/../../ > > /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C > > -fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++ > > -I/usr/local/gcc/gcc-20150616/Build/ia64-suse-linux/libstdc++-v3/include/ia64-suse-linux > > -I/usr/local/gcc/gcc-20150616/Build/ia64-suse-linux/libstdc++-v3/include > > -I/usr/local/gcc/gcc-20150616/libstdc++-v3/libsupc++ > > -I/usr/local/gcc/gcc-20150616/libstdc++-v3/include/backward > > -I/usr/local/gcc/gcc-20150616/libstdc++-v3/testsuite/util > > -fmessage-length=0 -std=c++11 -pedantic-errors -Wno-long-long -S -o > > nsdmi-template14.s. > > /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C:14:6: > > error: recursive instantiation of non-static data member initializer for > > 'B<1>::p'. > > compiler exited with status 1 > > output is: > > /usr/local/gcc/gcc-20150616/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C:14:6: > > error: recursive instantiation of non-static data member initializer for > > 'B<1>::p'. > > > > FAIL: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 4) > > FAIL: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 6) > > PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line > > 14) > > PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for excess errors) > > strange. This is what I got on x86_64-linux (fedora21, FWIW) > > > spawn -ignore SIGHUP > /home/nathan/egcs/head/x86_64-linux/gcc/testsuite/g++3/../../xg++ > -B/home/nathan/egcs/head/x86_64-linux/gcc/testsuite/g++3/../../ > /home/nathan/egcs/head/src/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C > -fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++ > -I/home/nathan/egcs/head/x86_64-linux/x86_64-unknown-linux-gnu/libstdc++-v3/include/x86_64-unknown-linux-gnu > > -I/home/nathan/egcs/head/x86_64-linux/x86_64-unknown-linux-gnu/libstdc++-v3/include > > -I/home/nathan/egcs/head/src/libstdc++-v3/libsupc++ > -I/home/nathan/egcs/head/src/libstdc++-v3/include/backward > -I/home/nathan/egcs/head/src/libstdc++-v3/testsuite/util -fmessage-length=0 > -std=c++11 -pedantic-errors -Wno-long-long -S -o nsdmi-template14.s > > PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 4) > PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 6) > PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 14) > PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for excess errors) > > The missing errors are here: > > template struct A // { dg-error "has been parsed" } > { >int i = (A<0>(), 0); // { dg-error "has been parsed" } > }; > > It's almost as if the initializer isn't being parsed at all. (prior to my > patch, > it should end up ICEing instantiating DEFARG) I'm seeing the same issues on aarch64-none-elf and aarch64_be-none-elf in one of my testing environments, but, interestingly, not on aarch64-none-linux-gnu or in my other aarch64-none-elf testing environment (!!). I've pasted both log extracts below (after stripping the file paths for each build environment, so you can see just how similar the invocations are!). The PASSing environment does use a slightly more modern toolchain for building the cross-toolchain (PASSing environment uses 4.9.2, FAILing environment uses 4.8.1), so that could be a source of the difference? Thanks, James --- Failing: spawn .../aarch64-none-elf/obj/gcc2/gcc/testsuite/g++14/../../xg++ -B.../aarch64-none-elf/obj/gcc2/gcc/testsuite/g++14/../../ .../gcc/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C -fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++ -I.../aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include/aarch64-none-elf -I.../aarch64-none-elf/obj/gcc2/aarch64-none-elf/libstdc++-v3/include -I.../gcc/libstdc++-v3/libsupc++ -I.../gcc/libstdc++-v3/include/backward -I.../gcc/libstdc++-v3/testsuite/util -fmessage-length=0 -std=c++11 -pedantic-errors -Wno-long-long -S -mcmodel=small -o nsdmi-template14.s .../gcc/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C:14:6: error: recursive instantiation of non-static data member initializer for 'B<1>::p' compiler exited with status 1 output is: .../gcc/gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C:14:6: error: recursive instantiation of non-static data member initializer for 'B<1>::p' FAIL: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 4) FAIL: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 6) PASS: g++.dg/cpp0x/nsdmi-template14.C -std=c++11 (test for errors, line 14) PASS: g++.dg/cpp0x/ns
Re: [C++/58583] ICE instantiating NSDMIs
On 06/17/15 04:57, James Greenhalgh wrote: I'm seeing the same issues on aarch64-none-elf and aarch64_be-none-elf in one of my testing environments, but, interestingly, not on aarch64-none-linux-gnu or in my other aarch64-none-elf testing environment (!!). ugh. What is the behavior on the testcase with the patch reverted? Is it the same on both elf systems? (I'm expecting an ICE in one of the tsubst variants when it meets a DEFAULT_ARG) I've pasted both log extracts below (after stripping the file paths for each build environment, so you can see just how similar the invocations are!). The PASSing environment does use a slightly more modern toolchain for building the cross-toolchain (PASSing environment uses 4.9.2, FAILing environment uses 4.8.1), so that could be a source of the difference? ew. nathan
Re: [C++/58583] ICE instantiating NSDMIs
This also fails on powerpc. Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: [C++/58583] ICE instantiating NSDMIs
On 06/20/15 02:09, Andreas Schwab wrote: This also fails on powerpc. what is the build compiler? James provided a clue that 4.9.2 is ok but 4.8.1 is bad. nathan
Re: [C++/58583] ICE instantiating NSDMIs
On 06/21/15 19:00, Nathan Sidwell wrote: On 06/20/15 02:09, Andreas Schwab wrote: This also fails on powerpc. what is the build compiler? James provided a clue that 4.9.2 is ok but 4.8.1 is bad. FWIW, I can't reproduce the failure with using a stock 4.8.2 build compiler for an x86_64-linux target. nathan
Re: [C++/58583] ICE instantiating NSDMIs
Nathan Sidwell writes: > On 06/20/15 02:09, Andreas Schwab wrote: >> This also fails on powerpc. > > what is the build compiler? It is a bootstrapped build, so the build compiler should not matter. Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: [C++/58583] ICE instantiating NSDMIs
On 06/22/15 03:37, Andreas Schwab wrote: Nathan Sidwell writes: On 06/20/15 02:09, Andreas Schwab wrote: This also fails on powerpc. what is the build compiler? It is a bootstrapped build, so the build compiler should not matter. ok, thanks. I've just built me a powerpc-linux targeting compiler from an x86_64-linux host. That is showing the expected diagnostic, so I'm still unable to reproduce the failure. nsidwell@build6-lucid-cs:19>install/bin/powerpc-linux-gnu-g++ -std=c++11 -c nsdmi-template14.C nsdmi-template14.C:6:20: error: constructor required before non-static data member for 'A<0>::i' has been parsed int i = (A<0>(), 0); // { dg-error "has been parsed" } ^ nsdmi-template14.C: In constructor 'constexpr A<0>::A()': nsdmi-template14.C:4:22: error: constructor required before non-static data member for 'A<0>::i' has been parsed template struct A // { dg-error "has been parsed" } ^ nsdmi-template14.C: At global scope: nsdmi-template14.C:6:20: note: synthesized method 'constexpr A<0>::A()' first required here int i = (A<0>(), 0); // { dg-error "has been parsed" } ^ nsdmi-template14.C:14:6: error: recursive instantiation of non-static data member initializer for 'B<1>::p' B<1> x; // { dg-error "recursive instantiation of non-static data" } ^ nathan