https://gcc.gnu.org/g:0eac9cfee8cb0b21de866a04d5d59685ab35208f

commit r16-2258-g0eac9cfee8cb0b21de866a04d5d59685ab35208f
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Jul 15 15:00:33 2025 +0200

    c, c++: Extend -Wunused-but-set-* warnings [PR44677]
    
    The -Wunused-but-set-* warnings work by using 2 bits on VAR_DECLs &
    PARM_DECLs, TREE_USED and DECL_READ_P.  If neither is set, we typically
    emit -Wunused-variable or -Wunused-parameter warning, that is for variables
    which are just declared (including initializer) and completely unused.
    If TREE_USED is set and DECL_READ_P is unset, -Wunused-but-set-* warnings
    are emitted, i.e. for variables which can appear on the lhs of an assignment
    expression but aren't actually used elsewhere.  The DECL_READ_P marking is
    done through mark_exp_read called from lots of places (e.g. lvalue to rvalue
    conversions etc.).
    
    LLVM has an extension on top of that in that it doesn't count pre/post
    inc/decrements as use (i.e. DECL_READ_P for GCC).
    
    The following patch does that too, though because we had the current
    behavior for 11+ years already and lot of people is -Wunused-but-set-*
    warning free in the current GCC behavior and not in the clang one (including
    GCC sources), it allows users to choose.
    Furthermore, it implements another level, where also var @= expr uses of var
    (except when it is also used in expr) aren't counted as DECL_READ_P.
    
    I think it would be nice to also handle var = var @ expr or var = expr @ var
    but unfortunately mark_exp_read is then done in both FEs during parsing of
    var @ expr or expr @ var and the code doesn't know it is rhs of an
    assignment with var as lhs.
    
    The patch works mostly by checking if DECL_READ_P is clear at some point and
    then clearing it again after some operation which might have set it.
    
    -Wunused or -Wall or -Wunused -Wextra or -Wall -Wextra turn on the 3 level
    of the new warning (i.e. the one which ignores also var++, ++var etc. as
    well as var @= expr), so does -Wunused-but-set-{variable,parameter}, but
    users can use explicit -Wunused-but-set-{variable,parameter}={1,2} to select
    a different level.
    
    2025-07-15  Jakub Jelinek  <ja...@redhat.com>
                Jason Merrill  <ja...@redhat.com>
    
            PR c/44677
    gcc/
            * common.opt (Wunused-but-set-parameter=, 
Wunused-but-set-variable=):
            New options.
            (Wunused-but-set-parameter, Wunused-but-set-variable): Turn into
            aliases.
            * common.opt.urls: Regenerate.
            * diagnostic-spec.cc (nowarn_spec_t::nowarn_spec_t): Use
            OPT_Wunused_but_set_variable_ instead of 
OPT_Wunused_but_set_variable
            and OPT_Wunused_but_set_parameter_ instead of
            OPT_Wunused_but_set_parameter.
            * gimple-ssa-store-merging.cc (find_bswap_or_nop_1): Remove unused
            but set variable tmp.
            * ipa-strub.cc (pass_ipa_strub::execute): Cast named_args to
            (void) if ATTR_FNSPEC_DECONST_WATERMARK is not defined.
            * doc/invoke.texi (Wunused-but-set-parameter=,
            Wunused-but-set-variable=): Document new options.
            (Wunused-but-set-parameter, Wunused-but-set-variable): Adjust
            documentation now that they are just aliases.
    gcc/c-family/
            * c-opts.cc (c_common_post_options): Change
            warn_unused_but_set_parameter and warn_unused_but_set_variable
            from 1 to 3 if they were set only implicitly.
            * c-attribs.cc (build_attr_access_from_parms): Remove unused
            but set variable nelts.
    gcc/c/
            * c-parser.cc (c_parser_unary_expression): Clear DECL_READ_P
            after default_function_array_read_conversion for
            -Wunused-but-set-{parameter,variable}={2,3} on
            PRE{IN,DE}CREMENT_EXPR argument.
            (c_parser_postfix_expression_after_primary): Similarly for
            POST{IN,DE}CREMENT_EXPR.
            * c-decl.cc (pop_scope): Use OPT_Wunused_but_set_variable_
            instead of OPT_Wunused_but_set_variable.
            (finish_function): Use OPT_Wunused_but_set_parameter_
            instead of OPT_Wunused_but_set_parameter.
            * c-typeck.cc (mark_exp_read): Handle {PRE,POST}{IN,DE}CREMENT_EXPR
            and don't handle it when cast to void.
            (build_modify_expr): Clear DECL_READ_P after build_binary_op
            for -Wunused-but-set-{parameter,variable}=3.
    gcc/cp/
            * cp-gimplify.cc (cp_fold): Clear DECL_READ_P on lhs of MODIFY_EXPR
            after cp_fold_rvalue if it wasn't set before.
            * decl.cc (poplevel): Use OPT_Wunused_but_set_variable_
            instead of OPT_Wunused_but_set_variable.
            (finish_function): Use OPT_Wunused_but_set_parameter_
            instead of OPT_Wunused_but_set_parameter.
            * expr.cc (mark_use): Clear read_p for {PRE,POST}{IN,DE}CREMENT_EXPR
            cast to void on {VAR,PARM}_DECL for
            -Wunused-but-set-{parameter,variable}={2,3}.
            (mark_exp_read): Handle {PRE,POST}{IN,DE}CREMENT_EXPR and don't 
handle
            it when cast to void.
            * module.cc (trees_in::fn_parms_fini): Remove unused but set 
variable
            ix.
            * semantics.cc (finish_unary_op_expr): Return early for
            PRE{IN,DE}CREMENT_EXPR.
            * typeck.cc (cp_build_unary_op): Clear DECL_READ_P
            after mark_lvalue_use for 
-Wunused-but-set-{parameter,variable}={2,3}
            on PRE{IN,DE}CREMENT_EXPR argument.
            (cp_build_modify_expr): Clear DECL_READ_P after cp_build_binary_op
            for -Wunused-but-set-{parameter,variable}=3.
    gcc/go/
            * gofrontend/gogo.cc (Function::export_func_with_type): Remove
            unused but set variable i.
    gcc/cobol/
            * gcobolspec.cc (lang_specific_driver): Remove unused but set 
variable
            n_cobol_files.
    gcc/testsuite/
            * c-c++-common/Wunused-parm-1.c: New test.
            * c-c++-common/Wunused-parm-2.c: New test.
            * c-c++-common/Wunused-parm-3.c: New test.
            * c-c++-common/Wunused-parm-4.c: New test.
            * c-c++-common/Wunused-parm-5.c: New test.
            * c-c++-common/Wunused-parm-6.c: New test.
            * c-c++-common/Wunused-var-7.c (bar, baz): Expect warning on a.
            * c-c++-common/Wunused-var-19.c: New test.
            * c-c++-common/Wunused-var-20.c: New test.
            * c-c++-common/Wunused-var-21.c: New test.
            * c-c++-common/Wunused-var-22.c: New test.
            * c-c++-common/Wunused-var-23.c: New test.
            * c-c++-common/Wunused-var-24.c: New test.
            * g++.dg/cpp26/name-independent-decl1.C (foo): Expect one
            set but not used warning.
            * g++.dg/warn/Wunused-parm-12.C: New test.
            * g++.dg/warn/Wunused-parm-13.C: New test.
            * g++.dg/warn/Wunused-var-2.C (f2): Expect set but not used warning
            on parameter x and variable a.
            * g++.dg/warn/Wunused-var-40.C: New test.
            * g++.dg/warn/Wunused-var-41.C: New test.
            * gcc.dg/memchr-3.c (test_find): Change return type from void to 
int,
            and add return n; statement.
            * gcc.dg/unused-9.c (g): Move dg-bogus to the correct line and 
expect
            a warning on i.

Diff:
---
 gcc/c-family/c-attribs.cc                          |  3 +-
 gcc/c-family/c-opts.cc                             | 11 ++++
 gcc/c/c-decl.cc                                    |  8 +--
 gcc/c/c-parser.cc                                  | 48 ++++++++++++--
 gcc/c/c-typeck.cc                                  | 31 ++++++++-
 gcc/cobol/gcobolspec.cc                            |  8 ---
 gcc/common.opt                                     | 10 ++-
 gcc/common.opt.urls                                |  6 ++
 gcc/cp/cp-gimplify.cc                              |  8 +++
 gcc/cp/decl.cc                                     |  8 +--
 gcc/cp/expr.cc                                     | 39 ++++++++++-
 gcc/cp/module.cc                                   |  3 +-
 gcc/cp/semantics.cc                                |  5 ++
 gcc/cp/typeck.cc                                   | 28 +++++++-
 gcc/diagnostic-spec.cc                             |  4 +-
 gcc/doc/invoke.texi                                | 75 ++++++++++++++++++++--
 gcc/gimple-ssa-store-merging.cc                    |  4 +-
 gcc/go/gofrontend/gogo.cc                          |  3 +-
 gcc/ipa-strub.cc                                   |  2 +
 gcc/testsuite/c-c++-common/Wunused-parm-1.c        | 50 +++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-parm-2.c        | 50 +++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-parm-3.c        | 50 +++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-parm-4.c        | 50 +++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-parm-5.c        | 50 +++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-parm-6.c        | 50 +++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-var-19.c        | 60 +++++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-var-20.c        | 60 +++++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-var-21.c        | 60 +++++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-var-22.c        | 60 +++++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-var-23.c        | 60 +++++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-var-24.c        | 60 +++++++++++++++++
 gcc/testsuite/c-c++-common/Wunused-var-7.c         |  4 +-
 .../g++.dg/cpp26/name-independent-decl1.C          |  2 +-
 gcc/testsuite/g++.dg/warn/Wunused-parm-12.C        | 59 +++++++++++++++++
 gcc/testsuite/g++.dg/warn/Wunused-parm-13.C        | 59 +++++++++++++++++
 gcc/testsuite/g++.dg/warn/Wunused-var-2.C          |  4 +-
 gcc/testsuite/g++.dg/warn/Wunused-var-40.C         | 69 ++++++++++++++++++++
 gcc/testsuite/g++.dg/warn/Wunused-var-41.C         | 69 ++++++++++++++++++++
 gcc/testsuite/gcc.dg/memchr-3.c                    |  3 +-
 gcc/testsuite/gcc.dg/unused-9.c                    |  9 +--
 40 files changed, 1185 insertions(+), 57 deletions(-)

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5d7a31fd99b6..ac215344f300 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -5858,8 +5858,7 @@ build_attr_access_from_parms (tree parms, bool 
skip_voidptr)
             order.  */
          vblist = tree_cons (NULL_TREE, argvbs, vblist);
 
-         unsigned nelts = 0;
-         for (tree vb = argvbs; vb; vb = TREE_CHAIN (vb), ++nelts)
+         for (tree vb = argvbs; vb; vb = TREE_CHAIN (vb))
            {
              tree bound = TREE_VALUE (vb);
              if (const unsigned *psizpos = arg2pos.get (bound))
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index 872bdf4ea246..795f5a355af6 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -1226,6 +1226,17 @@ c_common_post_options (const char **pfilename)
   SET_OPTION_IF_UNSET (&global_options, &global_options_set,
                       flag_range_for_ext_temps, cxx_dialect >= cxx23);
 
+  /* EnabledBy unfortunately can't specify value to use if set and
+     LangEnabledBy can't specify multiple options with &&.  For -Wunused
+     or -Wunused -Wextra we want these to default to 3 unless user specified
+     some other level explicitly.  */
+  if (warn_unused_but_set_parameter == 1)
+    SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+                        warn_unused_but_set_parameter, 3);
+  if (warn_unused_but_set_variable == 1)
+    SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+                        warn_unused_but_set_variable, 3);
+
   /* -fimmediate-escalation has no effect when immediate functions are not
      supported.  */
   if (flag_immediate_escalation && cxx_dialect < cxx20)
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 8bbd6ebc66ad..acbe2b88e674 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -1363,7 +1363,7 @@ pop_scope (void)
        case VAR_DECL:
          /* Warnings for unused variables.  */
          if ((!TREE_USED (p) || !DECL_READ_P (p))
-             && !warning_suppressed_p (p, OPT_Wunused_but_set_variable)
+             && !warning_suppressed_p (p, OPT_Wunused_but_set_variable_)
              && !DECL_IN_SYSTEM_HEADER (p)
              && DECL_NAME (p)
              && !DECL_ARTIFICIAL (p)
@@ -1377,7 +1377,7 @@ pop_scope (void)
                }
              else if (DECL_CONTEXT (p) == current_function_decl)
                warning_at (DECL_SOURCE_LOCATION (p),
-                           OPT_Wunused_but_set_variable,
+                           OPT_Wunused_but_set_variable_,
                            "variable %qD set but not used", p);
            }
 
@@ -11465,9 +11465,9 @@ finish_function (location_t end_loc)
            && !DECL_READ_P (decl)
            && DECL_NAME (decl)
            && !DECL_ARTIFICIAL (decl)
-           && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter))
+           && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter_))
          warning_at (DECL_SOURCE_LOCATION (decl),
-                     OPT_Wunused_but_set_parameter,
+                     OPT_Wunused_but_set_parameter_,
                      "parameter %qD set but not used", decl);
     }
 
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 0c3e3e2889c6..5119841a5895 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -10547,15 +10547,31 @@ c_parser_unary_expression (c_parser *parser)
       c_parser_consume_token (parser);
       exp_loc = c_parser_peek_token (parser)->location;
       op = c_parser_cast_expression (parser, NULL);
-
-      op = default_function_array_read_conversion (exp_loc, op);
+      if ((VAR_P (op.value) || TREE_CODE (op.value) == PARM_DECL)
+         && !DECL_READ_P (op.value)
+         && (VAR_P (op.value) ? warn_unused_but_set_variable
+                              : warn_unused_but_set_parameter) > 1)
+       {
+         op = default_function_array_read_conversion (exp_loc, op);
+         DECL_READ_P (op.value) = 0;
+       }
+      else
+       op = default_function_array_read_conversion (exp_loc, op);
       return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
     case CPP_MINUS_MINUS:
       c_parser_consume_token (parser);
       exp_loc = c_parser_peek_token (parser)->location;
       op = c_parser_cast_expression (parser, NULL);
-
-      op = default_function_array_read_conversion (exp_loc, op);
+      if ((VAR_P (op.value) || TREE_CODE (op.value) == PARM_DECL)
+         && !DECL_READ_P (op.value)
+         && (VAR_P (op.value) ? warn_unused_but_set_variable
+                              : warn_unused_but_set_parameter) > 1)
+       {
+         op = default_function_array_read_conversion (exp_loc, op);
+         DECL_READ_P (op.value) = 0;
+       }
+      else
+       op = default_function_array_read_conversion (exp_loc, op);
       return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
     case CPP_AND:
       c_parser_consume_token (parser);
@@ -13933,7 +13949,17 @@ c_parser_postfix_expression_after_primary (c_parser 
*parser,
          start = expr.get_start ();
          finish = c_parser_peek_token (parser)->get_finish ();
          c_parser_consume_token (parser);
-         expr = default_function_array_read_conversion (expr_loc, expr);
+         if ((VAR_P (expr.value) || TREE_CODE (expr.value) == PARM_DECL)
+             && !DECL_READ_P (expr.value)
+             && (VAR_P (expr.value) ? warn_unused_but_set_variable
+                                    : warn_unused_but_set_parameter) > 1
+             && TREE_CODE (TREE_TYPE (expr.value)) != ARRAY_TYPE)
+           {
+             expr = default_function_array_read_conversion (expr_loc, expr);
+             DECL_READ_P (expr.value) = 0;
+           }
+         else
+           expr = default_function_array_read_conversion (expr_loc, expr);
          expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
                                       expr.value, false);
          set_c_expr_source_range (&expr, start, finish);
@@ -13945,7 +13971,17 @@ c_parser_postfix_expression_after_primary (c_parser 
*parser,
          start = expr.get_start ();
          finish = c_parser_peek_token (parser)->get_finish ();
          c_parser_consume_token (parser);
-         expr = default_function_array_read_conversion (expr_loc, expr);
+         if ((VAR_P (expr.value) || TREE_CODE (expr.value) == PARM_DECL)
+             && !DECL_READ_P (expr.value)
+             && (VAR_P (expr.value) ? warn_unused_but_set_variable
+                                    : warn_unused_but_set_parameter) > 1
+             && TREE_CODE (TREE_TYPE (expr.value)) != ARRAY_TYPE)
+           {
+             expr = default_function_array_read_conversion (expr_loc, expr);
+             DECL_READ_P (expr.value) = 0;
+           }
+         else
+           expr = default_function_array_read_conversion (expr_loc, expr);
          expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
                                       expr.value, false);
          set_c_expr_source_range (&expr, start, finish);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 9a5eb0da3a1d..5d11e576dc99 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -2310,14 +2310,30 @@ mark_exp_read (tree exp)
     case PARM_DECL:
       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:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-    CASE_CONVERT:
     case ADDR_EXPR:
     case VIEW_CONVERT_EXPR:
+    case PREINCREMENT_EXPR:
+    case PREDECREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
       mark_exp_read (TREE_OPERAND (exp, 0));
       break;
     case COMPOUND_EXPR:
@@ -7308,8 +7324,21 @@ build_modify_expr (location_t location, tree lhs, tree 
lhs_origtype,
                newrhs = build1 (EXCESS_PRECISION_EXPR, TREE_TYPE (rhs),
                                 newrhs);
            }
+         bool clear_decl_read = false;
+         if ((VAR_P (lhs) || TREE_CODE (lhs) == PARM_DECL)
+             && !DECL_READ_P (lhs)
+             && (VAR_P (lhs) ? warn_unused_but_set_variable
+                             : warn_unused_but_set_parameter) > 2)
+           {
+             mark_exp_read (newrhs);
+             if (!DECL_READ_P (lhs))
+               clear_decl_read = true;
+           }
+
          newrhs = build_binary_op (location,
                                    modifycode, lhs, newrhs, true);
+         if (clear_decl_read)
+           DECL_READ_P (lhs) = 0;
 
          /* The original type of the right hand side is no longer
             meaningful.  */
diff --git a/gcc/cobol/gcobolspec.cc b/gcc/cobol/gcobolspec.cc
index 9532d4256b22..038aaec13469 100644
--- a/gcc/cobol/gcobolspec.cc
+++ b/gcc/cobol/gcobolspec.cc
@@ -142,9 +142,6 @@ lang_specific_driver (struct cl_decoded_option 
**in_decoded_options,
   int n_infiles = 0;
   int n_outfiles = 0;
 
-  // The number of input files when the language is "none" or "cobol"
-  int n_cobol_files = 0;
-
   // saw_OPT_no_main means "don't expect -main"
   bool saw_OPT_no_main = false;
 
@@ -234,11 +231,6 @@ lang_specific_driver (struct cl_decoded_option 
**in_decoded_options,
       case OPT_SPECIAL_input_file:
         no_files_error = false;
         n_infiles += 1;
-        if(    strcmp(language, "none")  == 0
-            || strcmp(language, "cobol") == 0 )
-          {
-          n_cobol_files += 1;
-          }
         if( strstr(decoded_options[i].orig_option_with_args_text, 
"libgcobol.a") )
           {
           // We have been given an explicit libgcobol.a.  We need to note that.
diff --git a/gcc/common.opt b/gcc/common.opt
index 3d65656e658c..d68d7d8d9148 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -851,11 +851,17 @@ Common Var(warn_unused) Init(0) Warning
 Enable all -Wunused- warnings.
 
 Wunused-but-set-parameter
-Common Var(warn_unused_but_set_parameter) Warning EnabledBy(Wunused && Wextra)
+Common Alias(Wunused-but-set-parameter=,3,0) Warning
+
+Wunused-but-set-parameter=
+Common Var(warn_unused_but_set_parameter) RejectNegative Joined UInteger 
Warning IntegerRange(0, 3) EnabledBy(Wunused && Wextra)
 Warn when a function parameter is only set, otherwise unused.
 
 Wunused-but-set-variable
-Common Var(warn_unused_but_set_variable) Warning EnabledBy(Wunused)
+Common Alias(Wunused-but-set-variable=,3,0) Warning
+
+Wunused-but-set-variable=
+Common Var(warn_unused_but_set_variable) RejectNegative Joined UInteger 
Warning IntegerRange(0, 3) EnabledBy(Wunused)
 Warn when a variable is only set, otherwise unused.
 
 Wunused-function
diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls
index a507168d4092..38dd9d317598 100644
--- a/gcc/common.opt.urls
+++ b/gcc/common.opt.urls
@@ -272,9 +272,15 @@ UrlSuffix(gcc/Warning-Options.html#index-Wno-unused)
 Wunused-but-set-parameter
 UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-but-set-parameter)
 
+Wunused-but-set-parameter=
+UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-but-set-parameter)
+
 Wunused-but-set-variable
 UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-but-set-variable)
 
+Wunused-but-set-variable=
+UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-but-set-variable)
+
 Wunused-function
 UrlSuffix(gcc/Warning-Options.html#index-Wno-unused-function)
 
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 882a943391cb..addbc29d104b 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -3217,7 +3217,15 @@ cp_fold (tree x, fold_flags_t flags)
 
       loc = EXPR_LOCATION (x);
       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
+      bool clear_decl_read;
+      clear_decl_read = false;
+      if (code == MODIFY_EXPR
+         && (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);
+      if (clear_decl_read)
+       DECL_READ_P (op0) = 0;
 
       /* decltype(nullptr) has only one value, so optimize away all comparisons
         with that type right away, keeping them in the IL causes troubles for
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 843f0e4fd160..4752874fc97a 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -747,11 +747,11 @@ poplevel (int keep, int reverse, int functionbody)
              {
                if (!DECL_NAME (decl) && DECL_DECOMPOSITION_P (decl))
                  warning_at (DECL_SOURCE_LOCATION (decl),
-                             OPT_Wunused_but_set_variable, "structured "
+                             OPT_Wunused_but_set_variable_, "structured "
                              "binding declaration set but not used");
                else
                  warning_at (DECL_SOURCE_LOCATION (decl),
-                             OPT_Wunused_but_set_variable,
+                             OPT_Wunused_but_set_variable_,
                              "variable %qD set but not used", decl);
                unused_but_set_errorcount = errorcount;
              }
@@ -19496,14 +19496,14 @@ finish_function (bool inline_p)
            && !DECL_READ_P (decl)
            && DECL_NAME (decl)
            && !DECL_ARTIFICIAL (decl)
-           && !warning_suppressed_p (decl,OPT_Wunused_but_set_parameter)
+           && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter_)
            && !DECL_IN_SYSTEM_HEADER (decl)
            && TREE_TYPE (decl) != error_mark_node
            && !TYPE_REF_P (TREE_TYPE (decl))
            && (!CLASS_TYPE_P (TREE_TYPE (decl))
                || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
          warning_at (DECL_SOURCE_LOCATION (decl),
-                     OPT_Wunused_but_set_parameter,
+                     OPT_Wunused_but_set_parameter_,
                      "parameter %qD set but not used", decl);
       unused_but_set_errorcount = errorcount;
     }
diff --git a/gcc/cp/expr.cc b/gcc/cp/expr.cc
index 2157cfba2ebb..8b5a098ecb37 100644
--- a/gcc/cp/expr.cc
+++ b/gcc/cp/expr.cc
@@ -211,8 +211,27 @@ mark_use (tree expr, bool rvalue_p, bool read_p,
            }
          return expr;
        }
-      gcc_fallthrough();
+      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;
 
@@ -361,16 +380,32 @@ mark_exp_read (tree exp)
     case PARM_DECL:
       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:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-    CASE_CONVERT:
     case ADDR_EXPR:
     case INDIRECT_REF:
     case FLOAT_EXPR:
     case VIEW_CONVERT_EXPR:
+    case PREINCREMENT_EXPR:
+    case PREDECREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
       mark_exp_read (TREE_OPERAND (exp, 0));
       break;
     case COMPOUND_EXPR:
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 689319ad9213..e3c1a686b732 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -11124,8 +11124,7 @@ trees_in::fn_parms_fini (int tag, tree fn, tree 
existing, bool is_defn)
 {
   tree existing_parm = existing ? DECL_ARGUMENTS (existing) : NULL_TREE;
   tree parms = DECL_ARGUMENTS (fn);
-  unsigned ix = 0;
-  for (tree parm = parms; parm; parm = DECL_CHAIN (parm), ix++)
+  for (tree parm = parms; parm; parm = DECL_CHAIN (parm))
     {
       if (existing_parm)
        {
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 77fac458ec8c..640e1eab7d35 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -3741,6 +3741,11 @@ finish_unary_op_expr (location_t op_loc, enum tree_code 
code, cp_expr expr,
   if (!(complain & tf_warning))
     return result;
 
+  /* These will never fold into a constant, so no need to check for
+     overflow for them.  */
+  if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
+    return result;
+
   tree result_ovl = result;
   tree expr_ovl = expr;
 
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 0bf5ae4e4e26..a604511db710 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -7680,7 +7680,18 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool 
noconvert,
       if (val != 0)
        goto return_build_unary_op;
 
-      arg = mark_lvalue_use (arg);
+      tree stripped_arg;
+      stripped_arg = tree_strip_any_location_wrapper (arg);
+      if ((VAR_P (stripped_arg) || TREE_CODE (stripped_arg) == PARM_DECL)
+         && !DECL_READ_P (stripped_arg)
+         && (VAR_P (stripped_arg) ? warn_unused_but_set_variable
+                                  : warn_unused_but_set_parameter) > 1)
+       {
+         arg = mark_lvalue_use (arg);
+         DECL_READ_P (stripped_arg) = 0;
+       }
+      else
+       arg = mark_lvalue_use (arg);
 
       /* Increment or decrement the real part of the value,
         and don't change the imaginary part.  */
@@ -9796,7 +9807,22 @@ cp_build_modify_expr (location_t loc, tree lhs, enum 
tree_code modifycode,
          {
            auto_diagnostic_group d;
            rhs = stabilize_expr (rhs, &init);
+           bool clear_decl_read = false;
+           tree stripped_lhs = tree_strip_any_location_wrapper (lhs);
+           if ((VAR_P (stripped_lhs) || TREE_CODE (stripped_lhs) == PARM_DECL)
+               && !DECL_READ_P (stripped_lhs)
+               && (VAR_P (stripped_lhs) ? warn_unused_but_set_variable
+                                        : warn_unused_but_set_parameter) > 2
+               && !CLASS_TYPE_P (TREE_TYPE (lhs))
+               && !CLASS_TYPE_P (TREE_TYPE (rhs)))
+             {
+               mark_exp_read (rhs);
+               if (!DECL_READ_P (stripped_lhs))
+                 clear_decl_read = true;
+             }
            newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
+           if (clear_decl_read)
+             DECL_READ_P (stripped_lhs) = 0;
            if (newrhs == error_mark_node)
              {
                if (complain & tf_error)
diff --git a/gcc/diagnostic-spec.cc b/gcc/diagnostic-spec.cc
index df7857988b6a..b43ae637c161 100644
--- a/gcc/diagnostic-spec.cc
+++ b/gcc/diagnostic-spec.cc
@@ -72,9 +72,9 @@ nowarn_spec_t::nowarn_spec_t (opt_code opt)
     case OPT_Wstrict_aliasing:
     case OPT_Wunused:
     case OPT_Wunused_function:
-    case OPT_Wunused_but_set_variable:
+    case OPT_Wunused_but_set_variable_:
     case OPT_Wunused_variable:
-    case OPT_Wunused_but_set_parameter:
+    case OPT_Wunused_but_set_parameter_:
       m_bits = NW_LEXICAL;
       break;
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f60865bdc6ee..09802303254c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -433,7 +433,8 @@ Objective-C and Objective-C++ Dialects}.
 -Wunsuffixed-float-constants
 -Wunterminated-string-initialization
 -Wunused
--Wunused-but-set-parameter  -Wunused-but-set-variable
+-Wunused-but-set-parameter  -Wunused-but-set-parameter=@var{n}
+-Wunused-but-set-variable  -Wunused-but-set-variable=@var{n}
 -Wunused-const-variable  -Wunused-const-variable=@var{n}
 -Wunused-function  -Wunused-label  -Wunused-local-typedefs
 -Wunused-macros
@@ -7921,27 +7922,89 @@ statement.
 @opindex Wunused-but-set-parameter
 @opindex Wno-unused-but-set-parameter
 @item -Wunused-but-set-parameter
+@option{-Wunused-but-set-parameter} is the same as
+@option{-Wunused-but-set-parameter=3} and
+@option{-Wno-unused-but-set-parameter} is the same as
+@option{-Wunused-but-set-parameter=0}.
+
+@opindex Wunused-but-set-parameter=
+@item -Wunused-but-set-parameter=@var{n}
 Warn whenever a function parameter is assigned to, but otherwise unused
 (aside from its declaration).
 
 To suppress this warning use the @code{unused} attribute
 (@pxref{Variable Attributes}).
 
-This warning is also enabled by @option{-Wunused} together with
-@option{-Wextra}.
+@option{-Wunused-but-set-parameter=0} disables the warning.
+With @option{-Wunused-but-set-parameter=1} all uses except initialization
+and left hand side of assignment which is not further used disable the
+warning.
+With @option{-Wunused-but-set-parameter=2} additionally uses of parameter
+in @code{++} and @code{--} operators don't count as uses.
+And finally with @option{-Wunused-but-set-parameter=3} additionally
+uses in @var{parm} @code{@var{@@}=} @var{rhs} outside of @var{rhs} don't
+count as uses.  See @option{-Wunused-but-set-variable=@var{n}} option for
+examples.
+
+This @option{-Wunused-but-set-parameter=3} warning is also enabled by
+@option{-Wunused} together with @option{-Wextra}.
 
 @opindex Wunused-but-set-variable
 @opindex Wno-unused-but-set-variable
 @item -Wunused-but-set-variable
+@option{-Wunused-but-set-variable} is the same as
+@option{-Wunused-but-set-variable=3} and
+@option{-Wno-unused-but-set-variable} is the same as
+@option{-Wunused-but-set-variable=0}.
+
+@opindex Wunused-but-set-variable=
+@item -Wunused-but-set-variable=@var{n}
 Warn whenever a local variable is assigned to, but otherwise unused
 (aside from its declaration).
-This warning is enabled by @option{-Wall}.
+This @option{-Wunused-but-set-variable=3} warning is enabled by @option{-Wall}.
 
 To suppress this warning use the @code{unused} attribute
 (@pxref{Variable Attributes}).
 
-This warning is also enabled by @option{-Wunused}, which is enabled
-by @option{-Wall}.
+@option{-Wunused-but-set-variable=0} disables the warning.
+With @option{-Wunused-but-set-variable=1} all uses except initialization
+and left hand side of assignment which is not further used disable the
+warning.
+With @option{-Wunused-but-set-variable=2} additionally uses of variable
+in @code{++} and @code{--} operators don't count as uses.
+And finally with @option{-Wunused-but-set-variable=3} additionally
+uses in @var{parm} @code{@var{@@}=} @var{rhs} outside of @var{rhs} don't
+count as uses.
+
+This @option{-Wunused-but-set-variable=3} warning is also enabled by
+@option{-Wunused}, which is enabled by @option{-Wall}.
+
+@smallexample
+void foo (void)
+@{
+  int a = 1; // @option{-Wunused-variable} warning
+  int b = 0; // Warning for @var{n} >= 1
+  b = 1; b = 2;
+  int c = 0; // Warning for @var{n} >= 2
+  ++c; c--; --c; c++;
+  int d = 0; // Warning for @var{n} >= 3
+  d += 4;
+  int e = 0; // No warning, cast to void
+  (void) e;
+  int f = 0; // No warning, f used
+  int g = f = 5;
+  (void) g;
+  int h = 0; // No warning, preincrement used
+  int i = ++h;
+  (void) i;
+  int j = 0; // No warning, postdecrement used
+  int k = j--;
+  (void) k;
+  int l = 0; // No warning, l used
+  int m = l |= 2;
+  (void) m;
+@}
+@end smallexample
 
 @opindex Wunused-function
 @opindex Wno-unused-function
diff --git a/gcc/gimple-ssa-store-merging.cc b/gcc/gimple-ssa-store-merging.cc
index 90f449ce82f4..ce56d97d4383 100644
--- a/gcc/gimple-ssa-store-merging.cc
+++ b/gcc/gimple-ssa-store-merging.cc
@@ -644,9 +644,7 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number 
*n, int limit)
 
          /* Mask.  */
          uint64_t mask = 0;
-         uint64_t tmp = (1 << BITS_PER_UNIT) - 1;
-         for (unsigned i = 0; i < bitsize / BITS_PER_UNIT;
-              i++, tmp <<= BITS_PER_UNIT)
+         for (unsigned i = 0; i < bitsize / BITS_PER_UNIT; i++)
            mask |= (uint64_t) MARKER_MASK << (i * BITS_PER_MARKER);
          n->n &= mask;
 
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 3aad4194c628..566eca82e4d6 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -5987,12 +5987,11 @@ Function::export_func_with_type(Export* exp, const 
Named_object* no,
   const Typed_identifier_list* parameters = fntype->parameters();
   if (parameters != NULL)
     {
-      size_t i = 0;
       bool is_varargs = fntype->is_varargs();
       bool first = true;
       for (Typed_identifier_list::const_iterator p = parameters->begin();
           p != parameters->end();
-          ++p, ++i)
+          ++p)
        {
          if (first)
            first = false;
diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
index d7c0a9286002..86270af3dbae 100644
--- a/gcc/ipa-strub.cc
+++ b/gcc/ipa-strub.cc
@@ -3059,6 +3059,8 @@ pass_ipa_strub::execute (function *)
                         TYPE_ATTRIBUTES (TREE_TYPE (nnode->decl)));
        }
     }
+#else
+    (void) named_args;
 #endif
 
     {
diff --git a/gcc/testsuite/c-c++-common/Wunused-parm-1.c 
b/gcc/testsuite/c-c++-common/Wunused-parm-1.c
new file mode 100644
index 000000000000..355fa4a5fe52
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-parm-1.c
@@ -0,0 +1,50 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-parameter" } */
+
+void baz (int);
+
+void
+foo (int a,            /* { dg-warning "parameter 'a' set but not used" } */
+     int b,            /* { dg-warning "parameter 'b' set but not used" } */
+     int c,            /* { dg-warning "parameter 'c' set but not used" } */
+     int d,            /* { dg-warning "parameter 'd' set but not used" } */
+     int e,            /* { dg-warning "parameter 'e' set but not used" } */
+     int f,            /* { dg-warning "parameter 'f' set but not used" } */
+     int g,            /* { dg-warning "parameter 'g' set but not used" } */
+     int h,            /* { dg-warning "parameter 'h' set but not used" } */
+     int i,            /* { dg-warning "parameter 'i' set but not used" } */
+     int j,            /* { dg-warning "parameter 'j' set but not used" } */
+     int k,            /* { dg-warning "parameter 'k' set but not used" } */
+     int l,            /* { dg-warning "parameter 'l' set but not used" } */
+     int m)            /* { dg-warning "parameter 'm' set but not used" } */
+{
+  a = 1;
+  ++b;
+  c++;
+  --d;
+  e--;
+  f += 2;
+  g |= 2;
+  h -= 2;
+  i &= 2;
+  j ^= 2;
+  k *= 2;
+  l %= 2;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
+     int k, int l, int m, int n)
+{
+  b = ++a;
+  d = --c;
+  f = e--;
+  h = g++;
+  j = i += 42;
+  l = k *= 4;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-parm-2.c 
b/gcc/testsuite/c-c++-common/Wunused-parm-2.c
new file mode 100644
index 000000000000..2caea94857eb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-parm-2.c
@@ -0,0 +1,50 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused -Wextra" } */
+
+void baz (int);
+
+void
+foo (int a,            /* { dg-warning "parameter 'a' set but not used" } */
+     int b,            /* { dg-warning "parameter 'b' set but not used" } */
+     int c,            /* { dg-warning "parameter 'c' set but not used" } */
+     int d,            /* { dg-warning "parameter 'd' set but not used" } */
+     int e,            /* { dg-warning "parameter 'e' set but not used" } */
+     int f,            /* { dg-warning "parameter 'f' set but not used" } */
+     int g,            /* { dg-warning "parameter 'g' set but not used" } */
+     int h,            /* { dg-warning "parameter 'h' set but not used" } */
+     int i,            /* { dg-warning "parameter 'i' set but not used" } */
+     int j,            /* { dg-warning "parameter 'j' set but not used" } */
+     int k,            /* { dg-warning "parameter 'k' set but not used" } */
+     int l,            /* { dg-warning "parameter 'l' set but not used" } */
+     int m)            /* { dg-warning "parameter 'm' set but not used" } */
+{
+  a = 1;
+  ++b;
+  c++;
+  --d;
+  e--;
+  f += 2;
+  g |= 2;
+  h -= 2;
+  i &= 2;
+  j ^= 2;
+  k *= 2;
+  l %= 2;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
+     int k, int l, int m, int n)
+{
+  b = ++a;
+  d = --c;
+  f = e--;
+  h = g++;
+  j = i += 42;
+  l = k *= 4;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-parm-3.c 
b/gcc/testsuite/c-c++-common/Wunused-parm-3.c
new file mode 100644
index 000000000000..2978cd447c89
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-parm-3.c
@@ -0,0 +1,50 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-parameter=3" } */
+
+void baz (int);
+
+void
+foo (int a,            /* { dg-warning "parameter 'a' set but not used" } */
+     int b,            /* { dg-warning "parameter 'b' set but not used" } */
+     int c,            /* { dg-warning "parameter 'c' set but not used" } */
+     int d,            /* { dg-warning "parameter 'd' set but not used" } */
+     int e,            /* { dg-warning "parameter 'e' set but not used" } */
+     int f,            /* { dg-warning "parameter 'f' set but not used" } */
+     int g,            /* { dg-warning "parameter 'g' set but not used" } */
+     int h,            /* { dg-warning "parameter 'h' set but not used" } */
+     int i,            /* { dg-warning "parameter 'i' set but not used" } */
+     int j,            /* { dg-warning "parameter 'j' set but not used" } */
+     int k,            /* { dg-warning "parameter 'k' set but not used" } */
+     int l,            /* { dg-warning "parameter 'l' set but not used" } */
+     int m)            /* { dg-warning "parameter 'm' set but not used" } */
+{
+  a = 1;
+  ++b;
+  c++;
+  --d;
+  e--;
+  f += 2;
+  g |= 2;
+  h -= 2;
+  i &= 2;
+  j ^= 2;
+  k *= 2;
+  l %= 2;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
+     int k, int l, int m, int n)
+{
+  b = ++a;
+  d = --c;
+  f = e--;
+  h = g++;
+  j = i += 42;
+  l = k *= 4;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-parm-4.c 
b/gcc/testsuite/c-c++-common/Wunused-parm-4.c
new file mode 100644
index 000000000000..063b40fb24f5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-parm-4.c
@@ -0,0 +1,50 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-parameter=2" } */
+
+void baz (int);
+
+void
+foo (int a,            /* { dg-warning "parameter 'a' set but not used" } */
+     int b,            /* { dg-warning "parameter 'b' set but not used" } */
+     int c,            /* { dg-warning "parameter 'c' set but not used" } */
+     int d,            /* { dg-warning "parameter 'd' set but not used" } */
+     int e,            /* { dg-warning "parameter 'e' set but not used" } */
+     int f,
+     int g,
+     int h,
+     int i,
+     int j,
+     int k,
+     int l,
+     int m)            /* { dg-warning "parameter 'm' set but not used" } */
+{
+  a = 1;
+  ++b;
+  c++;
+  --d;
+  e--;
+  f += 2;
+  g |= 2;
+  h -= 2;
+  i &= 2;
+  j ^= 2;
+  k *= 2;
+  l %= 2;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
+     int k, int l, int m, int n)
+{
+  b = ++a;
+  d = --c;
+  f = e--;
+  h = g++;
+  j = i += 42;
+  l = k *= 4;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-parm-5.c 
b/gcc/testsuite/c-c++-common/Wunused-parm-5.c
new file mode 100644
index 000000000000..1c80a8240864
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-parm-5.c
@@ -0,0 +1,50 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-parameter=1" } */
+
+void baz (int);
+
+void
+foo (int a,            /* { dg-warning "parameter 'a' set but not used" } */
+     int b,
+     int c,
+     int d,
+     int e,
+     int f,
+     int g,
+     int h,
+     int i,
+     int j,
+     int k,
+     int l,
+     int m)
+{
+  a = 1;
+  ++b;
+  c++;
+  --d;
+  e--;
+  f += 2;
+  g |= 2;
+  h -= 2;
+  i &= 2;
+  j ^= 2;
+  k *= 2;
+  l %= 2;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
+     int k, int l, int m, int n)
+{
+  b = ++a;
+  d = --c;
+  f = e--;
+  h = g++;
+  j = i += 42;
+  l = k *= 4;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-parm-6.c 
b/gcc/testsuite/c-c++-common/Wunused-parm-6.c
new file mode 100644
index 000000000000..ee328bd75e1f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-parm-6.c
@@ -0,0 +1,50 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-parameter=0" } */
+
+void baz (int);
+
+void
+foo (int a,
+     int b,
+     int c,
+     int d,
+     int e,
+     int f,
+     int g,
+     int h,
+     int i,
+     int j,
+     int k,
+     int l,
+     int m)
+{
+  a = 1;
+  ++b;
+  c++;
+  --d;
+  e--;
+  f += 2;
+  g |= 2;
+  h -= 2;
+  i &= 2;
+  j ^= 2;
+  k *= 2;
+  l %= 2;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
+     int k, int l, int m, int n)
+{
+  b = ++a;
+  d = --c;
+  f = e--;
+  h = g++;
+  j = i += 42;
+  l = k *= 4;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-var-19.c 
b/gcc/testsuite/c-c++-common/Wunused-var-19.c
new file mode 100644
index 000000000000..32c47e688461
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-var-19.c
@@ -0,0 +1,60 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-variable" } */
+
+void baz (int);
+
+void
+foo (void)
+{
+  int a = 0;           /* { dg-warning "variable 'a' set but not used" } */
+  a = 1;
+  int b = 0;           /* { dg-warning "variable 'b' set but not used" } */
+  ++b;
+  int c = 0;           /* { dg-warning "variable 'c' set but not used" } */
+  c++;
+  int d = 0;           /* { dg-warning "variable 'd' set but not used" } */
+  --d;
+  int e = 0;           /* { dg-warning "variable 'e' set but not used" } */
+  e--;
+  int f = 0;           /* { dg-warning "variable 'f' set but not used" } */
+  f += 2;
+  int g = 0;           /* { dg-warning "variable 'g' set but not used" } */
+  g |= 2;
+  int h = 0;           /* { dg-warning "variable 'h' set but not used" } */
+  h -= 2;
+  int i = 0;           /* { dg-warning "variable 'i' set but not used" } */
+  i &= 2;
+  int j = 0;           /* { dg-warning "variable 'j' set but not used" } */
+  j ^= 2;
+  int k = 0;           /* { dg-warning "variable 'k' set but not used" } */
+  k *= 2;
+  int l = 0;           /* { dg-warning "variable 'l' set but not used" } */
+  l %= 2;
+  int m = 0;           /* { dg-warning "variable 'm' set but not used" } */
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (void)
+{
+  int a = 0;
+  int b = ++a;
+  int c = 0;
+  int d = --c;
+  int e = 0;
+  int f = e--;
+  int g = 0;
+  int h = g++;
+  int i = 0;
+  int j;
+  j = i += 42;
+  int k = 0;
+  int l;
+  l = k *= 4;
+  int m = 0;
+  int n;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-var-20.c 
b/gcc/testsuite/c-c++-common/Wunused-var-20.c
new file mode 100644
index 000000000000..e25b26b63e87
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-var-20.c
@@ -0,0 +1,60 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused" } */
+
+void baz (int);
+
+void
+foo (void)
+{
+  int a = 0;           /* { dg-warning "variable 'a' set but not used" } */
+  a = 1;
+  int b = 0;           /* { dg-warning "variable 'b' set but not used" } */
+  ++b;
+  int c = 0;           /* { dg-warning "variable 'c' set but not used" } */
+  c++;
+  int d = 0;           /* { dg-warning "variable 'd' set but not used" } */
+  --d;
+  int e = 0;           /* { dg-warning "variable 'e' set but not used" } */
+  e--;
+  int f = 0;           /* { dg-warning "variable 'f' set but not used" } */
+  f += 2;
+  int g = 0;           /* { dg-warning "variable 'g' set but not used" } */
+  g |= 2;
+  int h = 0;           /* { dg-warning "variable 'h' set but not used" } */
+  h -= 2;
+  int i = 0;           /* { dg-warning "variable 'i' set but not used" } */
+  i &= 2;
+  int j = 0;           /* { dg-warning "variable 'j' set but not used" } */
+  j ^= 2;
+  int k = 0;           /* { dg-warning "variable 'k' set but not used" } */
+  k *= 2;
+  int l = 0;           /* { dg-warning "variable 'l' set but not used" } */
+  l %= 2;
+  int m = 0;           /* { dg-warning "variable 'm' set but not used" } */
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (void)
+{
+  int a = 0;
+  int b = ++a;
+  int c = 0;
+  int d = --c;
+  int e = 0;
+  int f = e--;
+  int g = 0;
+  int h = g++;
+  int i = 0;
+  int j;
+  j = i += 42;
+  int k = 0;
+  int l;
+  l = k *= 4;
+  int m = 0;
+  int n;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-var-21.c 
b/gcc/testsuite/c-c++-common/Wunused-var-21.c
new file mode 100644
index 000000000000..0732d98f6c11
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-var-21.c
@@ -0,0 +1,60 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-variable=3" } */
+
+void baz (int);
+
+void
+foo (void)
+{
+  int a = 0;           /* { dg-warning "variable 'a' set but not used" } */
+  a = 1;
+  int b = 0;           /* { dg-warning "variable 'b' set but not used" } */
+  ++b;
+  int c = 0;           /* { dg-warning "variable 'c' set but not used" } */
+  c++;
+  int d = 0;           /* { dg-warning "variable 'd' set but not used" } */
+  --d;
+  int e = 0;           /* { dg-warning "variable 'e' set but not used" } */
+  e--;
+  int f = 0;           /* { dg-warning "variable 'f' set but not used" } */
+  f += 2;
+  int g = 0;           /* { dg-warning "variable 'g' set but not used" } */
+  g |= 2;
+  int h = 0;           /* { dg-warning "variable 'h' set but not used" } */
+  h -= 2;
+  int i = 0;           /* { dg-warning "variable 'i' set but not used" } */
+  i &= 2;
+  int j = 0;           /* { dg-warning "variable 'j' set but not used" } */
+  j ^= 2;
+  int k = 0;           /* { dg-warning "variable 'k' set but not used" } */
+  k *= 2;
+  int l = 0;           /* { dg-warning "variable 'l' set but not used" } */
+  l %= 2;
+  int m = 0;           /* { dg-warning "variable 'm' set but not used" } */
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (void)
+{
+  int a = 0;
+  int b = ++a;
+  int c = 0;
+  int d = --c;
+  int e = 0;
+  int f = e--;
+  int g = 0;
+  int h = g++;
+  int i = 0;
+  int j;
+  j = i += 42;
+  int k = 0;
+  int l;
+  l = k *= 4;
+  int m = 0;
+  int n;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-var-22.c 
b/gcc/testsuite/c-c++-common/Wunused-var-22.c
new file mode 100644
index 000000000000..84f57c59d05c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-var-22.c
@@ -0,0 +1,60 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-variable=2" } */
+
+void baz (int);
+
+void
+foo (void)
+{
+  int a = 0;           /* { dg-warning "variable 'a' set but not used" } */
+  a = 1;
+  int b = 0;           /* { dg-warning "variable 'b' set but not used" } */
+  ++b;
+  int c = 0;           /* { dg-warning "variable 'c' set but not used" } */
+  c++;
+  int d = 0;           /* { dg-warning "variable 'd' set but not used" } */
+  --d;
+  int e = 0;           /* { dg-warning "variable 'e' set but not used" } */
+  e--;
+  int f = 0;
+  f += 2;
+  int g = 0;
+  g |= 2;
+  int h = 0;
+  h -= 2;
+  int i = 0;
+  i &= 2;
+  int j = 0;
+  j ^= 2;
+  int k = 0;
+  k *= 2;
+  int l = 0;
+  l %= 2;
+  int m = 0;           /* { dg-warning "variable 'm' set but not used" } */
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (void)
+{
+  int a = 0;
+  int b = ++a;
+  int c = 0;
+  int d = --c;
+  int e = 0;
+  int f = e--;
+  int g = 0;
+  int h = g++;
+  int i = 0;
+  int j;
+  j = i += 42;
+  int k = 0;
+  int l;
+  l = k *= 4;
+  int m = 0;
+  int n;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-var-23.c 
b/gcc/testsuite/c-c++-common/Wunused-var-23.c
new file mode 100644
index 000000000000..b74c3f4652a5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-var-23.c
@@ -0,0 +1,60 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-variable=1" } */
+
+void baz (int);
+
+void
+foo (void)
+{
+  int a = 0;           /* { dg-warning "variable 'a' set but not used" } */
+  a = 1;
+  int b = 0;
+  ++b;
+  int c = 0;
+  c++;
+  int d = 0;
+  --d;
+  int e = 0;
+  e--;
+  int f = 0;
+  f += 2;
+  int g = 0;
+  g |= 2;
+  int h = 0;
+  h -= 2;
+  int i = 0;
+  i &= 2;
+  int j = 0;
+  j ^= 2;
+  int k = 0;
+  k *= 2;
+  int l = 0;
+  l %= 2;
+  int m = 0;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (void)
+{
+  int a = 0;
+  int b = ++a;
+  int c = 0;
+  int d = --c;
+  int e = 0;
+  int f = e--;
+  int g = 0;
+  int h = g++;
+  int i = 0;
+  int j;
+  j = i += 42;
+  int k = 0;
+  int l;
+  l = k *= 4;
+  int m = 0;
+  int n;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-var-24.c 
b/gcc/testsuite/c-c++-common/Wunused-var-24.c
new file mode 100644
index 000000000000..a59f50a09048
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wunused-var-24.c
@@ -0,0 +1,60 @@
+/* PR c/44677 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wunused-but-set-variable=0" } */
+
+void baz (int);
+
+void
+foo (void)
+{
+  int a = 0;
+  a = 1;
+  int b = 0;
+  ++b;
+  int c = 0;
+  c++;
+  int d = 0;
+  --d;
+  int e = 0;
+  e--;
+  int f = 0;
+  f += 2;
+  int g = 0;
+  g |= 2;
+  int h = 0;
+  h -= 2;
+  int i = 0;
+  i &= 2;
+  int j = 0;
+  j ^= 2;
+  int k = 0;
+  k *= 2;
+  int l = 0;
+  l %= 2;
+  int m = 0;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+int
+bar (void)
+{
+  int a = 0;
+  int b = ++a;
+  int c = 0;
+  int d = --c;
+  int e = 0;
+  int f = e--;
+  int g = 0;
+  int h = g++;
+  int i = 0;
+  int j;
+  j = i += 42;
+  int k = 0;
+  int l;
+  l = k *= 4;
+  int m = 0;
+  int n;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
diff --git a/gcc/testsuite/c-c++-common/Wunused-var-7.c 
b/gcc/testsuite/c-c++-common/Wunused-var-7.c
index 74196436db88..ea6babda683f 100644
--- a/gcc/testsuite/c-c++-common/Wunused-var-7.c
+++ b/gcc/testsuite/c-c++-common/Wunused-var-7.c
@@ -24,7 +24,7 @@ foo (void)
 void
 bar (void)
 {
-  int a;
+  int a;               /* { dg-warning "set but not used" } */
   int b;
   int c;               /* { dg-warning "set but not used" } */
   a = 1;
@@ -36,7 +36,7 @@ bar (void)
 void
 baz (void)
 {
-  int a;
+  int a;               /* { dg-warning "set but not used" } */
   int b;
   int c;
   int d;
diff --git a/gcc/testsuite/g++.dg/cpp26/name-independent-decl1.C 
b/gcc/testsuite/g++.dg/cpp26/name-independent-decl1.C
index 0830ce863f9d..9b56e841583f 100644
--- a/gcc/testsuite/g++.dg/cpp26/name-independent-decl1.C
+++ b/gcc/testsuite/g++.dg/cpp26/name-independent-decl1.C
@@ -70,7 +70,7 @@ foo ()
       ++_;
     }
     {
-      static int _ = 3;
+      static int _ = 3;                // { dg-warning "variable '_' set but 
not used" }
       ++_;
     }
     {
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-parm-12.C 
b/gcc/testsuite/g++.dg/warn/Wunused-parm-12.C
new file mode 100644
index 000000000000..03029f92206d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-parm-12.C
@@ -0,0 +1,59 @@
+// PR c/44677
+// { dg-do compile }
+// { dg-options "-O2 -Wunused-but-set-parameter" }
+
+void baz (int);
+
+template <int N>
+void
+foo (int a,            // { dg-warning "parameter 'a' set but not used" }
+     int b,            // { dg-warning "parameter 'b' set but not used" }
+     int c,            // { dg-warning "parameter 'c' set but not used" }
+     int d,            // { dg-warning "parameter 'd' set but not used" }
+     int e,            // { dg-warning "parameter 'e' set but not used" }
+     int f,            // { dg-warning "parameter 'f' set but not used" }
+     int g,            // { dg-warning "parameter 'g' set but not used" }
+     int h,            // { dg-warning "parameter 'h' set but not used" }
+     int i,            // { dg-warning "parameter 'i' set but not used" }
+     int j,            // { dg-warning "parameter 'j' set but not used" }
+     int k,            // { dg-warning "parameter 'k' set but not used" }
+     int l,            // { dg-warning "parameter 'l' set but not used" }
+     int m)            // { dg-warning "parameter 'm' set but not used" }
+{
+  a = 1;
+  ++b;
+  c++;
+  --d;
+  e--;
+  f += 2;
+  g |= 2;
+  h -= 2;
+  i &= 2;
+  j ^= 2;
+  k *= 2;
+  l %= 2;
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+template <int N>
+int
+bar (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
+     int k, int l, int m, int n)
+{
+  b = ++a;
+  d = --c;
+  f = e--;
+  h = g++;
+  j = i += 42;
+  l = k *= 4;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
+
+void
+test ()
+{
+  foo <0> (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+  bar <0> (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-parm-13.C 
b/gcc/testsuite/g++.dg/warn/Wunused-parm-13.C
new file mode 100644
index 000000000000..f2d357f85e60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-parm-13.C
@@ -0,0 +1,59 @@
+// PR c/44677
+// { dg-do compile }
+// { dg-options "-O2 -Wunused-but-set-parameter" }
+
+void baz (int);
+
+template <typename T>
+void
+foo (T a,              // { dg-warning "parameter 'a' set but not used" }
+     T b,              // { dg-warning "parameter 'b' set but not used" }
+     T c,              // { dg-warning "parameter 'c' set but not used" }
+     T d,              // { dg-warning "parameter 'd' set but not used" }
+     T e,              // { dg-warning "parameter 'e' set but not used" }
+     T f,              // { dg-warning "parameter 'f' set but not used" }
+     T g,              // { dg-warning "parameter 'g' set but not used" }
+     T h,              // { dg-warning "parameter 'h' set but not used" }
+     T i,              // { dg-warning "parameter 'i' set but not used" }
+     T j,              // { dg-warning "parameter 'j' set but not used" }
+     T k,              // { dg-warning "parameter 'k' set but not used" }
+     T l,              // { dg-warning "parameter 'l' set but not used" }
+     T m)              // { dg-warning "parameter 'm' set but not used" }
+{
+  a = 1;
+  ++b;
+  c++;
+  --d;
+  e--;
+  f += 2;
+  g |= 2;
+  h -= 2;
+  i &= 2;
+  j ^= 2;
+  k *= 2;
+  l %= 2;
+  for (T n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+template <typename T>
+T
+bar (T a, T b, T c, T d, T e, T f, T g, T h, T i, T j,
+     T k, T l, T m, T n)
+{
+  b = ++a;
+  d = --c;
+  f = e--;
+  h = g++;
+  j = i += 42;
+  l = k *= 4;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
+
+void
+test ()
+{
+  foo <int> (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+  bar <int> (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-2.C 
b/gcc/testsuite/g++.dg/warn/Wunused-var-2.C
index 0b21ef116257..869065fda63b 100644
--- a/gcc/testsuite/g++.dg/warn/Wunused-var-2.C
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-2.C
@@ -18,9 +18,9 @@ f1 ()
 }
 
 void
-f2 (int x)
+f2 (int x)     // { dg-warning "parameter 'x' set but not used" }
 {
-  int a = 0;
+  int a = 0;   // { dg-warning "variable 'a' set but not used" }
   x++;
   ++a;
 }
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-40.C 
b/gcc/testsuite/g++.dg/warn/Wunused-var-40.C
new file mode 100644
index 000000000000..935136769a0c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-40.C
@@ -0,0 +1,69 @@
+// PR c/44677
+// { dg-do compile }
+// { dg-options "-O2 -Wunused-but-set-variable" }
+
+void baz (int);
+
+template <int N>
+void
+foo (void)
+{
+  int a = 0;           // { dg-warning "variable 'a' set but not used" }
+  a = 1;
+  int b = 0;           // { dg-warning "variable 'b' set but not used" }
+  ++b;
+  int c = 0;           // { dg-warning "variable 'c' set but not used" }
+  c++;
+  int d = 0;           // { dg-warning "variable 'd' set but not used" }
+  --d;
+  int e = 0;           // { dg-warning "variable 'e' set but not used" }
+  e--;
+  int f = 0;           // { dg-warning "variable 'f' set but not used" }
+  f += 2;
+  int g = 0;           // { dg-warning "variable 'g' set but not used" }
+  g |= 2;
+  int h = 0;           // { dg-warning "variable 'h' set but not used" }
+  h -= 2;
+  int i = 0;           // { dg-warning "variable 'i' set but not used" }
+  i &= 2;
+  int j = 0;           // { dg-warning "variable 'j' set but not used" }
+  j ^= 2;
+  int k = 0;           // { dg-warning "variable 'k' set but not used" }
+  k *= 2;
+  int l = 0;           // { dg-warning "variable 'l' set but not used" }
+  l %= 2;
+  int m = 0;           // { dg-warning "variable 'm' set but not used" }
+  for (int n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+template <int N>
+int
+bar (void)
+{
+  int a = 0;
+  int b = ++a;
+  int c = 0;
+  int d = --c;
+  int e = 0;
+  int f = e--;
+  int g = 0;
+  int h = g++;
+  int i = 0;
+  int j;
+  j = i += 42;
+  int k = 0;
+  int l;
+  l = k *= 4;
+  int m = 0;
+  int n;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
+
+void
+test ()
+{
+  foo <0> ();
+  bar <0> ();
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-41.C 
b/gcc/testsuite/g++.dg/warn/Wunused-var-41.C
new file mode 100644
index 000000000000..ff981ee6ec34
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-41.C
@@ -0,0 +1,69 @@
+// PR c/44677
+// { dg-do compile }
+// { dg-options "-O2 -Wunused-but-set-variable" }
+
+void baz (int);
+
+template <typename T>
+void
+foo (void)
+{
+  T a = 0;             // { dg-warning "variable 'a' set but not used" }
+  a = 1;
+  T b = 0;             // { dg-warning "variable 'b' set but not used" }
+  ++b;
+  T c = 0;             // { dg-warning "variable 'c' set but not used" }
+  c++;
+  T d = 0;             // { dg-warning "variable 'd' set but not used" }
+  --d;
+  T e = 0;             // { dg-warning "variable 'e' set but not used" }
+  e--;
+  T f = 0;             // { dg-warning "variable 'f' set but not used" }
+  f += 2;
+  T g = 0;             // { dg-warning "variable 'g' set but not used" }
+  g |= 2;
+  T h = 0;             // { dg-warning "variable 'h' set but not used" }
+  h -= 2;
+  T i = 0;             // { dg-warning "variable 'i' set but not used" }
+  i &= 2;
+  T j = 0;             // { dg-warning "variable 'j' set but not used" }
+  j ^= 2;
+  T k = 0;             // { dg-warning "variable 'k' set but not used" }
+  k *= 2;
+  T l = 0;             // { dg-warning "variable 'l' set but not used" }
+  l %= 2;
+  T m = 0;             // { dg-warning "variable 'm' set but not used" }
+  for (T n = 4; n < 10; n++, m++)
+    baz (n);
+}
+
+template <typename T>
+T
+bar (void)
+{
+  T a = 0;
+  T b = ++a;
+  T c = 0;
+  T d = --c;
+  T e = 0;
+  T f = e--;
+  T g = 0;
+  T h = g++;
+  T i = 0;
+  T j;
+  j = i += 42;
+  T k = 0;
+  T l;
+  l = k *= 4;
+  T m = 0;
+  T n;
+  n = m |= 2;
+  return b + d + f + h + j + l + n;
+}
+
+void
+test ()
+{
+  foo <int> ();
+  bar <int> ();
+}
diff --git a/gcc/testsuite/gcc.dg/memchr-3.c b/gcc/testsuite/gcc.dg/memchr-3.c
index 9a3573519500..9caa2ac30f0b 100644
--- a/gcc/testsuite/gcc.dg/memchr-3.c
+++ b/gcc/testsuite/gcc.dg/memchr-3.c
@@ -17,9 +17,10 @@ struct SX
 const struct SX sx = { 0x1221 };
 const char sx_rep[] = { };
 
-void test_find (void)
+int test_find (void)
 {
   int n = 0, nb = (const char*)&sx.a - (const char*)&sx;
   const char *p = (const char*)&sx, *q = sx_rep;
   n += p + 1 == memchr (p, q[1], nb);
+  return n;
 }
diff --git a/gcc/testsuite/gcc.dg/unused-9.c b/gcc/testsuite/gcc.dg/unused-9.c
index bdf36e1f50e8..ad1ad0ec8abc 100644
--- a/gcc/testsuite/gcc.dg/unused-9.c
+++ b/gcc/testsuite/gcc.dg/unused-9.c
@@ -2,12 +2,9 @@
 /* { dg-do compile } */
 /* { dg-options "-Wunused" } */
 
-
 void g(void)
 {
-  int i = 0;
-  volatile int x;
-  (x, i++);    /* { dg-bogus "set but not used" } */
+  int i = 0;           /* { dg-warning "variable 'i' set but not used" } */
+  volatile int x;      /* { dg-bogus "variable 'x' set but not used" } */
+  (x, i++);
 }
-
-

Reply via email to