Hi! 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. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Though, I'm afraid the gofrontend part will need to go in separately through upstream. 2025-04-24 Jakub Jelinek <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 after cp_fold_rvalue for x = x OP y. * 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): Clear DECL_READ_P after cp_fully_fold for -Wunused-but-set-{parameter,variable}={2,3} on PRE{IN,DE}CREMENT_EXPR argument. * 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/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. --- gcc/common.opt.jj 2025-04-15 21:43:05.029214497 +0200 +++ gcc/common.opt 2025-04-23 21:33:19.025931935 +0200 @@ -853,11 +853,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 --- gcc/common.opt.urls.jj 2025-04-17 10:56:43.093328861 +0200 +++ gcc/common.opt.urls 2025-04-24 08:23:26.958220151 +0200 @@ -269,9 +269,15 @@ UrlSuffix(gcc/Warning-Options.html#index 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) --- gcc/diagnostic-spec.cc.jj 2025-01-02 20:54:32.122130018 +0100 +++ gcc/diagnostic-spec.cc 2025-04-23 21:33:19.026931922 +0200 @@ -72,9 +72,9 @@ nowarn_spec_t::nowarn_spec_t (opt_code o 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; --- gcc/gimple-ssa-store-merging.cc.jj 2025-01-02 20:54:32.239128399 +0100 +++ gcc/gimple-ssa-store-merging.cc 2025-04-23 23:16:06.760754906 +0200 @@ -644,9 +644,7 @@ find_bswap_or_nop_1 (gimple *stmt, struc /* 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; --- gcc/ipa-strub.cc.jj 2025-01-02 20:54:32.266128025 +0100 +++ gcc/ipa-strub.cc 2025-04-24 00:02:57.347838302 +0200 @@ -3060,6 +3060,8 @@ pass_ipa_strub::execute (function *) TYPE_ATTRIBUTES (TREE_TYPE (nnode->decl))); } } +#else + (void) named_args; #endif { --- gcc/doc/invoke.texi.jj 2025-04-23 21:32:50.747306995 +0200 +++ gcc/doc/invoke.texi 2025-04-23 21:33:19.031931856 +0200 @@ -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 @@ -7781,27 +7782,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 --- gcc/c-family/c-opts.cc.jj 2025-02-12 22:23:07.139772186 +0100 +++ gcc/c-family/c-opts.cc 2025-04-23 21:33:19.032931842 +0200 @@ -1217,6 +1217,17 @@ c_common_post_options (const char **pfil 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) --- gcc/c-family/c-attribs.cc.jj 2025-03-18 21:22:20.651027530 +0100 +++ gcc/c-family/c-attribs.cc 2025-04-23 21:57:19.077838901 +0200 @@ -5849,8 +5849,7 @@ build_attr_access_from_parms (tree parms 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)) --- gcc/c/c-parser.cc.jj 2025-04-02 23:02:22.019473781 +0200 +++ gcc/c/c-parser.cc 2025-04-23 21:33:19.040931736 +0200 @@ -10493,15 +10493,31 @@ c_parser_unary_expression (c_parser *par 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); @@ -13833,7 +13849,17 @@ c_parser_postfix_expression_after_primar 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); @@ -13845,7 +13871,17 @@ c_parser_postfix_expression_after_primar 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); --- gcc/c/c-decl.cc.jj 2025-04-09 18:28:23.515697147 +0200 +++ gcc/c/c-decl.cc 2025-04-23 21:33:19.043931697 +0200 @@ -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); } @@ -11486,9 +11486,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); } --- gcc/c/c-typeck.cc.jj 2025-04-16 18:24:17.674393580 +0200 +++ gcc/c/c-typeck.cc 2025-04-23 21:33:19.048931630 +0200 @@ -2316,14 +2316,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: @@ -7218,8 +7234,21 @@ build_modify_expr (location_t location, 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. */ --- gcc/cp/cp-gimplify.cc.jj 2025-04-12 21:41:42.660924514 +0200 +++ gcc/cp/cp-gimplify.cc 2025-04-23 21:33:19.050931604 +0200 @@ -3200,7 +3200,23 @@ 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) + && (VAR_P (op0) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 2 + && BINARY_CLASS_P (TREE_OPERAND (x, 1)) + && TREE_OPERAND (TREE_OPERAND (x, 1), 0) == op0) + { + mark_exp_read (TREE_OPERAND (TREE_OPERAND (x, 1), 1)); + if (!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 --- gcc/cp/decl.cc.jj 2025-04-22 21:26:15.719920897 +0200 +++ gcc/cp/decl.cc 2025-04-23 21:33:19.053931564 +0200 @@ -747,11 +747,11 @@ poplevel (int keep, int reverse, int fun { 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; } @@ -19423,14 +19423,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; } --- gcc/cp/expr.cc.jj 2025-01-02 20:54:32.078130627 +0100 +++ gcc/cp/expr.cc 2025-04-23 21:33:19.054931551 +0200 @@ -211,8 +211,27 @@ mark_use (tree expr, bool rvalue_p, bool } 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: --- gcc/cp/module.cc.jj 2025-04-14 15:02:23.751540802 +0200 +++ gcc/cp/module.cc 2025-04-24 00:00:18.975911347 +0200 @@ -10971,8 +10971,7 @@ trees_in::fn_parms_fini (int tag, tree f { 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) { --- gcc/cp/semantics.cc.jj 2025-04-22 21:26:15.735920684 +0200 +++ gcc/cp/semantics.cc 2025-04-23 21:33:19.057931511 +0200 @@ -3740,7 +3740,28 @@ finish_unary_op_expr (location_t op_loc, tree expr_ovl = expr; if (!processing_template_decl) - expr_ovl = cp_fully_fold (expr_ovl); + switch (code) + { + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + case POSTDECREMENT_EXPR: + tree stripped_expr; + stripped_expr = tree_strip_any_location_wrapper (expr); + if ((VAR_P (stripped_expr) || TREE_CODE (stripped_expr) == PARM_DECL) + && !DECL_READ_P (stripped_expr) + && (VAR_P (stripped_expr) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1) + { + expr_ovl = cp_fully_fold (expr_ovl); + DECL_READ_P (stripped_expr) = 0; + break; + } + /* FALLTHRU */ + default: + expr_ovl = cp_fully_fold (expr_ovl); + break; + } if (!CONSTANT_CLASS_P (expr_ovl) || TREE_OVERFLOW_P (expr_ovl)) --- gcc/cp/typeck.cc.jj 2025-04-01 21:52:48.490575729 +0200 +++ gcc/cp/typeck.cc 2025-04-23 21:33:19.060931471 +0200 @@ -7630,7 +7630,18 @@ cp_build_unary_op (enum tree_code code, 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. */ @@ -9746,7 +9757,22 @@ cp_build_modify_expr (location_t loc, tr { 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) --- gcc/go/gofrontend/gogo.cc.jj 2024-12-05 22:00:16.430164341 +0100 +++ gcc/go/gofrontend/gogo.cc 2025-04-24 00:02:29.930197191 +0200 @@ -5987,12 +5987,11 @@ Function::export_func_with_type(Export* 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; --- gcc/testsuite/c-c++-common/Wunused-parm-1.c.jj 2025-04-23 21:33:19.060931471 +0200 +++ gcc/testsuite/c-c++-common/Wunused-parm-1.c 2025-04-23 21:33:19.060931471 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-parm-2.c.jj 2025-04-23 21:33:19.060931471 +0200 +++ gcc/testsuite/c-c++-common/Wunused-parm-2.c 2025-04-23 21:33:19.060931471 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-parm-3.c.jj 2025-04-23 21:33:19.061931458 +0200 +++ gcc/testsuite/c-c++-common/Wunused-parm-3.c 2025-04-23 21:33:19.061931458 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-parm-4.c.jj 2025-04-23 21:33:19.061931458 +0200 +++ gcc/testsuite/c-c++-common/Wunused-parm-4.c 2025-04-23 21:33:19.061931458 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-parm-5.c.jj 2025-04-23 21:33:19.061931458 +0200 +++ gcc/testsuite/c-c++-common/Wunused-parm-5.c 2025-04-23 21:33:19.061931458 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-parm-6.c.jj 2025-04-23 21:33:19.061931458 +0200 +++ gcc/testsuite/c-c++-common/Wunused-parm-6.c 2025-04-23 21:33:19.061931458 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-var-7.c.jj 2020-01-14 20:02:46.643611931 +0100 +++ gcc/testsuite/c-c++-common/Wunused-var-7.c 2025-04-23 21:33:19.062931445 +0200 @@ -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; --- gcc/testsuite/c-c++-common/Wunused-var-19.c.jj 2025-04-23 21:33:19.061931458 +0200 +++ gcc/testsuite/c-c++-common/Wunused-var-19.c 2025-04-23 21:33:19.061931458 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-var-20.c.jj 2025-04-23 21:33:19.061931458 +0200 +++ gcc/testsuite/c-c++-common/Wunused-var-20.c 2025-04-23 21:33:19.061931458 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-var-21.c.jj 2025-04-23 21:33:19.061931458 +0200 +++ gcc/testsuite/c-c++-common/Wunused-var-21.c 2025-04-23 21:33:19.061931458 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-var-22.c.jj 2025-04-23 21:33:19.062931445 +0200 +++ gcc/testsuite/c-c++-common/Wunused-var-22.c 2025-04-23 21:33:19.062931445 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-var-23.c.jj 2025-04-23 21:33:19.062931445 +0200 +++ gcc/testsuite/c-c++-common/Wunused-var-23.c 2025-04-23 21:33:19.062931445 +0200 @@ -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; +} --- gcc/testsuite/c-c++-common/Wunused-var-24.c.jj 2025-04-23 21:33:19.062931445 +0200 +++ gcc/testsuite/c-c++-common/Wunused-var-24.c 2025-04-23 21:33:19.062931445 +0200 @@ -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; +} --- gcc/testsuite/g++.dg/cpp26/name-independent-decl1.C.jj 2023-11-30 22:24:40.962331534 +0100 +++ gcc/testsuite/g++.dg/cpp26/name-independent-decl1.C 2025-04-23 21:33:19.063931431 +0200 @@ -70,7 +70,7 @@ foo () ++_; } { - static int _ = 3; + static int _ = 3; // { dg-warning "variable '_' set but not used" } ++_; } { --- gcc/testsuite/g++.dg/warn/Wunused-parm-12.C.jj 2025-04-23 21:33:19.063931431 +0200 +++ gcc/testsuite/g++.dg/warn/Wunused-parm-12.C 2025-04-23 21:33:19.063931431 +0200 @@ -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); +} --- gcc/testsuite/g++.dg/warn/Wunused-parm-13.C.jj 2025-04-23 21:33:19.063931431 +0200 +++ gcc/testsuite/g++.dg/warn/Wunused-parm-13.C 2025-04-23 21:33:19.063931431 +0200 @@ -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); +} --- gcc/testsuite/g++.dg/warn/Wunused-var-2.C.jj 2020-01-14 20:02:47.003606539 +0100 +++ gcc/testsuite/g++.dg/warn/Wunused-var-2.C 2025-04-23 21:33:19.063931431 +0200 @@ -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; } --- gcc/testsuite/g++.dg/warn/Wunused-var-40.C.jj 2025-04-23 21:33:19.063931431 +0200 +++ gcc/testsuite/g++.dg/warn/Wunused-var-40.C 2025-04-23 21:33:19.063931431 +0200 @@ -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> (); +} --- gcc/testsuite/g++.dg/warn/Wunused-var-41.C.jj 2025-04-23 21:33:19.063931431 +0200 +++ gcc/testsuite/g++.dg/warn/Wunused-var-41.C 2025-04-23 21:33:19.063931431 +0200 @@ -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> (); +} --- gcc/testsuite/gcc.dg/memchr-3.c.jj 2024-01-08 23:26:44.000000000 +0100 +++ gcc/testsuite/gcc.dg/memchr-3.c 2025-04-24 07:57:16.045090120 +0200 @@ -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; } --- gcc/testsuite/gcc.dg/unused-9.c.jj 2020-12-17 13:33:09.000000000 +0100 +++ gcc/testsuite/gcc.dg/unused-9.c 2025-04-24 08:07:57.850543927 +0200 @@ -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++); } - - Jakub