re PR c/15052 (gcc frontend accepts mismatched function declaration/defintion)
authorJoseph Myers <jsm@polyomino.org.uk>
Thu, 22 Jul 2004 00:00:47 +0000 (01:00 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Thu, 22 Jul 2004 00:00:47 +0000 (01:00 +0100)
PR c/15052
* c-decl.c (grokdeclarator): Only pedwarn for qualified void
return type on function definitions.  Move other warnings for
qualified return type to -Wreturn-type.  Do not condition any such
warnings on -pedantic.  Update comments.
(start_function): Only copy function type from previous prototype
declaration if return types are compatible.
* c-typeck.c (function_types_compatible_p): Don't condition
warning for incompatibility of volatile qualifiers on the return
type on -pedantic.  Update comment.
* doc/invoke.texi (-Wreturn-type, -Wextra): Update.

testsuite:
* gcc.dg/noreturn-5.c: Test qualifiers on function type instead of
on return type.
* gcc.dg/qual-return-1.c: Use -Wreturn-type.  Update expected
messages.
* gcc.dg/qual-return-2.c: Update expected messages.
* gcc.dg/qual-return-3.c, gcc.dg/qual-return-4.c: New tests.

From-SVN: r85024

gcc/ChangeLog
gcc/c-decl.c
gcc/c-typeck.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/noreturn-5.c
gcc/testsuite/gcc.dg/qual-return-1.c
gcc/testsuite/gcc.dg/qual-return-2.c
gcc/testsuite/gcc.dg/qual-return-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/qual-return-4.c [new file with mode: 0644]

index 00f2261e63f1131bb2443c90497641560d70798d..41622fb420b3dfe65eac0fe57cf1521b3f8b7a89 100644 (file)
@@ -1,3 +1,17 @@
+2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk>
+
+       PR c/15052
+       * c-decl.c (grokdeclarator): Only pedwarn for qualified void
+       return type on function definitions.  Move other warnings for
+       qualified return type to -Wreturn-type.  Do not condition any such
+       warnings on -pedantic.  Update comments.
+       (start_function): Only copy function type from previous prototype
+       declaration if return types are compatible.
+       * c-typeck.c (function_types_compatible_p): Don't condition
+       warning for incompatibility of volatile qualifiers on the return
+       type on -pedantic.  Update comment.
+       * doc/invoke.texi (-Wreturn-type, -Wextra): Update.
+
 2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * c-typeck.c (set_init_index): Require designator to be of integer
index c5b50a263123799a88e4f920bbfb089e85e478ef..ac812e3dea7d80428071183f8171149f2e56e8ff 100644 (file)
@@ -4165,21 +4165,15 @@ grokdeclarator (tree declarator, tree declspecs,
             qualify the return type, not the function type.  */
          if (type_quals)
            {
-             /* Type qualifiers on a function return type are normally
-                permitted by the standard but have no effect, so give a
-                warning at -Wextra.  Qualifiers on a void return type have
-                meaning as a GNU extension, and are banned on function
-                definitions in ISO C.  FIXME: strictly we shouldn't
-                pedwarn for qualified void return types except on function
-                definitions, but not doing so could lead to the undesirable
-                state of a "volatile void" function return type not being
-                warned about, and a use of the function being compiled
-                with GNU semantics, with no diagnostics under -pedantic.  */
-             if (VOID_TYPE_P (type) && pedantic && !in_system_header)
-               pedwarn ("ISO C forbids qualified void function return type");
-             else if (extra_warnings
-                      && !(VOID_TYPE_P (type)
-                           && type_quals == TYPE_QUAL_VOLATILE))
+             /* Type qualifiers on a function return type are
+                normally permitted by the standard but have no
+                effect, so give a warning at -Wreturn-type.
+                Qualifiers on a void return type are banned on
+                function definitions in ISO C; GCC used to used them
+                for noreturn functions.  */
+             if (VOID_TYPE_P (type) && really_funcdef)
+               pedwarn ("function definition has qualified void return type");
+             else if (warn_return_type)
                warning ("type qualifiers ignored on function return type");
 
              type = c_build_qualified_type (type, type_quals);
@@ -4499,7 +4493,7 @@ grokdeclarator (tree declarator, tree declspecs,
        if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
          pedwarn ("ISO C forbids qualified function types");
 
-       /* GNU C interprets a `volatile void' return type to indicate
+       /* GNU C interprets a volatile-qualified function type to indicate
           that the function does not return.  */
        if ((type_quals & TYPE_QUAL_VOLATILE)
            && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
@@ -5714,8 +5708,8 @@ start_function (tree declspecs, tree declarator, tree attributes)
   old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope);
   if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
       && !DECL_BUILT_IN (old_decl)
-      && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
-         == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (old_decl))))
+      && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
+                   TREE_TYPE (TREE_TYPE (old_decl)))
       && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
     {
       TREE_TYPE (decl1) = TREE_TYPE (old_decl);
index 04ed0684dbe4d2e92b3c335eb5a9fb8650561fe0..8d201cdbda5ceb7852de1ac49b94096f202df7dc 100644 (file)
@@ -958,9 +958,9 @@ function_types_compatible_p (tree f1, tree f2)
   ret1 = TREE_TYPE (f1);
   ret2 = TREE_TYPE (f2);
 
-  /* 'volatile' qualifiers on a function's return type mean the function
-     is noreturn.  */
-  if (pedantic && TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
+  /* 'volatile' qualifiers on a function's return type used to mean
+     the function is noreturn.  */
+  if (TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
     pedwarn ("function return types not compatible due to `volatile'");
   if (TYPE_VOLATILE (ret1))
     ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1),
index 43f2df66ddbf229d9725d9147ca5cf5308a0b6c7..efd20a97eed6ff0c2315da8423d1214fc284dde1 100644 (file)
@@ -2349,6 +2349,12 @@ Warn whenever a function is defined with a return-type that defaults to
 @code{int}.  Also warn about any @code{return} statement with no
 return-value in a function whose return-type is not @code{void}.
 
+For C, also warn if the return type of a function has a type qualifier
+such as @code{const}.  Such a type qualifier has no effect, since the
+value returned by a function is not an lvalue.  ISO C prohibits
+qualified @code{void} return types on function definitions, so such
+return types always receive a warning even without this option.
+
 For C++, a function without return type always produces a diagnostic
 message, even when @option{-Wno-return-type} is specified.  The only
 exceptions are @samp{main} and functions defined in system headers.
@@ -2578,13 +2584,6 @@ An unsigned value is compared against zero with @samp{<} or @samp{>=}.
 Storage-class specifiers like @code{static} are not the first things in
 a declaration.  According to the C Standard, this usage is obsolescent.
 
-@item
-The return type of a function has a type qualifier such as @code{const}.
-Such a type qualifier has no effect, since the value returned by a
-function is not an lvalue.  (But don't warn about the GNU extension of
-@code{volatile void} return types.  That extension will be warned about
-if @option{-pedantic} is specified.)
-
 @item
 If @option{-Wall} or @option{-Wunused} is also specified, warn about unused
 arguments.
index b03d923cd217e499e656735be0fdb869e931213e..501da15db6f1850f68ec431a163743aa23f38849 100644 (file)
@@ -1,3 +1,13 @@
+2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk>
+
+       PR c/15052
+       * gcc.dg/noreturn-5.c: Test qualifiers on function type instead of
+       on return type.
+       * gcc.dg/qual-return-1.c: Use -Wreturn-type.  Update expected
+       messages.
+       * gcc.dg/qual-return-2.c: Update expected messages.
+       * gcc.dg/qual-return-3.c, gcc.dg/qual-return-4.c: New tests.
+
 2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * gcc.dg/c99-init-3.c, gcc.dg/gnu99-init-2.c: New tests.
index 07381a66d24402d963c849e15ffbcbfde094e9be..e69087a4d74fb4a2c2d04c4ca4e2e1d53d59c4b6 100644 (file)
@@ -4,4 +4,5 @@
    The testsuite uses -ansi -pedantic-errors by default, so this has
    to override.  */
 extern void xxx (int) __attribute__((noreturn));
-__volatile extern void xxx (int);
+typedef void voidfn (int);
+__volatile extern voidfn xxx;
index 5cab75c93d79a3b631547fbc98fc75226f98aabe..ac94df6d2bb0787479a504ea0a21bf60eeb81d49 100644 (file)
@@ -1,7 +1,7 @@
 /* Test for warnings for qualified function return types.  */
 /* Origin: Joseph Myers <jsm28@cam.ac.uk> */
 /* { dg-do compile } */
-/* { dg-options "-std=gnu99 -W" } */
+/* { dg-options "-std=gnu99 -Wreturn-type" } */
 
 /* Qualifying a function return type makes no sense.  */
 
@@ -11,13 +11,11 @@ const int int_fn2 (void) { return 0; } /* { dg-warning "qualifiers" "int defn" }
 
 const void void_fn (void); /* { dg-warning "qualifiers" "void decl" } */
 const void (*void_ptr) (void); /* { dg-warning "qualifiers" "void ptr" } */
-const void void_fn2 (void) { } /* { dg-warning "qualifiers" "void defn" } */
+const void void_fn2 (void) { } /* { dg-warning "qualified" "void defn" } */
 
-/* "volatile void" is a GNU extension, so only warn at -pedantic.  */
-
-volatile void vvoid_fn (void);
-volatile void (*vvoid_ptr) (void);
-volatile void vvoid_fn2 (void) { }
+volatile void vvoid_fn (void); /* { dg-warning "qualifiers" "void decl" } */
+volatile void (*vvoid_ptr) (void); /* { dg-warning "qualifiers" "void ptr" } */
+volatile void vvoid_fn2 (void) { } /* { dg-warning "qualified" "void defn" } */
 
 int *restrict ip_fn (void); /* { dg-warning "qualifiers" "restrict decl" } */
 int *restrict (*ip_ptr) (void); /* { dg-warning "qualifiers" "restrict ptr" } */
index 272787ee7c27a9807def63795f4e96205171db68..22a1946b03fe477e67ed6e409f48a735cb974c92 100644 (file)
@@ -5,10 +5,9 @@
 
 /* Qualifying a function return type makes no sense.  */
 
-/* "volatile void" is a GNU extension, so only warn at -pedantic.
-   Strictly, the first two of these should warn only if the function is
-   somewhere used or defined.  */
+/* The first two of these shouldn't warn (with just -pedantic) as long
+   as the function is not defined.  */
 
-volatile void vvoid_fn (void); /* { dg-warning "qualified" "volatile decl" } */
-volatile void (*vvoid_ptr) (void); /* { dg-warning "qualified" "volatile ptr" } */
+volatile void vvoid_fn (void);
+volatile void (*vvoid_ptr) (void);
 volatile void vvoid_fn2 (void) { } /* { dg-warning "qualified" "volatile defn" } */
diff --git a/gcc/testsuite/gcc.dg/qual-return-3.c b/gcc/testsuite/gcc.dg/qual-return-3.c
new file mode 100644 (file)
index 0000000..7a92046
--- /dev/null
@@ -0,0 +1,16 @@
+/* Test for warnings for qualified function return types.  Bug 15052
+   from Olatunji Ruwase (tjruwase at stanfordalumni.org): qualifiers
+   should not be lost when merging declarations.  */
+
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int foo (); /* { dg-error "previous declaration" "different qualifiers" } */
+const int foo () { return 0; } /* { dg-error "conflicting types" "different qualifiers" } */
+
+void bar (void);
+volatile void bar () { } /* { dg-warning "qualified|volatile" "different qualifiers" } */
+
+volatile void baz (void);
+void baz () { } /* { dg-warning "not compatible" "different qualifiers" } */
diff --git a/gcc/testsuite/gcc.dg/qual-return-4.c b/gcc/testsuite/gcc.dg/qual-return-4.c
new file mode 100644 (file)
index 0000000..9b61cfe
--- /dev/null
@@ -0,0 +1,10 @@
+/* Test for warnings for qualified function return types.  -pedantic
+   test.  Only the definition gets a warning for qualified void return
+   types, not other such types within the definition.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "-pedantic" } */
+
+volatile void (*y)(int);
+
+volatile void (*vvf(int x))(int) { return y; }