c-decl.c (diagnose_mismatched_decls): Accept mismatched function types: void with...
authorDale Johannesen <dalej@apple.com>
Fri, 17 Dec 2004 20:05:34 +0000 (20:05 +0000)
committerDale Johannesen <dalej@gcc.gnu.org>
Fri, 17 Dec 2004 20:05:34 +0000 (20:05 +0000)
2004-12-17  Dale Johannesen  <dalej@apple.com>

* c-decl.c (diagnose_mismatched_decls):  Accept mismatched
function types: void with previous implicit int.

From-SVN: r92329

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20041213-1.c [new file with mode: 0644]

index 3a80abab8aa6af9d68a430230b665a44ed465c80..50a14327d99d260a7c60ed65c2ada776dadad5b0 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-17  Dale Johannesen  <dalej@apple.com>
+
+       * c-decl.c (diagnose_mismatched_decls):  Accept mismatched
+       function types: void with previous implicit int.
+
 2004-12-17  Andreas Krebbel  <krebbel1@de.ibm.com>
 
        * config/s390/s390.c (s390_gimplify_va_arg): Set alias set to 
index ea26da44a3c048ba7673d59d75639f8d549d983e..b728a6b3faae02c838de22006a2c435ecaaddb36 100644 (file)
@@ -1191,7 +1191,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       else if (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl)
               && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == void_type_node
               && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
-              && C_FUNCTION_IMPLICIT_INT (newdecl))
+              && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl))
        {
          pedwarn ("%Jconflicting types for %qD", newdecl, newdecl);
          /* Make sure we keep void as the return type.  */
@@ -1199,6 +1199,18 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
          pedwarned = true;
        }
+      /* Permit void foo (...) to match an earlier call to foo (...) with
+        no declared type (thus, implicitly int).  */
+      else if (TREE_CODE (newdecl) == FUNCTION_DECL
+              && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == void_type_node
+              && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node
+              && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
+       {
+         pedwarn ("%Jconflicting types for %qD", newdecl, newdecl);
+         /* Make sure we keep void as the return type.  */
+         TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype;
+         pedwarned = true;
+       }
       else
        {
          if (TYPE_QUALS (newtype) != TYPE_QUALS (oldtype))
index ee5212094b21c10e7f0d69205ed8c75a06126787..6dbca4ac5d69d6849bcc94a3c4574a826da06ede 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-17  Dale Johannesen  <dalej@apple.com>
+
+       * gcc.dg/20041213-1.c:  New.
+
 2004-12-17  Ziemowit Laski  <zlaski@apple.com>
 
        * objc.dg/stabs-1.m: Allow assembly label to begin
diff --git a/gcc/testsuite/gcc.dg/20041213-1.c b/gcc/testsuite/gcc.dg/20041213-1.c
new file mode 100644 (file)
index 0000000..9902737
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* test redeclarations with void and implicit int */
+extern foo1(); /* { dg-error "error: previous declaration" } */
+extern void foo1(); /* { dg-error "error: conflicting types" } */
+
+extern void foo2(); /* { dg-error "error: previous declaration" } */
+extern foo2(); /* { dg-error "error: conflicting types" } */
+
+void foo3() {} /* { dg-error "error: previous definition" } */
+extern foo3(); /* { dg-error "error: conflicting types" } */
+
+extern foo4(); /* { dg-error "error: previous declaration" } */
+void foo4() {} /* { dg-error "error: conflicting types" } */
+
+extern void foo5(); /* { dg-warning "previous declaration" } */
+foo5() {} /* { dg-warning "conflicting types" } */
+
+foo6() {} /* { dg-error "error: previous definition" } */
+extern void foo6(); /* { dg-error "error: conflicting types" } */
+
+foo7() {} /* { dg-error "error: previous definition" } */
+void foo7() {} /* { dg-error "error: conflicting types" } */
+
+void foo8() {} /* { dg-error "error: previous definition" } */
+foo8() {} /* { dg-error "error: conflicting types" } */
+
+int use9() { foo9(); } /* { dg-warning "previous implicit declaration" } */
+extern void foo9(); /* { dg-warning "conflicting types" } */
+
+int use10() { foo10(); } /* { dg-warning "previous implicit declaration" } */
+void foo10() {} /* { dg-warning "conflicting types" } */
+