From 4378d117ec35f58d5a552eafcb91c91550e6566e Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 28 Jun 2016 20:09:36 +0000 Subject: [PATCH] PR c/71552 - Confusing error for incorrect struct initialization gcc/c/ChangeLog: PR c/71552 * c-typeck.c (output_init_element): Diagnose incompatible types before non-constant initializers. gcc/testsuite/ChangeLog: PR c/71552 * gcc.dg/init-bad-9.c: New test. From-SVN: r237829 --- gcc/c/ChangeLog | 6 ++++++ gcc/c/c-typeck.c | 29 ++++++++++++++++++----------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/init-bad-9.c | 12 ++++++++++++ 4 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/init-bad-9.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index d32049c13e6..403f267b612 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2016-06-28 Martin Sebor + + PR c/71552 + * c-typeck.c (output_init_element): Diagnose incompatible types + before non-constant initializers. + 2016-06-28 Jakub Jelinek * Make-lang.in: Don't cat ../stage_current if it does not exist. diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 7c6241c22d6..818ad944f3f 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -8754,6 +8754,22 @@ output_init_element (location_t loc, tree value, tree origtype, 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) @@ -8798,17 +8814,8 @@ output_init_element (location_t loc, tree value, tree origtype, || 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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d210675ed59..5fb67e13288 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-06-28 Martin Sebor + + PR c/71552 + * gcc.dg/init-bad-9.c: New test. + 2016-06-28 Bill Schmidt * gcc.target/powerpc/abs128-1.c: Require VSX. diff --git a/gcc/testsuite/gcc.dg/init-bad-9.c b/gcc/testsuite/gcc.dg/init-bad-9.c new file mode 100644 index 00000000000..035d34940dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/init-bad-9.c @@ -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" } */ -- 2.30.2