https://gcc.gnu.org/g:1a17acec2dbe61ac950fd93780a886526367298f

commit 1a17acec2dbe61ac950fd93780a886526367298f
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Jul 14 18:29:17 2025 -0400

    c++: don't mark void exprs as read [PR44677]
    
    In Jakub's patch for PR44677 he added code to prevent mark_exp_read on
    e.g. (void)++i from marking i as read, but it seems to me that we can
    generalize that to avoid looking any farther into any void expression;
    you can't read a void value, and an explicit cast will have already called
    mark_exp_read on its operand in convert_to_void.
    
    For testing I added an assert to catch places where we were trying to mark
    void expressions as read, and fix a few that it found.  But there were
    several other places (such as check_return_expr) where we could have a void
    expression but always calling mark_exp_read makes sense, so I dropped the
    assert from the final commit.
    
            PR c++/44677
    
    gcc/cp/ChangeLog:
    
            * cp-gimplify.cc (cp_fold) [CLEANUP_POINT_EXPR]: Don't force rvalue.
            [COMPOUND_EXPR]: Likewise.
            * cvt.cc (convert_to_void): Call mark_exp_read later.
            * expr.cc (mark_use): Turn off read_p for any void argument.
            (mark_exp_read): Return early for void argument.

Diff:
---
 gcc/cp/cp-gimplify.cc |  5 +++--
 gcc/cp/cvt.cc         | 13 ++++++-------
 gcc/cp/expr.cc        | 37 ++++++-------------------------------
 3 files changed, 15 insertions(+), 40 deletions(-)

diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index addbc29d104b..d54fe347a6ca 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -3028,7 +3028,7 @@ cp_fold (tree x, fold_flags_t flags)
     case CLEANUP_POINT_EXPR:
       /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
         effects.  */
-      r = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
+      r = cp_fold (TREE_OPERAND (x, 0), flags);
       if (!TREE_SIDE_EFFECTS (r))
        x = r;
       break;
@@ -3223,7 +3223,8 @@ cp_fold (tree x, fold_flags_t flags)
          && (VAR_P (op0) || TREE_CODE (op0) == PARM_DECL)
          && !DECL_READ_P (op0))
        clear_decl_read = true;
-      op1 = cp_fold_rvalue (TREE_OPERAND (x, 1), flags);
+      op1 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 1),
+                                 code != COMPOUND_EXPR, flags);
       if (clear_decl_read)
        DECL_READ_P (op0) = 0;
 
diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
index f663a6d08c89..55be12db9513 100644
--- a/gcc/cp/cvt.cc
+++ b/gcc/cp/cvt.cc
@@ -1186,13 +1186,6 @@ convert_to_void (tree expr, impl_conv_void implicit, 
tsubst_flags_t complain)
 
   expr = maybe_undo_parenthesized_ref (expr);
 
-  expr = mark_discarded_use (expr);
-  if (implicit == ICV_CAST)
-    /* An explicit cast to void avoids all -Wunused-but-set* warnings.  */
-    mark_exp_read (expr);
-
-  if (!TREE_TYPE (expr))
-    return expr;
   if (invalid_nonstatic_memfn_p (loc, expr, complain))
     return error_mark_node;
   if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
@@ -1209,6 +1202,12 @@ convert_to_void (tree expr, impl_conv_void implicit, 
tsubst_flags_t complain)
 
   if (VOID_TYPE_P (TREE_TYPE (expr)))
     return expr;
+
+  expr = mark_discarded_use (expr);
+  if (implicit == ICV_CAST)
+    /* An explicit cast to void avoids all -Wunused-but-set* warnings.  */
+    mark_exp_read (expr);
+
   switch (TREE_CODE (expr))
     {
     case COND_EXPR:
diff --git a/gcc/cp/expr.cc b/gcc/cp/expr.cc
index 8b5a098ecb37..32dc3eee78f9 100644
--- a/gcc/cp/expr.cc
+++ b/gcc/cp/expr.cc
@@ -102,6 +102,9 @@ mark_use (tree expr, bool rvalue_p, bool read_p,
   if (reject_builtin && reject_gcc_builtin (expr, loc))
     return error_mark_node;
 
+  if (TREE_TYPE (expr) && VOID_TYPE_P (TREE_TYPE (expr)))
+    read_p = false;
+
   if (read_p)
     mark_exp_read (expr);
 
@@ -213,25 +216,6 @@ mark_use (tree expr, bool rvalue_p, bool read_p,
        }
       gcc_fallthrough ();
     CASE_CONVERT:
-      if (VOID_TYPE_P (TREE_TYPE (expr)))
-       switch (TREE_CODE (TREE_OPERAND (expr, 0)))
-         {
-         case PREINCREMENT_EXPR:
-         case PREDECREMENT_EXPR:
-         case POSTINCREMENT_EXPR:
-         case POSTDECREMENT_EXPR:
-           tree op0;
-           op0 = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
-           STRIP_ANY_LOCATION_WRAPPER (op0);
-           if ((VAR_P (op0) || TREE_CODE (op0) == PARM_DECL)
-               && !DECL_READ_P (op0)
-               && (VAR_P (op0) ? warn_unused_but_set_variable
-                               : warn_unused_but_set_parameter) > 1)
-             read_p = false;
-           break;
-         default:
-           break;
-         }
       recurse_op[0] = true;
       break;
 
@@ -371,6 +355,9 @@ mark_exp_read (tree exp)
   if (exp == NULL)
     return;
 
+  if (TREE_TYPE (exp) && VOID_TYPE_P (TREE_TYPE (exp)))
+    return;
+
   switch (TREE_CODE (exp))
     {
     case VAR_DECL:
@@ -381,18 +368,6 @@ mark_exp_read (tree exp)
       DECL_READ_P (exp) = 1;
       break;
     CASE_CONVERT:
-      if (VOID_TYPE_P (TREE_TYPE (exp)))
-       switch (TREE_CODE (TREE_OPERAND (exp, 0)))
-         {
-         case PREINCREMENT_EXPR:
-         case PREDECREMENT_EXPR:
-         case POSTINCREMENT_EXPR:
-         case POSTDECREMENT_EXPR:
-           return;
-         default:
-           break;
-         }
-      /* FALLTHRU */
     case ARRAY_REF:
     case COMPONENT_REF:
     case MODIFY_EXPR:

Reply via email to