+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
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);
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))))
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);
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),
@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.
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.
+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.
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;
/* 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. */
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" } */
/* 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" } */
--- /dev/null
+/* 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" } */
--- /dev/null
+/* 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; }