For arrays of size zero the C++ frontend generates a TYPE_DOMAIN using build_index_type (which is hardcoded to unsigned sizetype) passing it -1 (in ssizetype ...) as the maximum index (build_index_type will use size_zero_node as minimum index). That works all well as long as sizetype constants are signextended, but process_init_constructor_array does:
tree domain = TYPE_DOMAIN (type); if (domain) ! len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain)) ! - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain)) ! + 1); so if that -1 is not sign-extended and sizetype is 32bits on a 64bit host (where TREE_INT_CST_LOW is 64bit) then the above computes a non-sensical value, 0x100000000, that is. The C frontend (now) avoids this by using a [0, ] TYPE_DOMAIN for the extension of zero-size arrays but I see that size can be the result of template expansion in C++ (and maybe other places in the C++ frontend assume taht TYPE_MAX_VALUE of TYPE_DOMAIN is never NULL). I know that simply using a range type with ssizetype does not work (yeah, we should make that work I guess ...), so the fix for the above code is to properly do twos-complement arithmetic and truncate/extend the HOST_WIDE_INT value. Another fix would be to use a [1, 0] domain - not sure what that would break though. Like with the following patch (heh, C++ operator overloading would make dealing with double-ints so much nicer to look at ...). Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. This cures the last non-Ada failure I have with the patchset that makes TYPE_UNSIGNED sizetype constants no longer sign-extended. Ok for trunk? Thanks, Richard. 2012-03-28 Richard Guenther <rguent...@suse.de> cp/ * typeck2.c (process_init_constructor_array): Use the proper type for computing the array length. Index: gcc/cp/typeck2.c =================================================================== *** gcc/cp/typeck2.c (revision 185911) --- gcc/cp/typeck2.c (working copy) *************** process_init_constructor_array (tree typ *** 1054,1062 **** { tree domain = TYPE_DOMAIN (type); if (domain) ! len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain)) ! - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain)) ! + 1); else unbounded = true; /* Take as many as there are. */ } --- 1054,1067 ---- { tree domain = TYPE_DOMAIN (type); if (domain) ! len = double_int_ext ! (double_int_add ! (double_int_sub ! (tree_to_double_int (TYPE_MAX_VALUE (domain)), ! tree_to_double_int (TYPE_MIN_VALUE (domain))), ! double_int_one), ! TYPE_PRECISION (TREE_TYPE (domain)), ! TYPE_UNSIGNED (TREE_TYPE (domain))).low; else unbounded = true; /* Take as many as there are. */ }