PR c/71552 - Confusing error for incorrect struct initialization
authorMartin Sebor <msebor@redhat.com>
Tue, 28 Jun 2016 20:09:36 +0000 (20:09 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 28 Jun 2016 20:09:36 +0000 (14:09 -0600)
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
gcc/c/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/init-bad-9.c [new file with mode: 0644]

index d32049c13e6a2b9c82359fb42d0612be88bf510e..403f267b612b0459d84bd5838409211cdfb4370d 100644 (file)
@@ -1,3 +1,9 @@
+2016-06-28 Martin Sebor  <msebor@redhat.com>
+
+       PR c/71552
+       * c-typeck.c (output_init_element): Diagnose incompatible types
+       before non-constant initializers.
+
 2016-06-28  Jakub Jelinek  <jakub@redhat.com>
 
        * Make-lang.in: Don't cat ../stage_current if it does not exist.
index 7c6241c22d61fd163d4835be9163e5f635430cf8..818ad944f3fc2fd5e8573100cb1f67134c04c596 100644 (file)
@@ -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.  */
index d210675ed59d13a460fa1eb7f96a4fe413a428c0..5fb67e13288f346b01de7ed73579c50e4db8b5d7 100644 (file)
@@ -1,3 +1,8 @@
+2016-06-28 Martin Sebor  <msebor@redhat.com>
+
+       PR c/71552
+       * gcc.dg/init-bad-9.c: New test.
+
 2016-06-28  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        * 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 (file)
index 0000000..035d349
--- /dev/null
@@ -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" } */