re PR c/21342 (some incompatible external declarations not diagnosed)
authorJoseph Myers <joseph@codesourcery.com>
Tue, 10 May 2005 12:38:34 +0000 (13:38 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Tue, 10 May 2005 12:38:34 +0000 (13:38 +0100)
PR c/21342
* c-decl.c (pushdecl): When there is a declaration in the current
scope and the declarations are external linkage, check for
compatibility with the type in the external scope and update the
type in the external scope with the composite type information.
Do not form a composite type of the new type and the visible type
if they are incompatible.

testsuite:
* gcc.dg/redecl-11.c, gcc.dg/redecl-12.c, gcc.dg/redecl-13.c,
gcc.dg/redecl-14.c, gcc.dg/redecl-15.c: New tests.

From-SVN: r99510

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/redecl-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/redecl-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/redecl-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/redecl-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/redecl-15.c [new file with mode: 0644]

index 82d7ba0629da241c0001f40118b6c8dff2e2c56f..ffdd2bbff2afbf8dfedbe289589f6ee41fef5058 100644 (file)
@@ -1,3 +1,13 @@
+2005-05-10  Joseph S. Myers  <joseph@codesourcery.com>
+
+       PR c/21342
+       * c-decl.c (pushdecl): When there is a declaration in the current
+       scope and the declarations are external linkage, check for
+       compatibility with the type in the external scope and update the
+       type in the external scope with the composite type information.
+       Do not form a composite type of the new type and the visible type
+       if they are incompatible.
+
 2005-05-10  Nathan Sidwell  <nathan@codesourcery.com>
 
        * crtstuff.c: Revert part of 2005-05-08 Change.
index e7ac0d3690da5e6f9e5183dd7fc325e31601e9c2..0ca4500021ecc44f02a2e06b0ff68e65657fc232 100644 (file)
@@ -2029,11 +2029,52 @@ pushdecl (tree x)
   b = I_SYMBOL_BINDING (name);
   if (b && B_IN_SCOPE (b, scope))
     {
+      struct c_binding *b_ext, *b_use;
+      tree type = TREE_TYPE (x);
+      tree visdecl = b->decl;
+      tree vistype = TREE_TYPE (visdecl);
       if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
          && COMPLETE_TYPE_P (TREE_TYPE (x)))
        b->inner_comp = false;
-      if (duplicate_decls (x, b->decl))
-       return b->decl;
+      b_use = b;
+      b_ext = b;
+      /* If this is an external linkage declaration, we should check
+        for compatibility with the type in the external scope before
+        setting the type at this scope based on the visible
+        information only.  */
+      if (TREE_PUBLIC (x) && TREE_PUBLIC (visdecl))
+       {
+         while (b_ext && !B_IN_EXTERNAL_SCOPE (b_ext))
+           b_ext = b_ext->shadowed;
+         if (b_ext)
+           {
+             b_use = b_ext;
+             if (b_use->type)
+               TREE_TYPE (b_use->decl) = b_use->type;
+           }
+       }
+      if (duplicate_decls (x, b_use->decl))
+       {
+         if (b_use != b)
+           {
+             /* Save the updated type in the external scope and
+                restore the proper type for this scope.  */
+             tree thistype;
+             if (comptypes (vistype, type))
+               thistype = composite_type (vistype, type);
+             else
+               thistype = TREE_TYPE (b_use->decl);
+             b_use->type = TREE_TYPE (b_use->decl);
+             if (TREE_CODE (b_use->decl) == FUNCTION_DECL
+                 && DECL_BUILT_IN (b_use->decl))
+               thistype
+                 = build_type_attribute_variant (thistype,
+                                                 TYPE_ATTRIBUTES
+                                                 (b_use->type));
+             TREE_TYPE (b_use->decl) = thistype;
+           }
+         return b_use->decl;
+       }
       else
        goto skip_external_and_shadow_checks;
     }
@@ -2120,7 +2161,15 @@ pushdecl (tree x)
          && duplicate_decls (x, b->decl))
        {
          tree thistype;
-         thistype = (vistype ? composite_type (vistype, type) : type);
+         if (vistype)
+           {
+             if (comptypes (vistype, type))
+               thistype = composite_type (vistype, type);
+             else
+               thistype = TREE_TYPE (b->decl);
+           }
+         else
+           thistype = type;
          b->type = TREE_TYPE (b->decl);
          if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl))
            thistype
index 55605df8f03954b4cf3c177ba56cd02ade1e3e25..7dd2e1970d9089371c675a49ad897585971bac40 100644 (file)
@@ -1,3 +1,9 @@
+2005-05-10  Joseph S. Myers  <joseph@codesourcery.com>
+
+       PR c/21342
+       * gcc.dg/redecl-11.c, gcc.dg/redecl-12.c, gcc.dg/redecl-13.c,
+       gcc.dg/redecl-14.c, gcc.dg/redecl-15.c: New tests.
+
 2005-05-10  Ben Elliston  <bje@au.ibm.com>
 
        PR debug/16676
diff --git a/gcc/testsuite/gcc.dg/redecl-11.c b/gcc/testsuite/gcc.dg/redecl-11.c
new file mode 100644 (file)
index 0000000..a0554d9
--- /dev/null
@@ -0,0 +1,9 @@
+/* Some incompatible external linkage declarations were not diagnosed.
+   Bug 21342.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int f(int (*)[]);
+void g() { int f(int (*)[2]); } /* { dg-error "error: previous declaration of 'f' was here" } */
+int f(int (*)[3]); /* { dg-error "error: conflicting types for 'f'" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-12.c b/gcc/testsuite/gcc.dg/redecl-12.c
new file mode 100644 (file)
index 0000000..cb1501d
--- /dev/null
@@ -0,0 +1,9 @@
+/* Some incompatible external linkage declarations were not diagnosed.
+   Bug 21342.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+extern int a[];
+void f(void) { extern int a[]; extern int a[10]; } /* { dg-error "error: previous declaration of 'a' was here" } */
+extern int a[5]; /* { dg-error "error: conflicting types for 'a'" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-13.c b/gcc/testsuite/gcc.dg/redecl-13.c
new file mode 100644 (file)
index 0000000..54be4db
--- /dev/null
@@ -0,0 +1,9 @@
+/* Some incompatible external linkage declarations were not diagnosed.
+   Bug 21342.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+extern int a[];
+void f(void) { extern int a[10]; } /* { dg-error "error: previous declaration of 'a' was here" } */
+extern int a[5]; /* { dg-error "error: conflicting types for 'a'" } */
diff --git a/gcc/testsuite/gcc.dg/redecl-14.c b/gcc/testsuite/gcc.dg/redecl-14.c
new file mode 100644 (file)
index 0000000..ed19610
--- /dev/null
@@ -0,0 +1,22 @@
+/* Some incompatible external linkage declarations were not diagnosed.
+   Bug 21342.  Test type in inner scope is correct.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+typedef int IA[];
+typedef int IA5[5];
+typedef IA *IAP;
+typedef IA5 *IA5P;
+extern IAP a[];
+void
+f (void)
+{
+  {
+    extern IA5P a[];
+    sizeof (*a[0]);
+  }
+  extern IAP a[];
+  extern IAP a[5];
+  sizeof (*a[0]); /* { dg-error "error: invalid application of 'sizeof' to incomplete type 'IA'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/redecl-15.c b/gcc/testsuite/gcc.dg/redecl-15.c
new file mode 100644 (file)
index 0000000..c4ac76c
--- /dev/null
@@ -0,0 +1,14 @@
+/* Test for ICE with redeclaration in inner scope which is accepted
+   despite incompatible type.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+f (void)
+{
+  g(); /* { dg-warning "warning: previous implicit declaration of 'g' was here" } */
+  {
+    void g(); /* { dg-warning "warning: conflicting types for 'g'" } */
+  }
+}