aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2025-07-14 18:29:17 -0400
committerJason Merrill <jason@redhat.com>2025-07-15 15:05:48 -0400
commit35b19980046fc57d9d6851b8f4349bd22de3fa03 (patch)
tree28ad7b9636111905a361876a9273d0fedb10832e
parent3fbed69502770851c8a5bfece99e9ee8c6d9e4b0 (diff)
downloadgcc-35b19980046fc57d9d6851b8f4349bd22de3fa03.zip
gcc-35b19980046fc57d9d6851b8f4349bd22de3fa03.tar.gz
gcc-35b19980046fc57d9d6851b8f4349bd22de3fa03.tar.bz2
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.
-rw-r--r--gcc/cp/cp-gimplify.cc5
-rw-r--r--gcc/cp/cvt.cc13
-rw-r--r--gcc/cp/expr.cc37
3 files changed, 15 insertions, 40 deletions
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index addbc29..d54fe34 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 f663a6d..55be12d 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 8b5a098..32dc3ee 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: