The following code causes an ICE when compiled with the current GCC trunk at -O1 and above on x86_64-linux-gnu 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 20160410 (experimental) [trunk revision 234869] (GCC) $ $ g++-trunk -O0 -c small.cpp small.cpp:30:12: error: conflicting declaration ‘const B D::e’ const B D::e = { 0, (fp) &E::foo }; ^ small.cpp:20:12: note: previous declaration as ‘B D::e’ static B e; ^ small.cpp:30:12: error: declaration of ‘B D::e’ outside of class is not definition [-fpermissive] const B D::e = { 0, (fp) &E::foo }; ^ $ $ g++-5.3 -O1 -c small.cpp small.cpp:30:12: error: conflicting declaration ‘const B D::e’ const B D::e = { 0, (fp) &E::foo }; ^ small.cpp:20:12: note: previous declaration as ‘B D::e’ static B e; ^ small.cpp:30:12: error: declaration of ‘B D::e’ outside of class is not definition [-fpermissive] const B D::e = { 0, (fp) &E::foo }; ^ $ $ g++-trunk -O1 -c small.cpp small.cpp:30:12: error: conflicting declaration ‘const B D::e’ const B D::e = { 0, (fp) &E::foo }; ^ small.cpp:20:12: note: previous declaration as ‘B D::e’ static B e; ^ small.cpp:30:12: error: declaration of ‘B D::e’ outside of class is not definition [-fpermissive] const B D::e = { 0, (fp) &E::foo }; ^ cc1plus: internal compiler error: in record_reference, at cgraphbuild.c:64 0x95ef53 record_reference ../../gcc-source-trunk/gcc/cgraphbuild.c:64 0x100fec4 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 0x1010474 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:11848 0x1010474 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:11848 0x96008a record_references_in_initializer(tree_node*, bool) ../../gcc-source-trunk/gcc/cgraphbuild.c:404 0x1051957 varpool_node::analyze() ../../gcc-source-trunk/gcc/varpool.c:526 0x966359 analyze_functions ../../gcc-source-trunk/gcc/cgraphunit.c:1133 0x966f98 symbol_table::finalize_compilation_unit() ../../gcc-source-trunk/gcc/cgraphunit.c:2542 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. $ ------------------------------------------ class A; typedef void (A::*fp) (void); struct B { int n; fp f; }; struct C { const C *c; const B b; }; class D { public: static B e; static C m; }; class E : public D { public: void foo (); }; // OK: B D::e = { 0, (fp) &E::foo }; const B D::e = { 0, (fp) &E::foo }; C D::m = { &D::m, E::e };
Started with my r232278 aka PR68511 and PR69213 fix.
It is unfortunate that due to the Cilk+ bug it is hard to bisect this properly. Anyway, looking at what 5.x does I see a major difference of r229018, we used to modify the initializer (apparently in-place), but we no longer do and the PTRMEM_CST remains in the IL until the ME.
GCC 6.1 has been released.
GCC 6.2 is being released, adjusting target milestone.
GCC 6.3 is being released, adjusting target milestone.
Here's an even simpler example that ICEs since GCC 4.9.0: ========================= float foo(); struct A { static float x; }; double A::x = foo(); void bar() { A::x = 0; } ========================= bug.cc:8:11: error: conflicting declaration 'double A::x' double A::x = foo(); ^ bug.cc:5:16: note: previous declaration as 'float A::x' static float x; ^ bug.cc:8:11: error: declaration of 'float A::x' outside of class is not definition [-fpermissive] double A::x = foo(); ^ cc1plus: internal compiler error: in record_reference, at cgraphbuild.c:64 0x96b754 record_reference ../../gcc/gcc/cgraphbuild.c:64 0x1048663 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/gcc/tree.c:11838 0x1048ef2 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/gcc/tree.c:12155 0x96c952 record_references_in_initializer(tree_node*, bool) ../../gcc/gcc/cgraphbuild.c:401 0x1088e07 varpool_node::analyze() ../../gcc/gcc/varpool.c:532 0x972916 analyze_functions ../../gcc/gcc/cgraphunit.c:1180 0x973cc2 symbol_table::finalize_compilation_unit() ../../gcc/gcc/cgraphunit.c:2611 Please submit a full bug report, [etc.]
GCC 6.4 is being released, adjusting target milestone.
On it.
Author: paolo Date: Tue Sep 12 19:45:37 2017 New Revision: 252040 URL: https://gcc.gnu.org/viewcvs?rev=252040&root=gcc&view=rev Log: /cp 2017-09-12 Paolo Carlini <paolo.carlini@oracle.com> PR c++/70621 * decl.c (start_decl): Early return error_mark_node if duplicate_decls returns it; avoid misleading error message. /testsuite 2017-09-12 Paolo Carlini <paolo.carlini@oracle.com> PR c++/70621 * g++.dg/torture/pr70621.C: New. Added: trunk/gcc/testsuite/g++.dg/torture/pr70621.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/decl.c trunk/gcc/testsuite/ChangeLog
Fixed in trunk so far.
GCC 6 branch is being closed
Fixed in GCC8.