]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: Turn -Wreturn-mismatch into a permerror
authorFlorian Weimer <fweimer@redhat.com>
Fri, 1 Dec 2023 07:10:13 +0000 (08:10 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Fri, 1 Dec 2023 07:10:13 +0000 (08:10 +0100)
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.

23 files changed:
gcc/c/c-typeck.cc
gcc/doc/invoke.texi
gcc/testsuite/gcc.dg/20030906-1.c
gcc/testsuite/gcc.dg/20030906-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/20030906-2.c
gcc/testsuite/gcc.dg/20030906-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c
gcc/testsuite/gcc.dg/Wreturn-mismatch-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c
gcc/testsuite/gcc.dg/Wreturn-mismatch-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/diagnostic-range-bad-return-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/diagnostic-range-bad-return.c
gcc/testsuite/gcc.dg/permerror-default.c
gcc/testsuite/gcc.dg/permerror-gnu89-nopermissive.c
gcc/testsuite/gcc.dg/permerror-system.c
gcc/testsuite/gcc.dg/pr105635-2.c
gcc/testsuite/gcc.dg/pr23075-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr23075.c
gcc/testsuite/gcc.dg/pr29521-a.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr29521.c
gcc/testsuite/gcc.dg/pr67730-a.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr67730.c
gcc/testsuite/gcc.target/powerpc/conditional-return.c

index b309300ba33681470870d61eb9a8bf555a191e7d..b03532aee3429a63c3bd297b92c47f07564d5569 100644 (file)
@@ -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,
                               "%<return%> 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,
           "%<return%> with a value, in function returning void");
       else
index 51bf19db73aeeed34983d0f8aa677229fb24e533..2b55a1c056c62a2f61b210edabbcbc077c3599c5 100644 (file)
@@ -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
index c416f55ee75bbcde27f58295ae069b4ef0a94e9b..6ba5b3d770a588ac73c8320790ad1245c1b79c40 100644 (file)
@@ -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 (file)
index 0000000..46ca177
--- /dev/null
@@ -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;
+}              
index 1191133e6a06d9563d5e8f7dc2d09134f5725195..a85d91f46f3ec0725017410dbe3ae24af4255792 100644 (file)
@@ -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 (file)
index 0000000..a6ffbac
--- /dev/null
@@ -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;
+}
index 3bad847ecf7af099b95fcb48b4c58a2a9c6eee48..aef6782cbeb58e7611db2a30b00a0a96c0bdbec4 100644 (file)
@@ -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 (file)
index 0000000..70c7c9d
--- /dev/null
@@ -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" } */
+}
index 49eb5a5a95c5f396479ef3bf8fdb85e137d1388c..08811024b7e52cdcaad90c7e73bbcb35629532ad 100644 (file)
@@ -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 (file)
index 0000000..836651e
--- /dev/null
@@ -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 (file)
index 0000000..2fe8d34
--- /dev/null
@@ -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.  */
+}
index 063fdf1f6360b38177691836e519c6fbad521be6..b74481b870c7b963ce6c97b7cf173e3535283480 100644 (file)
@@ -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)
 {
index 90f2220037c59000e65196eb688b89bbdd2cffd4..9ed9814d69e0cc7b60ebf0d8b91ca84cff066eff 100644 (file)
@@ -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\\\]" } */
 }
index 0780e42b5ccaa0b5fcd6d50d24a2a94201338ccd..dc282a44489da8a867b30222578ae1a5b000fc1f 100644 (file)
@@ -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
index cad48c93f909486ac1104ad39e5b0507f0b1e9de..f00420358d94c55161c40a2128dbb2f674f7c23c 100644 (file)
@@ -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 } */
index 807eef0b7cdb49d638c1464d2dabaf484f0875a7..019dbc7e557ff84a4a8d81d17ec188753b577f1c 100644 (file)
@@ -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 (file)
index 0000000..0702ddf
--- /dev/null
@@ -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" } */
index 2d85fb0650fd9573df59f6d119df9870be23c3b6..28baf41006a3394ea06a28523b168f2ff478ee92 100644 (file)
@@ -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 (file)
index 0000000..2c6a48b
--- /dev/null
@@ -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" } */
+}
index b6fb535fab7ed1ea8431fbd3a1eca1fa56440199..cd431514ed2e738348cdea4f8320f8daf68df3df 100644 (file)
@@ -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 (file)
index 0000000..08737cc
--- /dev/null
@@ -0,0 +1,11 @@
+/* PR c/67730 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#include <stddef.h>
+
+void
+fn1 (void)
+{
+  return NULL; /* { dg-error "10:.return. with a value" } */
+}
index 54d73a62cf86a82b2fd5da167c80f39a70c8eda4..cc51858c531562f0a5b2165c94105d3bc415951c 100644 (file)
@@ -1,6 +1,6 @@
 /* PR c/67730 */
 /* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-fpermissive" } */
 
 #include <stddef.h>
 
index 6b3ef5f52ca8371a491059cca530e0a7e2085f5d..c6491216752bb558c39223417949c1829f837656 100644 (file)
@@ -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} } } */