https://gcc.gnu.org/g:32ff6f4728e4021ff33fb1da6eb3bafe3ea5a15e
commit r16-2280-g32ff6f4728e4021ff33fb1da6eb3bafe3ea5a15e Author: Jeremy Rifkin <jer...@rifkin.dev> Date: Tue Jul 15 18:17:01 2025 -0400 c, c++: Fix unused result for empty types [PR82134] Hi, This fixes PR c/82134 which concerns gcc emitting an incorrect unused result diagnostic for empty types. This diagnostic is emitted from tree-cfg.cc because of a couple code paths which attempt to avoid copying empty types, resulting in GIMPLE that isn't using the returned value of a call. To fix this I've added suppress_warning in three locations and a corresponding check in do_warn_unused_result. Cheers, Jeremy PR c/82134 gcc/cp/ChangeLog: * call.cc (build_call_a): Add suppress_warning * cp-gimplify.cc (cp_gimplify_expr): Add suppress_warning gcc/ChangeLog: * gimplify.cc (gimplify_modify_expr): Add suppress_warning * tree-cfg.cc (do_warn_unused_result): Check warning_suppressed_p gcc/testsuite/ChangeLog: * c-c++-common/attr-warn-unused-result-2.c: New test. Signed-off-by: Jeremy Rifkin <jer...@rifkin.dev> Diff: --- gcc/cp/call.cc | 1 + gcc/cp/cp-gimplify.cc | 1 + gcc/gimplify.cc | 1 + gcc/testsuite/c-c++-common/attr-warn-unused-result-2.c | 16 ++++++++++++++++ gcc/tree-cfg.cc | 2 ++ 5 files changed, 21 insertions(+) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 26296255b1ec..37ad0a977c22 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -412,6 +412,7 @@ build_call_a (tree function, int n, tree *argarray) /* We're disconnecting the initializer from its target, don't create a temporary. */ arg = TARGET_EXPR_INITIAL (arg); + suppress_warning (arg, OPT_Wunused_result); tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (arg)); arg = build2 (COMPOUND_EXPR, TREE_TYPE (t), arg, t); CALL_EXPR_ARG (function, i) = arg; diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index d54fe347a6ca..4ff8f36a9fb6 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -690,6 +690,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) && (REFERENCE_CLASS_P (op1) || DECL_P (op1))) op1 = build_fold_addr_expr (op1); + suppress_warning (op1, OPT_Wunused_result); gimplify_and_add (op1, pre_p); } gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 9f9ff92d0642..fa9890e7cea0 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -7305,6 +7305,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p)) && TREE_CODE (*from_p) == CALL_EXPR)) { + suppress_warning (*from_p, OPT_Wunused_result); gimplify_stmt (from_p, pre_p); gimplify_stmt (to_p, pre_p); *expr_p = NULL_TREE; diff --git a/gcc/testsuite/c-c++-common/attr-warn-unused-result-2.c b/gcc/testsuite/c-c++-common/attr-warn-unused-result-2.c new file mode 100644 index 000000000000..f35198dc6fa7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-warn-unused-result-2.c @@ -0,0 +1,16 @@ +/* PR c/82134 */ +/* { dg-do compile } */ +/* { dg-additional-options -Wno-c++-compat { target c } } */ + +struct S {}; + +__attribute__((warn_unused_result)) struct S foo(); + +void use_s(struct S); + +void +test (void) +{ + struct S s = foo(); /* { dg-bogus "ignoring return value of" } */ + use_s(foo()); /* { dg-bogus "ignoring return value of" } */ +} diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 3d23f178da7e..275fc436d135 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -9849,6 +9849,8 @@ do_warn_unused_result (gimple_seq seq) break; if (gimple_call_internal_p (g)) break; + if (warning_suppressed_p (g, OPT_Wunused_result)) + break; /* This is a naked call, as opposed to a GIMPLE_CALL with an LHS. All calls whose value is ignored should be