Patchwork Fix PR c/35445: ICE with conflicting declarations

login
register
mail settings
Submitter Simon Martin
Date May 2, 2011, 5:55 a.m.
Message ID <4DBE4735.3020008@users.sourceforge.net>
Download mbox | patch
Permalink /patch/93591/
State New
Headers show

Comments

Simon Martin - May 2, 2011, 5:55 a.m.
Hello,

The following invalid snippet triggers an ICE since 4.0.1:



2011-05-01  Simon Martin  <simartin@users.sourceforge.net>

     PR c/35445
     * gcc.dg/pr35445.c: New test.


/* PR c/35445 */
/* { dg-do "compile" } */

extern int i;
extern int i; /* { dg-message "was here" } */
int i[] = { 0 }; /* { dg-error "conflicting types" } */
Joseph S. Myers - May 2, 2011, 10:56 a.m.
On Mon, 2 May 2011, Simon Martin wrote:

> 2011-05-01  Simon Martin  <simartin@users.sourceforge.net>
> 
>     PR c/35445
>     * c-decl.c (finish_decl): Only create a composite if the types are
>     compatible.
> 
> 2011-05-01  Simon Martin  <simartin@users.sourceforge.net>
> 
>     PR c/35445
>     * gcc.dg/pr35445.c: New test.

OK.

Patch

====
extern int i;
extern int i;
int i[] = { 0 };
====

The problem is that 'finish_decl' ends up calling 'composite_type' with 
incompatible types when updating the type of the declaration of 'i' 
already encountered.

The attached patch fixes this by only calling 'composite_type' if 
'comptypes' returned a non-zero value, as stated in this function's 
documentation.

I've successfully bootstrapped and tested it on 
x86_64-apple-darwin10.6.0. Is it OK for trunk?

Best regards,
   Simon



2011-05-01  Simon Martin  <simartin@users.sourceforge.net>

     PR c/35445
     * c-decl.c (finish_decl): Only create a composite if the types are
     compatible.


Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 173206)
+++ gcc/c-decl.c	(working copy)
@@ -4246,7 +4246,7 @@ 
  		b_ext = b_ext->shadowed;
  	      if (b_ext)
  		{
-		  if (b_ext->u.type)
+		  if (b_ext->u.type && comptypes (b_ext->u.type, type))
  		    b_ext->u.type = composite_type (b_ext->u.type, type);
  		  else
  		    b_ext->u.type = type;