Hi, This line of code causes gcc for the AVR target to loop for a while and eventually crash after exhausting virtual memory.
char x[] = { [0xFFFFFF] = 2 }; output_pending_init_elements in gcc/c/c-typeck.c ends up in an infinite loop if elt->purpose is a tree representing an integer constant equal to max value of TREE_TYPE(constructor_unfilled_index). For the AVR, that's 0xFFFFFF (PSI mode). This happens because output_init_element, in addition to recording the initialization in a collection, logically increments constructor_unfilled_index (by generating a size_binop_loc with a PLUS_EXPR and a int const node representing the number 1, followed by a fold and a forcefit to the type). This obviously causes a overflow if the tree passed in represents an integer constant that's already at the max limit. This is not handled in the body of the while (elt) loop, and constructor_unfilled_index keeps alternating between trees representing 0 and 0xFFFFFF (max value), eventually running out of memory and crashing. I tried to reproduce the problem for x86_64, but I get an ICE even before output_pending_init_elements is called, apparently because of PR 57821. The below patch fixes the code to not consider an overflowed constructor_unfilled_index to be less than elt->purpose. Is this ok? Regards Senthil gcc/c/ChangeLog 2013-08-23 Senthil Kumar Selvaraj <senthil_kumar.selva...@atmel.com> * c-typeck.c (output_pending_init_elements): Handle overflow of constructor_unfilled_index. diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index d9ae01c..f87c2a0 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -7953,8 +7953,9 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) TREE_TYPE (constructor_type), constructor_unfilled_index, 0, false, braced_init_obstack); - else if (tree_int_cst_lt (constructor_unfilled_index, - elt->purpose)) + else if (!TREE_OVERFLOW_P (constructor_unfilled_index) + && tree_int_cst_lt (constructor_unfilled_index, + elt->purpose)) { /* Advance to the next smaller node. */ if (elt->left) @@ -7979,7 +7980,8 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) while (elt->parent && elt->parent->right == elt) elt = elt->parent; elt = elt->parent; - if (elt && tree_int_cst_lt (constructor_unfilled_index, + if (elt && !TREE_OVERFLOW_P (constructor_unfilled_index) + && tree_int_cst_lt (constructor_unfilled_index, elt->purpose)) { next = elt->purpose;