From: Florian Weimer Date: Fri, 1 Dec 2023 07:10:13 +0000 (+0100) Subject: c: Turn -Wreturn-mismatch into a permerror X-Git-Tag: basepoints/gcc-15~4103 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ecfa6c4a9df19b364cbdf6d9de5f0b98c22bd8f;p=thirdparty%2Fgcc.git c: Turn -Wreturn-mismatch into a permerror gcc/ * doc/invoke.texi (Warning Options): Document that -Wreturn-mismatch is a permerror in C99 and later. gcc/c/ PR c/96284 * c-typeck.cc (c_finish_return): Use permerrors for OPT_Wreturn_mismatch diagnostics. gcc/testsuite/ * gcc.dg/permerror-default.c (return_mismatch_1) (return_mismatch_2): Expect new permerror. * gcc.dg/permerror-gnu89-nopermissive.c (return_mismatch_1): Likewise. * gcc.dg/permerror-system.c: Likewise. * gcc.dg/20030906-1.c: Compile with -fpermissive due to expected -Wreturn-mismatch error. * gcc.dg/20030906-1a.c: New test. Copied from gcc.dg/20030906-1.c. Expect the error. * gcc.dg/20030906-2.c: Compile with -fpermissive due to expected -Wreturn-mismatch error. * gcc.dg/20030906-2a.c: New test. Copied from gcc.dg/20030906-2.c. Expect the error. * gcc.dg/Wreturn-mismatch-1.c: Compile with -fpermissive due to expected -Wreturn-mismatch error. * gcc.dg/Wreturn-mismatch-1a.c: New test. Copied from gcc.dg/Wreturn-mismatch-1.c. Expect the error. * gcc.dg/Wreturn-mismatch-2.c: Compile with -fpermissive due to expected -Wreturn-mismatch error. * gcc.dg/Wreturn-mismatch-2a.c: New test. Copied from gcc.dg/Wreturn-mismatch-2.c. Expect the error. * gcc.dg/diagnostic-range-bad-return.c: Compile with -fpermissive due to expected -Wreturn-mismatch error. * gcc.dg/diagnostic-range-bad-return-2.c: New test. Copied from gcc.dg/diagnostic-range-bad-return.c. Expect the error. * gcc.dg/pr105635-2.c: Expect -Wreturn-mismatch error. * gcc.dg/pr23075.c: Build with -fpermissive due to expected -Wreturn-mismatch error. * gcc.dg/pr23075-2.c: New test. Copied from gcc.dg/pr23075.c. Expect the error. * gcc.dg/pr29521.c: Compile with -fpermissive due to expected -Wreturn-mismatch error. * gcc.dg/pr29521-a.c: New test. Copied from gcc.dg/pr29521.c. Expect error. * gcc.dg/pr67730.c: Compile with -fpermissive due to expected -Wreturn-mismatch error. * gcc.dg/pr67730-a.c: New test. Copied from gcc.dg/pr67730-a.c. Expect error. * gcc.target/powerpc/conditional-return.c: Compile with -fpermissive due to expected -Wreturn-mismatch error. --- diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index b309300ba336..b03532aee342 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -11234,7 +11234,7 @@ c_finish_return (location_t loc, tree retval, tree origtype) && valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE) { no_warning = true; - if (emit_diagnostic (flag_isoc99 ? DK_PEDWARN : DK_WARNING, + if (emit_diagnostic (flag_isoc99 ? DK_PERMERROR : DK_WARNING, loc, OPT_Wreturn_mismatch, "% with no value," " in function returning non-void")) @@ -11247,7 +11247,7 @@ c_finish_return (location_t loc, tree retval, tree origtype) current_function_returns_null = 1; bool warned_here; if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) - warned_here = pedwarn + warned_here = permerror_opt (xloc, OPT_Wreturn_mismatch, "% with a value, in function returning void"); else diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 51bf19db73ae..2b55a1c056c6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6188,6 +6188,7 @@ that have their own flag: -Wimplicit-int @r{(C and Objective-C only)} -Wint-conversion @r{(C and Objective-C only)} -Wnarrowing @r{(C++)} +-Wreturn-mismatch @r{(C and Objective-C only)} } The @option{-fpermissive} option is the default for historic C language @@ -7390,7 +7391,10 @@ Attempting to use the return value of a non-@code{void} function other than @code{main} that flows off the end by reaching the closing curly brace that terminates the function is undefined. -This warning is specific to C and enabled by default. +This warning is specific to C and enabled by default. In C99 and later +language dialects, it is treated as an error. It can be downgraded +to a warning using @option{-fpermissive} (along with other warnings), +or for just this warning, with @option{-Wno-error=return-mismatch}. @opindex Wreturn-type @opindex Wno-return-type diff --git a/gcc/testsuite/gcc.dg/20030906-1.c b/gcc/testsuite/gcc.dg/20030906-1.c index c416f55ee75b..6ba5b3d770a5 100644 --- a/gcc/testsuite/gcc.dg/20030906-1.c +++ b/gcc/testsuite/gcc.dg/20030906-1.c @@ -2,7 +2,7 @@ Copyright (C) 2003 Free Software Foundation Inc. */ /* { dg-do compile } */ -/* { dg-options "-O -finline-functions -Wreturn-type" } */ +/* { dg-options "-fpermissive -O -finline-functions -Wreturn-type" } */ extern int i; extern int foo (void); diff --git a/gcc/testsuite/gcc.dg/20030906-1a.c b/gcc/testsuite/gcc.dg/20030906-1a.c new file mode 100644 index 000000000000..46ca1771a4de --- /dev/null +++ b/gcc/testsuite/gcc.dg/20030906-1a.c @@ -0,0 +1,21 @@ +/* Bug 9862 -- Spurious warnings with -finline-functions. + Copyright (C) 2003 Free Software Foundation Inc. */ + +/* { dg-do compile } */ +/* { dg-options "-O -finline-functions -Wreturn-type" } */ + +extern int i; +extern int foo (void); +extern int bar (void); + +int foo (void) +{ + if( i ) return 0; + else return 1; +} + +int bar (void) +{ + if( i ) return; /* { dg-error "'return' with no value, in function returning non-void" } */ + else return 1; +} diff --git a/gcc/testsuite/gcc.dg/20030906-2.c b/gcc/testsuite/gcc.dg/20030906-2.c index 1191133e6a06..a85d91f46f3e 100644 --- a/gcc/testsuite/gcc.dg/20030906-2.c +++ b/gcc/testsuite/gcc.dg/20030906-2.c @@ -2,7 +2,7 @@ Copyright (C) 2003 Free Software Foundation Inc. */ /* { dg-do compile } */ -/* { dg-options "-O -finline-functions -Wreturn-type" } */ +/* { dg-options "-fpermissive -O -finline-functions -Wreturn-type" } */ extern int i; extern int foo (void); diff --git a/gcc/testsuite/gcc.dg/20030906-2a.c b/gcc/testsuite/gcc.dg/20030906-2a.c new file mode 100644 index 000000000000..a6ffbacb46d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20030906-2a.c @@ -0,0 +1,21 @@ +/* Bug 9862 -- Spurious warnings with -finline-functions. + Copyright (C) 2003 Free Software Foundation Inc. */ + +/* { dg-do compile } */ +/* { dg-options "-O -finline-functions -Wreturn-type" } */ + +extern int i; +extern int foo (void); +extern int bar (void); + +int foo (void) +{ + if( i ) return; /* { dg-error "'return' with no value, in function returning non-void" } */ + else return 1; +} + +int bar (void) +{ + if( i ) return 0; + else return 1; +} diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c index 3bad847ecf7a..aef6782cbeb5 100644 --- a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "" } */ +/* { dg-options "-fpermissive" } */ void f1 (void); diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c new file mode 100644 index 000000000000..70c7c9ddb86b --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void f1 (void); + +int +f2 (void) +{ + f1 (); +} + +static inline int +f3 (void) +{ + f1 (); +} + +void +f4 (void) +{ + return 1; /* { dg-error "'return' with a value\[^\n\r\]*-Wreturn-mismatch" } */ +} + +void +f5 (void) +{ + return f1 (); /* { dg-bogus "ISO C" } */ +} + +int +f6 (void) +{ + return; /* { dg-error "'return' with no value\[^\n\r\]*-Wreturn-mismatch" } */ +} + +int +f7 (void) +{ + return f1 (); /* { dg-error "void value not ignored as it ought to be" } */ +} diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c index 49eb5a5a95c5..08811024b7e5 100644 --- a/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-Wall" } */ +/* { dg-options "-fpermissive -Wall" } */ void f1 (void); diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c new file mode 100644 index 000000000000..836651ed9257 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +void f1 (void); + +int +f2 (void) +{ + f1 (); +} /* { dg-warning "control reaches end of non-void\[^\n\r\]*-Wreturn-type" } */ + +static inline int +f3 (void) +{ + f1 (); +} /* { dg-warning "no return statement in function\[^\n\r\]*-Wreturn-type" } */ + +void +f4 (void) +{ + return 1; /* { dg-error "with a value,\[^\n\r\]*-Wreturn-mismatch" } */ +} + +void +f5 (void) +{ + return f1 (); +} + +int +f6 (void) +{ + return; /* { dg-error "with no value,\[^\n\r\]*Wreturn-mismatch" } */ +} + +int +f7 (void) +{ + return f1 (); /* { dg-error "void value not ignored as it ought to be" } */ +} /* { dg-warning "control reaches end of non-void\[^\n\r\]*-Wreturn-type" } */ + diff --git a/gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c new file mode 100644 index 000000000000..2fe8d341dba5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c @@ -0,0 +1,52 @@ +/* { dg-options "-fdiagnostics-show-caret -Wreturn-local-addr" } */ + +int *address_of_local (void) +{ + int some_local; + return &some_local; /* { dg-warning "function returns address of local variable" } */ +/* { dg-begin-multiline-output "" } + return &some_local; + ^~~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +void surplus_return_when_void_1 (void) +{ + return 500; /* { dg-error "'return' with a value, in function returning void" } */ +/* { dg-begin-multiline-output "" } + return 500; + ^~~ + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + void surplus_return_when_void_1 (void) + ^~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +void surplus_return_when_void_2 (int i, int j) +{ + return i * j; /* { dg-error "'return' with a value, in function returning void" } */ +/* { dg-begin-multiline-output "" } + return i * j; + ~~^~~ + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + void surplus_return_when_void_2 (int i, int j) + ^~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +int missing_return_value (void) +{ + return; /* { dg-error "'return' with no value, in function returning non-void" } */ +/* { dg-begin-multiline-output "" } + return; + ^~~~~~ + { dg-end-multiline-output "" } */ +/* { dg-begin-multiline-output "" } + int missing_return_value (void) + ^~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +/* TODO: ideally we'd underline the return type i.e. "int", but that + location isn't captured. */ +} diff --git a/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c index 063fdf1f6360..b74481b870c7 100644 --- a/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c +++ b/gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c @@ -1,4 +1,4 @@ -/* { dg-options "-fdiagnostics-show-caret -Wreturn-local-addr" } */ +/* { dg-options "-fpermissive -fdiagnostics-show-caret -Wreturn-local-addr" } */ int *address_of_local (void) { diff --git a/gcc/testsuite/gcc.dg/permerror-default.c b/gcc/testsuite/gcc.dg/permerror-default.c index 90f2220037c5..9ed9814d69e0 100644 --- a/gcc/testsuite/gcc.dg/permerror-default.c +++ b/gcc/testsuite/gcc.dg/permerror-default.c @@ -75,11 +75,11 @@ incompatible_pointer_types (int flag) void return_mismatch_1 (void) { - return 0; /* { dg-warning "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */ + return 0; /* { dg-error "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */ } int return_mismatch_2 (void) { - return; /* { dg-warning "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" } */ + return; /* { dg-error "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" } */ } diff --git a/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c b/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c index 0780e42b5cca..dc282a44489d 100644 --- a/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c +++ b/gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c @@ -75,7 +75,7 @@ incompatible_pointer_types (int flag) void return_mismatch_1 (void) { - return 0; /* { dg-warning "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */ + return 0; /* { dg-error "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" } */ } int diff --git a/gcc/testsuite/gcc.dg/permerror-system.c b/gcc/testsuite/gcc.dg/permerror-system.c index cad48c93f909..f00420358d94 100644 --- a/gcc/testsuite/gcc.dg/permerror-system.c +++ b/gcc/testsuite/gcc.dg/permerror-system.c @@ -27,3 +27,6 @@ /* { dg-error "initialization of 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 45 } */ /* { dg-error "assignment to 'int \\\*' from 'int' makes pointer from integer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 46 } */ /* { dg-error "returning 'int \\\*' from a function with return type 'int' makes integer from pointer without a cast \\\[-Wint-conversion\\\]" "" { target *-*-* } 48 } */ + +/* { dg-error "'return' with a value, in function returning void \\\[-Wreturn-mismatch\\\]" "" { target *-*-* } 78 } */ +/* { dg-error "return' with no value, in function returning non-void \\\[-Wreturn-mismatch\\\]" "" { target *-*-* } 84 } */ diff --git a/gcc/testsuite/gcc.dg/pr105635-2.c b/gcc/testsuite/gcc.dg/pr105635-2.c index 807eef0b7cdb..019dbc7e557f 100644 --- a/gcc/testsuite/gcc.dg/pr105635-2.c +++ b/gcc/testsuite/gcc.dg/pr105635-2.c @@ -7,5 +7,5 @@ void foo (int, int[*]); /* { dg-message "previous declaration of 'foo' with type foo (int x, int y) /* { dg-error "return type defaults to 'int'" } */ { /* { dg-warning "conflicting types for 'foo'" "" { target *-*-* } .-1 } */ /* { dg-message "declared here" "" { target *-*-* } .-2 } */ - return (x >= 0) != (y < 0); /* { dg-warning "'return' with a value, in function returning void" } */ + return (x >= 0) != (y < 0); /* { dg-error "'return' with a value, in function returning void" } */ } diff --git a/gcc/testsuite/gcc.dg/pr23075-2.c b/gcc/testsuite/gcc.dg/pr23075-2.c new file mode 100644 index 000000000000..0702ddf1a660 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr23075-2.c @@ -0,0 +1,14 @@ +/* PR c/23075 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wreturn-type" } */ + +int +foo (void) +{ + return; /* { dg-error "with no value" } */ +} /* { dg-bogus "control reaches end" } */ + +int +bar (void) +{ +} /* { dg-warning "control reaches end" } */ diff --git a/gcc/testsuite/gcc.dg/pr23075.c b/gcc/testsuite/gcc.dg/pr23075.c index 2d85fb0650fd..28baf41006a3 100644 --- a/gcc/testsuite/gcc.dg/pr23075.c +++ b/gcc/testsuite/gcc.dg/pr23075.c @@ -1,6 +1,6 @@ /* PR c/23075 */ /* { dg-do compile } */ -/* { dg-options "-O2 -Wreturn-type" } */ +/* { dg-options "-O2 -fpermissive -Wreturn-type" } */ int foo (void) diff --git a/gcc/testsuite/gcc.dg/pr29521-a.c b/gcc/testsuite/gcc.dg/pr29521-a.c new file mode 100644 index 000000000000..2c6a48b7e300 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr29521-a.c @@ -0,0 +1,15 @@ +/* PR 29521 : warning for return with expression in function returning void */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void func (void) { } + +void func2 (void) +{ + return func (); +} + +void func3 (void) +{ + return 1; /* { dg-error "'return' with a value" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr29521.c b/gcc/testsuite/gcc.dg/pr29521.c index b6fb535fab7e..cd431514ed2e 100644 --- a/gcc/testsuite/gcc.dg/pr29521.c +++ b/gcc/testsuite/gcc.dg/pr29521.c @@ -1,6 +1,6 @@ /* PR 29521 : warning for return with expression in function returning void */ /* { dg-do compile } */ -/* { dg-options "" } */ +/* { dg-options "-fpermissive" } */ void func (void) { } diff --git a/gcc/testsuite/gcc.dg/pr67730-a.c b/gcc/testsuite/gcc.dg/pr67730-a.c new file mode 100644 index 000000000000..08737cc98110 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr67730-a.c @@ -0,0 +1,11 @@ +/* PR c/67730 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +#include + +void +fn1 (void) +{ + return NULL; /* { dg-error "10:.return. with a value" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr67730.c b/gcc/testsuite/gcc.dg/pr67730.c index 54d73a62cf86..cc51858c5315 100644 --- a/gcc/testsuite/gcc.dg/pr67730.c +++ b/gcc/testsuite/gcc.dg/pr67730.c @@ -1,6 +1,6 @@ /* PR c/67730 */ /* { dg-do compile } */ -/* { dg-options "" } */ +/* { dg-options "-fpermissive" } */ #include diff --git a/gcc/testsuite/gcc.target/powerpc/conditional-return.c b/gcc/testsuite/gcc.target/powerpc/conditional-return.c index 6b3ef5f52ca8..c6491216752b 100644 --- a/gcc/testsuite/gcc.target/powerpc/conditional-return.c +++ b/gcc/testsuite/gcc.target/powerpc/conditional-return.c @@ -1,7 +1,7 @@ /* Check that a conditional return is used. */ /* { dg-do compile } */ -/* { dg-options "-O2 -w" } */ +/* { dg-options "-O2 -fpermissive -w" } */ /* { dg-final { scan-assembler {\mbeqlr\M} } } */