diff -urN gcc-16.1.0-orig/gcc/c-family/c.opt gcc-16.1.0/gcc/c-family/c.opt --- gcc-16.1.0-orig/gcc/c-family/c.opt 2026-04-30 17:33:20 +0900 +++ gcc-16.1.0/gcc/c-family/c.opt 2026-05-07 23:30:56 +0900 @@ -1624,6 +1624,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 diff -urN gcc-16.1.0-orig/gcc/doc/invoke.texi gcc-16.1.0/gcc/doc/invoke.texi --- gcc-16.1.0-orig/gcc/doc/invoke.texi 2026-04-30 17:33:20 +0900 +++ gcc-16.1.0/gcc/doc/invoke.texi 2026-05-07 23:32:23 +0900 @@ -464,7 +464,7 @@ -Wunused-const-variable -Wunused-const-variable=@var{n} -Wunused-function -Wunused-label -Wunused-local-typedefs -Wunused-macros --Wunused-parameter -Wno-unused-result +-Wunused-parameter -Wunused-result -Wunused-result=strict -Wunused-value -Wunused-variable -Wuse-after-free -Wuse-after-free=@var{n} -Wuseless-cast -Wno-varargs -Wvariadic-macros @@ -8365,10 +8365,18 @@ @opindex Wunused-result @opindex Wno-unused-result -@item -Wno-unused-result -Do not warn if a caller of a function marked with attribute +@item -Wunused-result +Warn if a caller of a function marked with attribute @code{warn_unused_result} (@pxref{Common 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. + +@opindex Wunused-result=strict +@item -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}. @opindex Wunused-variable @opindex Wno-unused-variable diff -urN gcc-16.1.0-orig/gcc/gimplify.cc gcc-16.1.0/gcc/gimplify.cc --- gcc-16.1.0-orig/gcc/gimplify.cc 2026-04-30 17:33:20 +0900 +++ gcc-16.1.0/gcc/gimplify.cc 2026-05-07 23:30:56 +0900 @@ -20564,10 +20564,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); diff -urN gcc-16.1.0-orig/gcc/testsuite/c-c++-common/attr-warn-unused-result.c gcc-16.1.0/gcc/testsuite/c-c++-common/attr-warn-unused-result.c --- gcc-16.1.0-orig/gcc/testsuite/c-c++-common/attr-warn-unused-result.c 2026-04-30 17:33:21 +0900 +++ gcc-16.1.0/gcc/testsuite/c-c++-common/attr-warn-unused-result.c 2026-05-07 23:30:56 +0900 @@ -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 diff -urN gcc-16.1.0-orig/gcc/testsuite/gcc.dg/Wunused-result-2.c gcc-16.1.0/gcc/testsuite/gcc.dg/Wunused-result-2.c --- gcc-16.1.0-orig/gcc/testsuite/gcc.dg/Wunused-result-2.c 1970-01-01 09:00:00 +0900 +++ gcc-16.1.0/gcc/testsuite/gcc.dg/Wunused-result-2.c 2026-05-07 23:30:56 +0900 @@ -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 +} diff -urN gcc-16.1.0-orig/gcc/testsuite/gcc.dg/Wunused-result-3.c gcc-16.1.0/gcc/testsuite/gcc.dg/Wunused-result-3.c --- gcc-16.1.0-orig/gcc/testsuite/gcc.dg/Wunused-result-3.c 1970-01-01 09:00:00 +0900 +++ gcc-16.1.0/gcc/testsuite/gcc.dg/Wunused-result-3.c 2026-05-07 23:30:56 +0900 @@ -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 +} diff -urN gcc-16.1.0-orig/gcc/testsuite/gcc.dg/Wunused-result-4.c gcc-16.1.0/gcc/testsuite/gcc.dg/Wunused-result-4.c --- gcc-16.1.0-orig/gcc/testsuite/gcc.dg/Wunused-result-4.c 1970-01-01 09:00:00 +0900 +++ gcc-16.1.0/gcc/testsuite/gcc.dg/Wunused-result-4.c 2026-05-07 23:30:56 +0900 @@ -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" } +}