Bug 17323 - [3.4/4.0/4.1 regression] ICE on invalid code if static member array initialized with size computed as division by zero
Summary: [3.4/4.0/4.1 regression] ICE on invalid code if static member array initializ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.1
: P2 normal
Target Milestone: 3.4.5
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-invalid-code, monitored
Depends on:
Blocks: 20789
  Show dependency treegraph
 
Reported: 2004-09-04 18:55 UTC by niemayer
Modified: 2005-06-14 08:30 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-02-26 18:42:20


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description niemayer 2004-09-04 18:55:19 UTC
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.
Comment 1 Kriang Lerdsuwanakij 2004-09-06 16:13:24 UTC
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> { ... };
Comment 2 Giovanni Bajo 2004-09-06 16:56:35 UTC
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.
Comment 3 Wolfgang Bangerth 2004-09-07 23:53:12 UTC
Wouldn't we then run into the same problem when using 
  (sizeof(T)-1) 
? 
 
W. 
Comment 4 Andrew Pinski 2004-09-08 07:04:03 UTC
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).
Comment 5 Volker Reichelt 2005-02-10 16:14:08 UTC
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
Comment 6 Volker Reichelt 2005-06-14 08:30:40 UTC
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.