[backport gcc-4.8/trunk r194860, there was no ChangeLog entry for the test case ] gcc/cp/ 2013-01-03 Jason Merrill PR c++/53650 * call.c (type_has_extended_temps): New. * cp-tree.h: Declare it. * decl.c (check_initializer): Use build_aggr_init for arrays if it is false. * init.c (build_vec_init): Avoid mixed signed/unsigned arithmetic. --- gcc-4.7.2/gcc/cp/call.c.~1~ 2012-08-31 19:16:39.000000000 +0200 +++ gcc-4.7.2/gcc/cp/call.c 2013-01-05 15:46:34.000000000 +0100 @@ -8832,6 +8832,30 @@ extend_ref_init_temps (tree decl, tree i return init; } +/* Returns true iff an initializer for TYPE could contain temporaries that + need to be extended because they are bound to references or + std::initializer_list. */ + +bool +type_has_extended_temps (tree type) +{ + type = strip_array_types (type); + if (TREE_CODE (type) == REFERENCE_TYPE) + return true; + if (CLASS_TYPE_P (type)) + { + tree f; + + if (is_std_init_list (type)) + return true; + for (f = next_initializable_field (TYPE_FIELDS (type)); + f; f = next_initializable_field (DECL_CHAIN (f))) + if (type_has_extended_temps (TREE_TYPE (f))) + return true; + } + return false; +} + /* Returns true iff TYPE is some variant of std::initializer_list. */ bool --- gcc-4.7.2/gcc/cp/cp-tree.h.~1~ 2012-09-10 16:24:19.000000000 +0200 +++ gcc-4.7.2/gcc/cp/cp-tree.h 2013-01-05 15:45:34.000000000 +0100 @@ -4892,6 +4892,7 @@ extern tree initialize_reference (tree, tsubst_flags_t); extern tree extend_ref_init_temps (tree, tree, VEC(tree,gc)**); extern tree make_temporary_var_for_ref_to_temp (tree, tree); +extern bool type_has_extended_temps (tree); extern tree strip_top_quals (tree); extern bool reference_related_p (tree, tree); extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t); --- gcc-4.7.2/gcc/cp/decl.c.~1~ 2012-09-10 16:24:19.000000000 +0200 +++ gcc-4.7.2/gcc/cp/decl.c 2013-01-05 15:45:34.000000000 +0100 @@ -5556,7 +5556,9 @@ check_initializer (tree decl, tree init, if ((type_build_ctor_call (type) || CLASS_TYPE_P (type)) && !(flags & LOOKUP_ALREADY_DIGESTED) && !(init && BRACE_ENCLOSED_INITIALIZER_P (init) - && CP_AGGREGATE_TYPE_P (type))) + && CP_AGGREGATE_TYPE_P (type) + && (CLASS_TYPE_P (type) + || type_has_extended_temps (type)))) { init_code = build_aggr_init_full_exprs (decl, init, flags); --- gcc-4.7.2/gcc/cp/init.c.~1~ 2012-09-10 16:24:07.000000000 +0200 +++ gcc-4.7.2/gcc/cp/init.c 2013-01-05 15:45:34.000000000 +0100 @@ -3501,7 +3501,9 @@ build_vec_init (tree base, tree maxindex if (TREE_CODE (type) == ARRAY_TYPE) m = cp_build_binary_op (input_location, MULT_EXPR, m, - array_type_nelts_total (type), + /* Avoid mixing signed and unsigned. */ + convert (TREE_TYPE (m), + array_type_nelts_total (type)), complain); finish_cleanup_try_block (try_block); --- gcc-4.7.2/gcc/testsuite/g++.dg/init/array34.C.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.2/gcc/testsuite/g++.dg/init/array34.C 2013-01-05 15:45:34.000000000 +0100 @@ -0,0 +1,13 @@ +// PR c++/53650 +// We should loop over array inits if they don't involve temporaries +// that need extending. +// { dg-final { scan-assembler-times "_ZN5ClassC1Ev" 1 } } + +struct Class { + Class(); +}; + +int main() { + Class table [10] = {}; + return 0; +}