The attached patch slightly changes the order in which initializers are checked for type compatibility to issue the same error for static initializers of incompatible types as for automatic objects, rather than rejecting the former for their lack of constness first.
I originally closed the bug as WontFix but a better test case sent by the submitter to gcc-help in a subsequent discussion convinced me that there is an improvement to be made here: https://gcc.gnu.org/ml/gcc-help/2016-06/msg00057.html Martin
PR c/71552 - Confusing error for incorrect struct initialization gcc/c/ChangeLog: 2016-06-18 Martin Sebor <mse...@redhat.com> PR c/71552 * c-typeck.c (output_init_element): Diagnose incompatible types before non-constant initializers. gcc/testsuite/ChangeLog: 2016-06-18 Martin Sebor <mse...@redhat.com> PR c/71552 * gcc.dg/init-bad-9.c: New test. Index: gcc/c/c-typeck.c =================================================================== --- gcc/c/c-typeck.c (revision 237461) +++ gcc/c/c-typeck.c (working copy) @@ -8760,6 +8760,22 @@ output_init_element (location_t loc, tre if (!maybe_const) constructor_nonconst = 1; + /* Digest the initializer and issue any errors about incompatible + types before issuing errors about non-constant initializers. */ + tree new_value = value; + if (semantic_type) + new_value = build1 (EXCESS_PRECISION_EXPR, semantic_type, value); + new_value = digest_init (loc, type, new_value, origtype, npc, strict_string, + require_constant_value); + if (new_value == error_mark_node) + { + constructor_erroneous = 1; + return; + } + if (require_constant_value || require_constant_elements) + constant_expression_warning (new_value); + + /* Proceed to check the constness of the original initializer. */ if (!initializer_constant_valid_p (value, TREE_TYPE (value))) { if (require_constant_value) @@ -8804,17 +8820,8 @@ output_init_element (location_t loc, tre || DECL_CHAIN (field))))) return; - if (semantic_type) - value = build1 (EXCESS_PRECISION_EXPR, semantic_type, value); - value = digest_init (loc, type, value, origtype, npc, strict_string, - require_constant_value); - if (value == error_mark_node) - { - constructor_erroneous = 1; - return; - } - if (require_constant_value || require_constant_elements) - constant_expression_warning (value); + /* Finally, set VALUE to the initializer value digested above. */ + value = new_value; /* If this element doesn't come next in sequence, put it on constructor_pending_elts. */ Index: gcc/testsuite/gcc.dg/init-bad-9.c =================================================================== --- gcc/testsuite/gcc.dg/init-bad-9.c (revision 0) +++ gcc/testsuite/gcc.dg/init-bad-9.c (working copy) @@ -0,0 +1,12 @@ +/* PR c/71552 - Confusing error for incorrect struct initialization */ +/* { dg-do compile } */ + +struct A { void *p; }; +struct B { struct A *p; }; +struct A a; + +/* Verify that the initializer is diagnosed for its incompatibility + with the type of the object being initialized, not for its lack + of constness (which is a lesser problem). */ +struct B b = { a }; /* { dg-error "incompatible types when initializing" } */ +struct B *p = a; /* { dg-error "incompatible types when initializing" } */