PoC: add -Wunused-result=strict
Checks
Commit Message
As requested in <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c41>,
this is a proof-of-concept patch to change -Wunused-result to not warn
about return values explicitly discarded by casting to void, and add
-Wunused-result=strict for the current behavior (warn even on void casts).
The core behavior change is based on an earlier patch at
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509#c10>; it appears to
do the correct thing based on the tests added by the patch, but it also
breaks a number of other attribute- and analyzer-related tests, so some
fine-tuning is probably needed (and I don't have the GCC internals
knowledge to know where to start).
I haven't touched [[nodiscard]] behavior, since GCC already ignores
explicit discards in that case; for consistency's sake, it might make
sense to also warn for explicitly discarded [[nodiscard]] values with
-Wunused-result=strict.
Please CC me on any replies, as I am not subscribed to the list.
--Andrew Church
https://achurch.org/
@@ -1361,6 +1361,10 @@
C ObjC C++ ObjC++ Var(warn_unused_result) Init(1) Warning
Warn if a caller of a function, marked with attribute warn_unused_result, does not use its return value.
+Wunused-result=strict
+C ObjC C++ ObjC++ RejectNegative Var(warn_unused_result,2) Init(1) Warning
+Warn if a caller of a function, marked with attribute warn_unused_result, does not use its return value.
+
Wunused-variable
C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wunused)
; documented in common.opt
@@ -406,7 +406,7 @@
-Wunused-const-variable -Wunused-const-variable=@var{n} @gol
-Wunused-function -Wunused-label -Wunused-local-typedefs @gol
-Wunused-macros @gol
--Wunused-parameter -Wno-unused-result @gol
+-Wunused-parameter -Wunused-result -Wunused-result=strict @gol
-Wunused-value -Wunused-variable @gol
-Wno-varargs -Wvariadic-macros @gol
-Wvector-operation-performance @gol
@@ -7037,12 +7037,20 @@
To suppress this warning use the @code{unused} attribute
(@pxref{Variable Attributes}).
-@item -Wno-unused-result
+@item -Wunused-result
@opindex Wunused-result
@opindex Wno-unused-result
-Do not warn if a caller of a function marked with attribute
+Warn if a caller of a function marked with attribute
@code{warn_unused_result} (@pxref{Function Attributes}) does not use
-its return value. The default is @option{-Wunused-result}.
+its return value, unless the return value is explicitly discarded with a
+cast to @code{void}. This warning is enabled by default.
+
+@item -Wunused-result=strict
+@opindex Wunused-result=strict
+Warn if a caller of a function marked with attribute
+@code{warn_unused_result} (@pxref{Function Attributes}) does not use
+its return value, even if the return value is explicitly discarded with
+a cast to @code{void}.
@item -Wunused-variable
@opindex Wunused-variable
@@ -15183,10 +15183,18 @@
|| fallback == fb_none)
{
/* Just strip a conversion to void (or in void context) and
- try again. */
- *expr_p = TREE_OPERAND (*expr_p, 0);
- ret = GS_OK;
- break;
+ try again. But if this is a function call cast to void
+ and strict unused-result warnings are not enabled,
+ preserve the cast so that do_warn_unused_result() knows
+ not to emit a warning. */
+ if (!(warn_unused_result == 1
+ && TREE_CODE (TREE_OPERAND (*expr_p, 0)) == CALL_EXPR
+ && VOID_TYPE_P (TREE_TYPE (*expr_p))))
+ {
+ *expr_p = TREE_OPERAND (*expr_p, 0);
+ ret = GS_OK;
+ break;
+ }
}
ret = gimplify_conversion (expr_p);
@@ -1,6 +1,6 @@
/* warn_unused_result attribute tests. */
/* { dg-do compile } */
-/* { dg-options "-O -ftrack-macro-expansion=0" } */
+/* { dg-options "-O -ftrack-macro-expansion=0 -Wunused-result=strict" } */
#define WUR __attribute__((warn_unused_result))
#define WURAI __attribute__((warn_unused_result, always_inline)) inline
@@ -0,0 +1,11 @@
+/* Test for -Wno-unused-result inhibiting all unused-result warnings.
+ { dg-do compile }
+ { dg-options "-Wno-unused-result" } */
+
+__attribute__ ((warn_unused_result)) int fwur (void);
+
+void wur (void)
+{
+ fwur (); // no warning
+ (void) fwur (); // no warning
+}
@@ -0,0 +1,12 @@
+/* Test for -Wunused-result inhibiting unused-result warnings when the
+ value is explicitly cast to void.
+ { dg-do compile }
+ { dg-options "-Wunused-result" } */
+
+__attribute__ ((warn_unused_result)) int fwur (void);
+
+void wur (void)
+{
+ fwur (); // { dg-warning "\\\[-Wunused-result" }
+ (void) fwur (); // no warning
+}
@@ -0,0 +1,12 @@
+/* Test for -Wunused-result=strict emitting unused-result warnings even
+ when the value is explicitly cast to void.
+ { dg-do compile }
+ { dg-options "-Wunused-result=strict" } */
+
+__attribute__ ((warn_unused_result)) int fwur (void);
+
+void wur (void)
+{
+ fwur (); // { dg-warning "\\\[-Wunused-result" }
+ (void) fwur (); // { dg-warning "\\\[-Wunused-result" }
+}