diff mbox

c/71552 - Confusing error for incorrect struct initialization

Message ID 5765C17C.3040801@gmail.com
State New
Headers show

Commit Message

Martin Sebor June 18, 2016, 9:47 p.m. UTC
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

Comments

Joseph Myers June 20, 2016, 2:52 p.m. UTC | #1
On Sat, 18 Jun 2016, Martin Sebor wrote:

> 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.

OK, presuming the patch has passed the usual testing.
Martin Sebor June 30, 2016, 10:38 p.m. UTC | #2
On 06/20/2016 08:52 AM, Joseph Myers wrote:
> On Sat, 18 Jun 2016, Martin Sebor wrote:
>
>> 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.
>
> OK, presuming the patch has passed the usual testing.

Thanks.  I committed it in r237829.  The reporter wants to know
if the patch can also be backported to 5 and or 6.  Should I go
ahead?

Martin
Jeff Law July 6, 2016, 9:55 p.m. UTC | #3
On 06/30/2016 04:38 PM, Martin Sebor wrote:
> On 06/20/2016 08:52 AM, Joseph Myers wrote:
>> On Sat, 18 Jun 2016, Martin Sebor wrote:
>>
>>> 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.
>>
>> OK, presuming the patch has passed the usual testing.
>
> Thanks.  I committed it in r237829.  The reporter wants to know
> if the patch can also be backported to 5 and or 6.  Should I go
> ahead?
My inclination would be no -- it's not a regression or incorrect code 
generation.

jeff
Martin Sebor July 6, 2016, 10:23 p.m. UTC | #4
On 07/06/2016 03:55 PM, Jeff Law wrote:
> On 06/30/2016 04:38 PM, Martin Sebor wrote:
>> On 06/20/2016 08:52 AM, Joseph Myers wrote:
>>> On Sat, 18 Jun 2016, Martin Sebor wrote:
>>>
>>>> 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.
>>>
>>> OK, presuming the patch has passed the usual testing.
>>
>> Thanks.  I committed it in r237829.  The reporter wants to know
>> if the patch can also be backported to 5 and or 6.  Should I go
>> ahead?
> My inclination would be no -- it's not a regression or incorrect code
> generation.

Thanks.  I let the reporter know.

Martin
diff mbox

Patch

PR c/71552 - Confusing error for incorrect struct initialization

gcc/c/ChangeLog:
2016-06-18  Martin Sebor  <msebor@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  <msebor@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" } */