The following tiny piece of C++ code causes an ICE: ---------------------- ice.cxx -------------------------------------- template <class T> class A { static const int x = 1024/sizeof(T); static char i[x]; }; class B : public A<B> { }; ------------------------------------------------------------------- Output after "gcc -c ice.cxx" is: ice.cxx: In instantiation of `A<B>': ice.cxx:8: instantiated from here ice.cxx:4: error: invalid application of `sizeof' to incomplete type `B' ice.cxx:4: warning: division by zero in `1024 / 0' gcc: Internal error: Segmentation fault (program cc1plus) Please submit a full bug report. BTW: I would be very interested to hear if there's a legal (compile-time) equivalent to the code above - so far I've found only clumsy work-arounds that need run-time tests.
Confirm the ICE. I don't know if this workaround is good enough - A<B> now only counts the size of B only, the 'x' and 'i' variables not included: class B { ... }; class C: public B, A<B> { ... };
This is probably unbroken if we internally return "1" as size of the incomplete type, after we emit the diagnostic. After all, no types in C++ can have size 0, so expanding sizeof to zero is asking for troubles.
Wouldn't we then run into the same problem when using (sizeof(T)-1) ? W.
hmm, the problem looks like it has nothing to do with sizeof at all but it has to do with DECL_INITIAL for x still being an INIT_EXPR so we check the first operand for value_dependent_expression_p but since that just links back to x, we go into an infinite loop which causes this ICE (stack overflow). Maybe we should have cleared out the DECL_INITIAL and put a error_node there instead. Part of the backtrace (I cannot get all of it because it is just repeating two parts of alue_dependent_expression_p) #40392 0x080eab2d in cp_parser_type_specifier (parser=0xf6e128f0, flags=Variable "flags" is not available. ) at /home/gates/pinskia/src/gnu/gcc/src/gcc/cp/parser.c:12809 warning: Source file is more recent than executable. 12809 CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type); (gdb) up -1 #40391 0x080776e1 in xref_basetypes (ref=0xf6e14074, base_list=0xf6e13180) at /home/gates/ pinskia/src/gnu/gcc/src/gcc/cp/decl.c:9136 warning: Source file is more recent than executable. Also gdb just seg faults on me alot when going through all these stack frames (yes I am using the cvs version, I should report a bug).
Here's a reduced testcase without sizeof: ================================= template<int N> struct A { static const int i = 8/N; char c[i]; }; A<0> a; ================================= The error message is: mmm.cc: In instantiation of 'A<0>': mmm.cc:7: instantiated from here mmm.cc:3: warning: division by zero in '8 / 0' g++: Internal error: Segmentation fault (program cc1plus) The ICE appears with 3.4.0. Before I get the following error message: mmm.cc: In instantiation of `A<0>': mmm.cc:7: instantiated from here mmm.cc:3: warning: division by zero in `8 / 0' mmm.cc:7: error: variable-size type declared outside of any function mmm.cc:7: error: variable-size type declared outside of any function
Fixed by Nathan's patch for PR 20789. Fixed already on mainline and 3.4 branch. The patch will be applied to the 4.0 branch once GCC 4.0.1 is out. So closing as fixed.