From e508a0190bcea40145bd040532cdcce39cd22fcb Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 22 Jul 2004 01:00:47 +0100 Subject: [PATCH] re PR c/15052 (gcc frontend accepts mismatched function declaration/defintion) 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 | 14 +++++++++++++ gcc/c-decl.c | 30 +++++++++++----------------- gcc/c-typeck.c | 6 +++--- gcc/doc/invoke.texi | 13 ++++++------ gcc/testsuite/ChangeLog | 10 ++++++++++ gcc/testsuite/gcc.dg/noreturn-5.c | 3 ++- gcc/testsuite/gcc.dg/qual-return-1.c | 12 +++++------ gcc/testsuite/gcc.dg/qual-return-2.c | 9 ++++----- gcc/testsuite/gcc.dg/qual-return-3.c | 16 +++++++++++++++ gcc/testsuite/gcc.dg/qual-return-4.c | 10 ++++++++++ 10 files changed, 82 insertions(+), 41 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/qual-return-3.c create mode 100644 gcc/testsuite/gcc.dg/qual-return-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 00f2261e63f..41622fb420b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2004-07-22 Joseph S. Myers + + 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 * c-typeck.c (set_init_index): Require designator to be of integer diff --git a/gcc/c-decl.c b/gcc/c-decl.c index c5b50a26312..ac812e3dea7 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 04ed0684dbe..8d201cdbda5 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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), diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 43f2df66ddb..efd20a97eed 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b03d923cd21..501da15db6f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2004-07-22 Joseph S. Myers + + 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 * gcc.dg/c99-init-3.c, gcc.dg/gnu99-init-2.c: New tests. diff --git a/gcc/testsuite/gcc.dg/noreturn-5.c b/gcc/testsuite/gcc.dg/noreturn-5.c index 07381a66d24..e69087a4d74 100644 --- a/gcc/testsuite/gcc.dg/noreturn-5.c +++ b/gcc/testsuite/gcc.dg/noreturn-5.c @@ -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; diff --git a/gcc/testsuite/gcc.dg/qual-return-1.c b/gcc/testsuite/gcc.dg/qual-return-1.c index 5cab75c93d7..ac94df6d2bb 100644 --- a/gcc/testsuite/gcc.dg/qual-return-1.c +++ b/gcc/testsuite/gcc.dg/qual-return-1.c @@ -1,7 +1,7 @@ /* Test for warnings for qualified function return types. */ /* Origin: Joseph Myers */ /* { 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" } */ diff --git a/gcc/testsuite/gcc.dg/qual-return-2.c b/gcc/testsuite/gcc.dg/qual-return-2.c index 272787ee7c2..22a1946b03f 100644 --- a/gcc/testsuite/gcc.dg/qual-return-2.c +++ b/gcc/testsuite/gcc.dg/qual-return-2.c @@ -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 index 00000000000..7a92046da81 --- /dev/null +++ b/gcc/testsuite/gcc.dg/qual-return-3.c @@ -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 */ +/* { 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 index 00000000000..9b61cfebf12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/qual-return-4.c @@ -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 */ +/* { dg-do compile } */ +/* { dg-options "-pedantic" } */ + +volatile void (*y)(int); + +volatile void (*vvf(int x))(int) { return y; } -- 2.30.2