The following testcase crashes when compiled with -O3. #include <stdbool.h>
bool v_2 = true; bool *v_3 = &v_2; int idv_2 = 0; int idv_3 = 0; int main (int argc, char **argv) { if ((bool)((1527719483 + 1477819644))) { } for (idv_2 = 0; idv_2 < 15; ++idv_2) { for (idv_3 = 0; idv_3 < (v_2 ? 1 : *v_3) ; ++idv_3) { } } return 0; } claire:~/claire/gnu/tmp/gcc402/gcc$ ./xgcc -B./ -O3 -c foo.c foo.c: In function 'main': foo.c:11: warning: integer overflow in expression foo.c:10: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. NOTE: I haven't confirmed the following, but am passing it on in case it speeds up root-causing this. GCC 4.x's tree infrastructure introduces a new mechanism to create constant tree node. Instead of creating a new tree node for every reference of certain type constant as in GCC 3.4.1, a global tree node is created and shared by all references of a constant in GCC 4.x. The attributes of the global tree node is shared by all the references of the constant as well. -------------------------------------------- if ((bool)((1527719483 + 1477819644))) { } for (...) { if (invariant_cond) A else B } ----------------------------------------------------------------- During const-folding optimization, overflow is detected for the expression "(1527719483 + 1477819644)". The folded constant is casted to a boolean constant "1", which is represented by a global tree node "boolean_true_node", and the attribute is passed to the tree node. During the later unswitch optimization, the loop segment is transformed: if (invariant_cond) for (...) { if (1) A else B } if (!invariant_cond) for (...) { if (0) A else B } During the later induction variable reduction optimization, the "1" expression in "if (1)" is checked in the following sequence in find_interesting_uses_cond(): if (integer_zerop(exp) || integer_nonzerop(exp)) {return;} else { ... = exp->operands[0] ... = exp->operands[1] ===> segmentation fault } ===> only one operand in "1" exp The reason is because after the overflow attribute is passed to the boolean_true_node, integer_nonzerop(exp) returns false while it should return true. -- Summary: segv after overflow detection Product: gcc Version: 4.0.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dje at transmeta dot com GCC host triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24599