https://gcc.gnu.org/g:a6d373d8a843043e11022ab383332fb259a45ba3

commit a6d373d8a843043e11022ab383332fb259a45ba3
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

Reply via email to