aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2023-11-09 09:50:54 +0100
committerFlorian Weimer <fweimer@redhat.com>2023-11-09 09:53:40 +0100
commit6e312b2b864bf923a9d772429f014375bf9dabc8 (patch)
tree42a9ab533a216f375efd9dbd5163482fe4738af8
parentf88b78b1196d71042cf129be7a0bf02b9a4de0d3 (diff)
downloadgcc-6e312b2b864bf923a9d772429f014375bf9dabc8.zip
gcc-6e312b2b864bf923a9d772429f014375bf9dabc8.tar.gz
gcc-6e312b2b864bf923a9d772429f014375bf9dabc8.tar.bz2
c: Add -Wreturn-mismatch warning, split from -Wreturn-type
The existing -Wreturn-type option covers both constraint violations (which are mandatory to diagnose) and warnings that have known false positives. The new -Wreturn-mismatch warning is only about the constraint violations (missing or extra return expressions), and should eventually be turned into a permerror. The -std=gnu89 test cases show that by default, we do not warn for return; in a function not returning void. This matches previous practice for -Wreturn-type. gcc/c-family/ * c.opt (Wreturn-mismatch): New. gcc/c/ * c-typeck.cc (c_finish_return): Use pedwarn with OPT_Wreturn_mismatch for missing/extra return expressions. gcc/ * doc/invoke.texi (Warning Options): Document -Wreturn-mismatch. Update -Wreturn-type documentation. gcc/testsuite/ * gcc.dg/Wreturn-mismatch-1.c: New. * gcc.dg/Wreturn-mismatch-2.c: New. * gcc.dg/Wreturn-mismatch-3.c: New. * gcc.dg/Wreturn-mismatch-4.c: New. * gcc.dg/Wreturn-mismatch-5.c: New. * gcc.dg/Wreturn-mismatch-6.c: New. * gcc.dg/noncompile/pr55976-1.c: Change -Werror=return-type to -Werror=return-mismatch. * gcc.dg/noncompile/pr55976-2.c: Change -Wreturn-type to -Wreturn-mismatch.
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/c-typeck.cc16
-rw-r--r--gcc/doc/invoke.texi37
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-mismatch-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c40
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c40
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c40
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-mismatch-6.c40
-rw-r--r--gcc/testsuite/gcc.dg/noncompile/pr55976-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/noncompile/pr55976-2.c4
11 files changed, 277 insertions, 27 deletions
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index d81177f..b10c605 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1271,6 +1271,10 @@ Wreorder
C++ ObjC++ Var(warn_reorder) Warning LangEnabledBy(C++ ObjC++,Wall)
Warn when the compiler reorders code.
+Wreturn-mismatch
+C ObjC Var(warn_return_mismatch) Warning Init(1)
+Warn whenever void-returning functions return a non-void expressions, or a return expression is missing in a function not returning void.
+
Wreturn-type
C ObjC C++ ObjC++ Var(warn_return_type) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Init(-1)
Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++).
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 4580ff0..dd5016a 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -11311,17 +11311,11 @@ c_finish_return (location_t loc, tree retval, tree origtype)
if ((warn_return_type >= 0 || flag_isoc99)
&& valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE)
{
- bool warned_here;
- if (flag_isoc99)
- warned_here = pedwarn
- (loc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
- "%<return%> with no value, in function returning non-void");
- else
- warned_here = warning_at
- (loc, OPT_Wreturn_type,
- "%<return%> with no value, in function returning non-void");
no_warning = true;
- if (warned_here)
+ if (emit_diagnostic (flag_isoc99 ? DK_PEDWARN : DK_WARNING,
+ loc, OPT_Wreturn_mismatch,
+ "%<return%> with no value,"
+ " in function returning non-void"))
inform (DECL_SOURCE_LOCATION (current_function_decl),
"declared here");
}
@@ -11332,7 +11326,7 @@ c_finish_return (location_t loc, tree retval, tree origtype)
bool warned_here;
if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
warned_here = pedwarn
- (xloc, warn_return_type >= 0 ? OPT_Wreturn_type : 0,
+ (xloc, OPT_Wreturn_mismatch,
"%<return%> with a value, in function returning void");
else
warned_here = pedwarn
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d0b55fb..1bf71ce 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -7350,22 +7350,33 @@ This warning is enabled by @option{-Wall} for C and C++.
Do not warn about returning a pointer (or in C++, a reference) to a
variable that goes out of scope after the function returns.
+@opindex Wreturn-mismatch
+@opindex Wno-return-mismatch
+@item -Wreturn-mismatch
+Warn about return statements without an expressions in functions which
+do not return @code{void}. Also warn about a @code{return} statement
+with an expression in a function whose return type is @code{void},
+unless the expression type is also @code{void}. As a GNU extension, the
+latter case is accepted without a warning unless @option{-Wpedantic} is
+used.
+
+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.
+
@opindex Wreturn-type
@opindex Wno-return-type
@item -Wreturn-type
-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}
-(falling off the end of the function body is considered returning
-without a value).
-
-For C only, warn about a @code{return} statement with an expression in a
-function whose return type is @code{void}, unless the expression type is
-also @code{void}. As a GNU extension, the latter case is accepted
-without a warning unless @option{-Wpedantic} is used. 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.
+Warn whenever a function is defined with a return type that defaults to
+@code{int} (unless @option{-Wimplicit-int} is active, which takes
+precedence). Also warn if execution may reach the end of the function
+body, or if the function does not contain any return statement at all.
+
+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.
Unlike in C, in C++, flowing off the end of a non-@code{void} function other
than @code{main} results in undefined behavior even when the value of
diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.c
new file mode 100644
index 0000000..3bad847
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-1.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-warning "'return' with a value\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+ return f1 (); /* { dg-bogus "ISO C" } */
+}
+
+int
+f6 (void)
+{
+ return; /* { dg-warning "'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
new file mode 100644
index 0000000..49eb5a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-2.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-warning "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+ return f1 ();
+}
+
+int
+f6 (void)
+{
+ return; /* { dg-warning "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/Wreturn-mismatch-3.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c
new file mode 100644
index 0000000..ee77ec6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-3.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-pedantic-errors" } */
+
+void f1 (void);
+
+int
+f2 (void)
+{
+ f1 ();
+}
+
+static inline int
+f3 (void)
+{
+ f1 ();
+}
+
+void
+f4 (void)
+{
+ return 1; /* { dg-error "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+ return f1 (); /* { dg-error "with expression, in function\[^\n\r\]*-Wpedantic" } */
+}
+
+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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c
new file mode 100644
index 0000000..f73e8a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-4.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu89" } */
+
+void f1 (void);
+
+int
+f2 (void)
+{
+ f1 ();
+}
+
+static inline int
+f3 (void)
+{
+ f1 ();
+}
+
+void
+f4 (void)
+{
+ return 1; /* { dg-warning "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+ return f1 ();
+}
+
+int
+f6 (void)
+{
+ return; /* { dg-bogus "with no value" } */
+}
+
+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-5.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c
new file mode 100644
index 0000000..f2fd329
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-5.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu89 -pedantic-errors" } */
+
+void f1 (void);
+
+int
+f2 (void)
+{
+ f1 ();
+}
+
+static inline int
+f3 (void)
+{
+ f1 ();
+}
+
+void
+f4 (void)
+{
+ return 1; /* { dg-error "with a value,\[^\n\r\]*-Wreturn-mismatch" } */
+}
+
+void
+f5 (void)
+{
+ return f1 (); /* { dg-error "with expression\[^\n\r\]*-Wpedantic" } */
+}
+
+int
+f6 (void)
+{
+ return;
+}
+
+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-6.c b/gcc/testsuite/gcc.dg/Wreturn-mismatch-6.c
new file mode 100644
index 0000000..51543fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-mismatch-6.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c90 -pedantic-errors -Wreturn-type" } */
+
+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 (); /* { dg-error "with expression\[^\n\r\]*-Wpedantic" } */
+}
+
+int
+f6 (void)
+{
+ return; /* { dg-warning "'return' 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/noncompile/pr55976-1.c b/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
index d078990..d348b03 100644
--- a/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
+++ b/gcc/testsuite/gcc.dg/noncompile/pr55976-1.c
@@ -1,6 +1,6 @@
/* PR c/55976 */
/* { dg-do compile } */
-/* { dg-options "-Werror=return-type" } */
+/* { dg-options "-Werror=return-mismatch" } */
/* { dg-prune-output "some warnings being treated as errors" } */
/* Verify warnings for return type become errors. */
diff --git a/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c b/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
index 0e493d0..d6f07a9 100644
--- a/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
+++ b/gcc/testsuite/gcc.dg/noncompile/pr55976-2.c
@@ -1,8 +1,8 @@
/* PR c/55976 */
/* { dg-do compile } */
-/* { dg-options "-Wno-return-type" } */
+/* { dg-options "-Wno-return-mismatch" } */
-/* Verify that -Wno-return-type turns off warnings about function return
+/* Verify that -Wno-return-mismatch turns off warnings about function return
type. */
void t () { return 1; } /* normally generates function returning void */