]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: don't mark void exprs as read [PR44677]
authorJason Merrill <jason@redhat.com>
Mon, 14 Jul 2025 22:29:17 +0000 (18:29 -0400)
committerJason Merrill <jason@redhat.com>
Tue, 15 Jul 2025 19:05:48 +0000 (15:05 -0400)
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.

gcc/cp/cp-gimplify.cc
gcc/cp/cvt.cc
gcc/cp/expr.cc

index addbc29d104bd11f431e5822880d9b6de6c4b5d2..d54fe347a6ca90c8a39daebb79b5ecfa2bfe5a9f 100644 (file)
@@ -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;
 
index f663a6d08c8974e58a0f0bca7c002f31c94a8a1d..55be12db9513686628a0bacf54473ee3c72ae100 100644 (file)
@@ -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:
index 8b5a098ecb379babe97d4698bf43c1abf52beffb..32dc3eee78f9bd6f1f935fd038089caa116e4498 100644 (file)
@@ -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: