[{"id":3685163,"web_url":"http://patchwork.ozlabs.org/comment/3685163/","msgid":"<44d8281e-6529-4844-95fe-70edea1a4a70@redhat.com>","list_archive_url":null,"date":"2026-05-01T15:54:25","subject":"Re: [PATCH] c, c++, v2: Introduce -Wconstant-logical-operand warning\n [PR125081]","submitter":{"id":4337,"url":"http://patchwork.ozlabs.org/api/people/4337/","name":"Jason Merrill","email":"jason@redhat.com"},"content":"On 4/30/26 4:11 PM, Jakub Jelinek wrote:\n> On Thu, Apr 30, 2026 at 02:08:46PM -0400, Jason Merrill wrote:\n>>> I can certainly implement that.  Or just warn also whenever the constant is\n>>> 1 with some enum type originally, I don't see why people actually would write\n>>> enum { A, B }; if (x && B) unless it is a poor man's pre-C11 replacement of bool (so\n>>> say typedef enum BOOL { FALSE, TRUE } BOOL;\n>>> and using if (x && TRUE)).  Or warn for constant 1 if it has enum type and\n>>> the enum type contains more enumerators than just 0/1.  One can always get\n>>> rid of the warning by using && ENUM != 0 instead of just && ENUM and make\n>>> the code even more readable that way.\n>>\n>> Sounds good.\n> \n> Here is another version of the patch which implements that.\n> This version would have caught the && ff_genericize case.\n> \n> 2026-04-30  Jakub Jelinek  <jakub@redhat.com>\n> \n> \tPR c++/125081\n> gcc/doc/\n> \t* invoke.texi (Wconstant-logical-operand): Document.\n> gcc/c-family/\n> \t* c.opt (Wconstant-logical-operand): New option.\n> \t* c.opt.urls: Regenerate.\n> gcc/c/\n> \t* c-tree.h (parser_build_binary_op): Add ORIG_ARG1 argument.\n> \t* c-typeck.cc (parser_build_binary_op): Likewise.  Emit\n> \t-Wconstant-logical-operand warnings.\n> \t* c-parser.cc (c_parser_binary_expression): Adjust\n> \tparser_build_binary_op caller, pass to it the original\n> \tstack[sp - 1].expr.value before c_objc_common_truthvalue_conversion.\n> gcc/cp/\n> \t* typeck.cc (cp_build_binary_op): Emit -Wconstant-logical-operand\n> \twarnings.\n> \t* c-c++-common/Wconstant-logical-operand-1.c: New test.\n> \t* c-c++-common/Wconstant-logical-operand-2.c: New test.\n> \n> --- gcc/doc/invoke.texi.jj\t2026-04-30 10:18:13.834688557 +0200\n> +++ gcc/doc/invoke.texi\t2026-04-30 22:07:50.717947812 +0200\n> @@ -385,7 +385,7 @@ Objective-C and Objective-C++ Dialects}.\n>   -Wchar-subscripts\n>   -Wclobbered  -Wcomment\n>   -Wcompare-distinct-pointer-types\n> --Wno-complain-wrong-lang\n> +-Wno-complain-wrong-lang  -Wconstant-logical-operand\n>   -Wconversion  -Wno-coverage-mismatch  -Wno-cpp\n>   -Wdangling-else  -Wdangling-pointer  -Wdangling-pointer=@var{n}\n>   -Wdate-time\n> @@ -10647,6 +10647,22 @@ extern int a;\n>   if (a < 0 && a < 0) @{ @dots{} @}\n>   @end smallexample\n>   \n> +@opindex Wconstant-logical-operand\n> +@opindex Wno-constant-logical-operand\n> +@item -Wconstant-logical-operand\n> +Warn about another case of suspicious uses of logical operators in\n> +expressions, when neither operand of a logical operator is boolean\n> +and one of the operands is (or folds into) a constant other than 0 or 1,\n> +or enumerator with value 1 if the enumeral type contains enumerators with\n> +values other than 0 or 1.\n> +In such case the warning will suggest using corresponding bitwise operator.\n> +@smallexample\n> +extern int a;\n> +if (a && 64) @{ @dots{} @}\n> +@end smallexample\n> +If the warning is a false positive, one can clarify the code by using\n> +e.g. @code{a && 64 != 0} instead.\n> +\n>   @opindex Wlogical-not-parentheses\n>   @opindex Wno-logical-not-parentheses\n>   @item -Wlogical-not-parentheses\n> --- gcc/c-family/c.opt.jj\t2026-04-30 10:18:08.247786966 +0200\n> +++ gcc/c-family/c.opt\t2026-04-30 20:14:14.864156018 +0200\n> @@ -595,6 +595,10 @@ Wconditionally-supported\n>   C++ ObjC++ Var(warn_conditionally_supported) Warning\n>   Warn for conditionally-supported constructs.\n>   \n> +Wconstant-logical-operand\n> +C ObjC C++ ObjC++ Var(warn_constant_logical_operand) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)\n> +Warn for constant operands of logical operators other than 0 or 1.\n> +\n>   Wconversion\n>   C ObjC C++ ObjC++ Var(warn_conversion) Warning\n>   Warn for implicit type conversions that may change a value.\n> --- gcc/c-family/c.opt.urls.jj\t2026-04-30 10:18:08.248786948 +0200\n> +++ gcc/c-family/c.opt.urls\t2026-04-30 20:14:14.865118139 +0200\n> @@ -415,6 +415,9 @@ UrlSuffix(gcc/Warning-Options.html#index\n>   Wconditionally-supported\n>   UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wconditionally-supported)\n>   \n> +Wconstant-logical-operand\n> +UrlSuffix(gcc/Warning-Options.html#index-Wconstant-logical-operand)\n> +\n>   Wconversion\n>   UrlSuffix(gcc/Warning-Options.html#index-Wconversion) LangUrlSuffix_Fortran(gfortran/Error-and-Warning-Options.html#index-Wconversion)\n>   \n> --- gcc/c/c-typeck.cc.jj\t2026-04-30 10:18:08.260786737 +0200\n> +++ gcc/c/c-typeck.cc\t2026-04-30 21:18:33.663623866 +0200\n> @@ -5112,13 +5112,15 @@ char_type_p (tree type)\n>      in the input.  CODE, a tree_code, specifies the binary operator, and\n>      ARG1 and ARG2 are the operands.  In addition to constructing the\n>      expression, we check for operands that were written with other binary\n> -   operators in a way that is likely to confuse the user.\n> +   operators in a way that is likely to confuse the user.  ORIG_ARG1 is\n> +   the original first operand for TRUTH_{AND,OR}IF_EXPR before it is\n> +   converted to truth value, otherwise NULL_TREE.\n>   \n>      LOCATION is the location of the binary operator.  */\n>   \n>   struct c_expr\n>   parser_build_binary_op (location_t location, enum tree_code code,\n> -\t\t\tstruct c_expr arg1, struct c_expr arg2)\n> +\t\t\tstruct c_expr arg1, struct c_expr arg2, tree orig_arg1)\n>   {\n>     struct c_expr result;\n>     result.m_decimal = 0;\n> @@ -5163,6 +5165,55 @@ parser_build_binary_op (location_t locat\n>       warn_logical_operator (location, code, TREE_TYPE (result.value),\n>   \t\t\t   code1, arg1.value, code2, arg2.value);\n>   \n> +  if (warn_constant_logical_operand\n> +      && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)\n> +      && (TREE_CODE (type1) == INTEGER_TYPE\n> +\t  || TREE_CODE (type1) == ENUMERAL_TYPE\n> +\t  || TREE_CODE (type1) == BITINT_TYPE)\n> +      && (TREE_CODE (type2) == INTEGER_TYPE\n> +\t  || TREE_CODE (type2) == ENUMERAL_TYPE\n> +\t  || TREE_CODE (type2) == BITINT_TYPE))\n> +    {\n> +      const char *name = code == TRUTH_ANDIF_EXPR ? \"&&\" : \"||\";\n> +      if (orig_arg1 == NULL_TREE)\n> +\torig_arg1 = arg1.value;\n> +      auto enum_other_than_0_1 = [] (tree type) {\n> +\tif (TREE_CODE (type) != ENUMERAL_TYPE)\n> +\t  return false;\n> +\tfor (tree l = TYPE_VALUES (type); l; l = TREE_CHAIN (l))\n> +\t  {\n> +\t    tree v = DECL_INITIAL (TREE_VALUE (l));\n> +\t    if (!integer_zerop (v) && !integer_onep (v))\n> +\t      return true;\n> +\t  }\n> +\treturn false;\n> +      };\n> +      if (TREE_CODE (arg2.value) == INTEGER_CST\n> +\t  && !integer_zerop (arg2.value)\n> +\t  && (!integer_onep (arg2.value) || enum_other_than_0_1 (type2)))\n> +\t{\n> +\t  gcc_rich_location richloc (location);\n> +\t  richloc.add_fixit_replace (name + 1);\n> +\t  auto_diagnostic_group d;\n> +\t  if (warning_at (location, OPT_Wconstant_logical_operand,\n> +\t\t\t  \"use of logical %qs with constant operand %qE\",\n> +\t\t\t  name, arg2.value))\n> +\t    inform (&richloc, \"use %qs for bitwise operation\", name + 1);\n> +\t}\n> +      else if (TREE_CODE (orig_arg1) == INTEGER_CST\n> +\t       && !integer_zerop (orig_arg1)\n> +\t       && (!integer_onep (orig_arg1) || enum_other_than_0_1 (type1)))\n> +\t{\n> +\t  gcc_rich_location richloc (location);\n> +\t  richloc.add_fixit_replace (name + 1);\n> +\t  auto_diagnostic_group d;\n> +\t  if (warning_at (location, OPT_Wconstant_logical_operand,\n> +\t\t\t  \"use of logical %qs with constant operand %qE\",\n> +\t\t\t  name, orig_arg1))\n> +\t    inform (&richloc, \"use %qs for bitwise operation\", name + 1);\n> +\t}\n> +    }\n> +\n>     if (warn_tautological_compare)\n>       {\n>         tree lhs = arg1.value;\n> --- gcc/c/c-parser.cc.jj\t2026-04-30 10:18:13.802689121 +0200\n> +++ gcc/c/c-parser.cc\t2026-04-30 20:14:14.869155933 +0200\n> @@ -10304,6 +10304,9 @@ c_parser_binary_expression (c_parser *pa\n>       location_t loc;\n>       /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR.  */\n>       tree sizeof_arg;\n> +    /* The original expr.value before c_objc_common_truthvalue_conversion\n> +       for TRUTH_{AND,OR}*_EXPR lhs operands.  */\n> +    tree orig_expr;\n>     } stack[NUM_PRECS];\n>     int sp;\n>     /* Location of the binary operator.  */\n> @@ -10399,7 +10402,9 @@ c_parser_binary_expression (c_parser *pa\n>         stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,\t      \\\n>   \t\t\t\t\t\t   stack[sp].op,\t      \\\n>   \t\t\t\t\t\t   stack[sp - 1].expr,\t      \\\n> -\t\t\t\t\t\t   stack[sp].expr);\t      \\\n> +\t\t\t\t\t\t   stack[sp].expr,\t      \\\n> +\t\t\t\t\t\t   stack[sp - 1].orig_expr);  \\\n> +    stack[sp - 1].orig_expr = NULL_TREE;\t\t\t\t      \\\n>       sp--;\t\t\t\t\t\t\t\t      \\\n>     } while (0)\n>     gcc_assert (!after || c_dialect_objc ());\n> @@ -10407,6 +10412,7 @@ c_parser_binary_expression (c_parser *pa\n>     stack[0].expr = c_parser_cast_expression (parser, after);\n>     stack[0].prec = PREC_NONE;\n>     stack[0].sizeof_arg = c_last_sizeof_arg;\n> +  stack[0].orig_expr = NULL_TREE;\n>     sp = 0;\n>     while (true)\n>       {\n> @@ -10505,6 +10511,7 @@ c_parser_binary_expression (c_parser *pa\n>   \t  stack[sp].expr\n>   \t    = convert_lvalue_to_rvalue (stack[sp].loc,\n>   \t\t\t\t\tstack[sp].expr, true, true);\n> +\t  stack[sp].orig_expr = stack[sp].expr.value;\n>   \t  stack[sp].expr.value = c_objc_common_truthvalue_conversion\n>   \t    (stack[sp].loc, default_conversion (stack[sp].expr.value));\n>   \t  c_inhibit_evaluation_warnings += (stack[sp].expr.value\n> @@ -10516,6 +10523,7 @@ c_parser_binary_expression (c_parser *pa\n>   \t  stack[sp].expr\n>   \t    = convert_lvalue_to_rvalue (stack[sp].loc,\n>   \t\t\t\t\tstack[sp].expr, true, true);\n> +\t  stack[sp].orig_expr = stack[sp].expr.value;\n>   \t  stack[sp].expr.value = c_objc_common_truthvalue_conversion\n>   \t    (stack[sp].loc, default_conversion (stack[sp].expr.value));\n>   \t  c_inhibit_evaluation_warnings += (stack[sp].expr.value\n> @@ -10531,6 +10539,7 @@ c_parser_binary_expression (c_parser *pa\n>         stack[sp].prec = oprec;\n>         stack[sp].op = ocode;\n>         stack[sp].sizeof_arg = c_last_sizeof_arg;\n> +      stack[sp].orig_expr = NULL_TREE;\n>       }\n>    out:\n>     while (sp > 0)\n> --- gcc/c/c-tree.h.jj\t2026-04-30 10:18:13.803689103 +0200\n> +++ gcc/c/c-tree.h\t2026-04-30 20:14:14.870460631 +0200\n> @@ -890,7 +890,7 @@ extern struct c_expr parser_build_unary_\n>       \t\t\t\t\t    struct c_expr);\n>   extern struct c_expr parser_build_binary_op (location_t,\n>       \t\t\t\t\t     enum tree_code, struct c_expr,\n> -\t\t\t\t\t     struct c_expr);\n> +\t\t\t\t\t     struct c_expr, tree);\n>   extern tree build_conditional_expr (location_t, tree, bool, tree, tree,\n>   \t\t\t\t    location_t, tree, tree, location_t);\n>   extern tree build_compound_expr (location_t, tree, tree);\n> --- gcc/cp/typeck.cc.jj\t2026-04-30 10:18:08.342785292 +0200\n> +++ gcc/cp/typeck.cc\t2026-04-30 21:18:00.423192892 +0200\n> @@ -5953,6 +5953,53 @@ cp_build_binary_op (const op_location_t\n>   \t  return cp_build_binary_op (location, code, op0, op1, complain);\n>   \t}\n>   \n> +      if (warn_constant_logical_operand\n> +\t  && (complain & tf_warning)\n> +\t  && (code0 == INTEGER_TYPE || code0 == ENUMERAL_TYPE)\n> +\t  && (code1 == INTEGER_TYPE || code1 == ENUMERAL_TYPE))\n> +\t{\n> +\t  tree cop0 = fold_for_warn (op0), cop1 = fold_for_warn (op1);\n> +\t  const char *name\n> +\t    = ((code == TRUTH_ANDIF_EXPR || code == TRUTH_AND_EXPR)\n> +\t       ? \"&&\" : \"||\");\n> +\t  auto enum_other_than_0_1 = [] (tree type) {\n> +\t    if (TREE_CODE (type) != ENUMERAL_TYPE)\n> +\t      return false;\n> +\t    for (tree l = TYPE_VALUES (type); l; l = TREE_CHAIN (l))\n> +\t      {\n> +\t\ttree v = DECL_INITIAL (TREE_VALUE (l));\n> +\t\tif (!integer_zerop (v) && !integer_onep (v))\n> +\t\t  return true;\n> +\t      }\n> +\t    return false;\n> +\t  };\n> +\t  if (TREE_CODE (cop1) == INTEGER_CST\n> +\t      && !integer_zerop (cop1)\n> +\t      && (!integer_onep (cop1) || enum_other_than_0_1 (orig_type1)))\n> +\t    {\n> +\t      gcc_rich_location richloc (location);\n> +\t      richloc.add_fixit_replace (location.m_operator_loc, name + 1);\n> +\t      auto_diagnostic_group d;\n> +\t      if (warning_at (location, OPT_Wconstant_logical_operand,\n> +\t\t\t      \"use of logical %qs with constant operand %qE\",\n> +\t\t\t      name, cop1))\n> +\t\tinform (&richloc, \"use %qs for bitwise operation\", name + 1);\n> +\t    }\n> +\t  else if (TREE_CODE (cop0) == INTEGER_CST\n> +\t\t   && !integer_zerop (cop0)\n> +\t\t   && (!integer_onep (cop0)\n> +\t\t       || enum_other_than_0_1 (orig_type0)))\n> +\t    {\n> +\t      gcc_rich_location richloc (location);\n> +\t      richloc.add_fixit_replace (location.m_operator_loc, name + 1);\n> +\t      auto_diagnostic_group d;\n> +\t      if (warning_at (location, OPT_Wconstant_logical_operand,\n> +\t\t\t      \"use of logical %qs with constant operand %qE\",\n> +\t\t\t      name, cop0))\n> +\t\tinform (&richloc, \"use %qs for bitwise operation\", name + 1);\n> +\t    }\n\nThis could also be factored into a lambda, rather than repeated?  The \nC++ changes are OK either way.\n\nJason\n\n\n> +\t}\n> +\n>         result_type = boolean_type_node;\n>         break;\n>   \n> --- gcc/testsuite/c-c++-common/Wconstant-logical-operand-1.c.jj\t2026-04-30 20:14:14.871996788 +0200\n> +++ gcc/testsuite/c-c++-common/Wconstant-logical-operand-1.c\t2026-04-30 21:23:09.467902519 +0200\n> @@ -0,0 +1,106 @@\n> +/* PR c++/125081 */\n> +/* { dg-do compile } */\n> +/* { dg-options \"-std=c23\" { target c } } */\n> +/* { dg-additional-options \"-Wconstant-logical-operand\" } */\n> +\n> +void foo (int);\n> +enum A { B, C };\n> +enum D { E, F, G, H, I };\n> +\n> +void\n> +bar (int x, bool y)\n> +{\n> +  if (x && 64)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '64'\" } */\n> +    foo (1);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (128 && x)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '128'\" } */\n> +    foo (2);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x && 1)\n> +    foo (3);\n> +  if (1 && x)\n> +    foo (4);\n> +  if (x && 0)\n> +    foo (5);\n> +  if (0 && x)\n> +    foo (6);\n> +  if (x || 32)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '32'\" } */\n> +    foo (7);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (256 || x)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '256'\" } */\n> +    foo (8);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x || 1)\n> +    foo (9);\n> +  if (1 || x)\n> +    foo (10);\n> +  if (x || 0)\n> +    foo (11);\n> +  if (0 || x)\n> +    foo (12);\n> +  if (y && 64)\n> +    foo (13);\n> +  if (128 && y)\n> +    foo (14);\n> +  if (y || 32)\n> +    foo (15);\n> +  if (256 || y)\n> +    foo (16);\n> +  if (x && B)\n> +    foo (17);\n> +  if (B && x)\n> +    foo (18);\n> +  if (x && C)\n> +    foo (19);\n> +  if (C && x)\n> +    foo (20);\n> +  if (x && E)\n> +    foo (21);\n> +  if (E && x)\n> +    foo (22);\n> +  if (x && F)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '\\[1F]'\" } */\n> +    foo (23);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (F && x)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '\\[1F]'\" } */\n> +    foo (24);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x && G)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '\\[2G]'\" } */\n> +    foo (25);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (G && x)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '\\[2G]'\" } */\n> +    foo (26);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x || B)\n> +    foo (27);\n> +  if (B || x)\n> +    foo (28);\n> +  if (x || C)\n> +    foo (29);\n> +  if (C || x)\n> +    foo (30);\n> +  if (x || E)\n> +    foo (31);\n> +  if (E || x)\n> +    foo (32);\n> +  if (x || F)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '\\[1F]'\" } */\n> +    foo (33);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (F || x)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '\\[1F]'\" } */\n> +    foo (34);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x || G)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '\\[2G]'\" } */\n> +    foo (35);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (G || x)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '\\[2G]'\" } */\n> +    foo (36);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +}\n> +\n> +void\n> +baz (int x, bool y)\n> +{\n> +  if (x && 63 + 1)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '64'\" } */\n> +    foo (1);\t\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (127 + 1 && x)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '128'\" } */\n> +    foo (2);\t\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x || 31 + 1)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '32'\" } */\n> +    foo (7);\t\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (255 + 1 || x)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '256'\" } */\n> +    foo (8);\t\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (y && 63 + 1)\n> +    foo (13);\n> +  if (127 + 1 && y)\n> +    foo (14);\n> +  if (y || 31 + 1)\n> +    foo (15);\n> +  if (255 + 1 || y)\n> +    foo (16);\n> +}\n> --- gcc/testsuite/c-c++-common/Wconstant-logical-operand-2.c.jj\t2026-04-30 20:14:14.872108767 +0200\n> +++ gcc/testsuite/c-c++-common/Wconstant-logical-operand-2.c\t2026-04-30 22:05:37.782226847 +0200\n> @@ -0,0 +1,110 @@\n> +/* PR c++/125081 */\n> +/* { dg-do compile } */\n> +/* { dg-options \"-std=c23\" { target c } } */\n> +/* { dg-additional-options \"-Wall\" } */\n> +\n> +void foo (int);\n> +enum A { B, C };\n> +enum D { E, F, G, H, I };\n> +\n> +void\n> +bar (int x, bool y)\n> +{\n> +  if (x && 64)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '64'\" } */\n> +    foo (1);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (128 && x)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '128'\" } */\n> +    foo (2);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x && 1)\n> +    foo (3);\n> +  if (1 && x)\n> +    foo (4);\n> +  if (x && 0)\n> +    foo (5);\n> +  if (0 && x)\n> +    foo (6);\n> +  if (x || 32)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '32'\" } */\n> +    foo (7);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (256 || x)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '256'\" } */\n> +    foo (8);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x || 1)\n> +    foo (9);\n> +  if (1 || x)\n> +    foo (10);\n> +  if (x || 0)\n> +    foo (11);\n> +  if (0 || x)\n> +    foo (12);\n> +  if (y && 64)\n> +    foo (13);\n> +  if (128 && y)\n> +    foo (14);\n> +  if (y || 32)\n> +    foo (15);\n> +  if (256 || y)\n> +    foo (16);\n> +  if (x && B)\n> +    foo (17);\n> +  if (B && x)\n> +    foo (18);\n> +  if (x && C)\n> +    foo (19);\n> +  if (C && x)\n> +    foo (20);\n> +  if (x && E)\n> +    foo (21);\n> +  if (E && x)\n> +    foo (22);\n> +  if (x && F)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '\\[1F]'\" } */\n> +    foo (23);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (F && x)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '\\[1F]'\" } */\n> +    foo (24);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x && G)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '\\[2G]'\" } */\n> +    foo (25);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +\t\t/* { dg-warning \"enum constant in boolean context\" \"\" { target c++ } .-2 } */\n> +  if (G && x)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '\\[2G]'\" } */\n> +    foo (26);\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +\t\t/* { dg-warning \"enum constant in boolean context\" \"\" { target c++ } .-2 } */\n> +  if (x || B)\n> +    foo (27);\n> +  if (B || x)\n> +    foo (28);\n> +  if (x || C)\n> +    foo (29);\n> +  if (C || x)\n> +    foo (30);\n> +  if (x || E)\n> +    foo (31);\n> +  if (E || x)\n> +    foo (32);\n> +  if (x || F)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '\\[1F]'\" } */\n> +    foo (33);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (F || x)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '\\[1F]'\" } */\n> +    foo (34);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x || G)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '\\[2G]'\" } */\n> +    foo (35);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +\t\t/* { dg-warning \"enum constant in boolean context\" \"\" { target c++ } .-2 } */\n> +  if (G || x)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '\\[2G]'\" } */\n> +    foo (36);\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +\t\t/* { dg-warning \"enum constant in boolean context\" \"\" { target c++ } .-2 } */\n> +}\n> +\n> +void\n> +baz (int x, bool y)\n> +{\n> +  if (x && 63 + 1)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '64'\" } */\n> +    foo (1);\t\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (127 + 1 && x)\t/* { dg-warning \"use of logical '\\\\\\&\\\\\\&' with constant operand '128'\" } */\n> +    foo (2);\t\t/* { dg-message \"note: use '\\\\\\&' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (x || 31 + 1)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '32'\" } */\n> +    foo (7);\t\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (255 + 1 || x)\t/* { dg-warning \"use of logical '\\\\\\|\\\\\\|' with constant operand '256'\" } */\n> +    foo (8);\t\t/* { dg-message \"note: use '\\\\\\|' for bitwise operation\" \"\" { target *-*-* } .-1 } */\n> +  if (y && 63 + 1)\n> +    foo (13);\n> +  if (127 + 1 && y)\n> +    foo (14);\n> +  if (y || 31 + 1)\n> +    foo (15);\n> +  if (255 + 1 || y)\n> +    foo (16);\n> +}\n> \n> \n> \tJakub\n>","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=hxaSuWrR;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=hxaSuWrR","sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","sourceware.org; spf=pass smtp.mailfrom=redhat.com","server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.129.124"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g6bGL3cCmz1xqf\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 02 May 2026 01:55:05 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 2041046A9CEB\n\tfor <incoming@patchwork.ozlabs.org>; Fri,  1 May 2026 15:55:03 +0000 (GMT)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id 10FCB4AA0963\n for <gcc-patches@gcc.gnu.org>; Fri,  1 May 2026 15:54:31 +0000 (GMT)","from mail-qv1-f71.google.com (mail-qv1-f71.google.com\n [209.85.219.71]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-581-K3KThRUnNzSWBbhoC12Duw-1; Fri, 01 May 2026 11:54:29 -0400","by mail-qv1-f71.google.com with SMTP id\n 6a1803df08f44-8b5ceedb5c1so10529806d6.0\n for <gcc-patches@gcc.gnu.org>; Fri, 01 May 2026 08:54:29 -0700 (PDT)","from [192.168.50.130]\n (130-44-146-247.s12789.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com.\n [130.44.146.247]) by smtp.gmail.com with ESMTPSA id\n 6a1803df08f44-8b53d0702aasm28818566d6.43.2026.05.01.08.54.25\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Fri, 01 May 2026 08:54:25 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 2041046A9CEB","OpenDKIM Filter v2.11.0 sourceware.org 10FCB4AA0963"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 10FCB4AA0963","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 10FCB4AA0963","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777650871; cv=none;\n b=S+tbDCPD58o+2Cz/KrWL5OaDItbMDJKJXSlyaqnkMf5ysqRdyk5VnhdevvwXAucUz8kT1LzX9XwLpX84ogymzDxl+TFsdiAcJNDeqkzQ2W+ce2ksefGh+Z+CkZHK33Ms7Ld4JKVjocRXI4KWDey26cCPBlsBIL1lmvfU3SZSxq8=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777650871; c=relaxed/simple;\n bh=+aOjY/l9tVUMBhk9n8SOQzH8viIkymbmPaJhNiXFM2Y=;\n h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From;\n b=lMmRmXD8VXpoWHBTQUihAJOSEHd46jl1QotuHLfM6IOEvPHcwNLyQX7+thuf5FO/Evoxao9bOV+eim/hhMcSjmI+hq3PstlI50+AqOFQgZ2RDe45c06g6UPNLbXY/PzgHJCXMWd8TTA35QcGpeQCCJ4KJQDP+TPvXa+DWixiI9I=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777650870;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=WLt5Lw9aq/9ABW2A33jJRsd3xdWrCQgJaLCgUXfcQuw=;\n b=hxaSuWrRuFORNOPpZi0uq0c27VLF8VQkYp6fxnTz07PHQavbvm1DvQ4qbAkOSSoqXVGe1X\n NtVCq+xw73D4j/CalKLVx0p0E74HQ67s3LE4O2X60AbFFLdqE65D+6va8/blheK4J9ceGF\n AHB3zW0Gp7fhpi1uo9D78OqdV99YwSI=","X-MC-Unique":"K3KThRUnNzSWBbhoC12Duw-1","X-Mimecast-MFC-AGG-ID":"K3KThRUnNzSWBbhoC12Duw_1777650869","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777650868; x=1778255668;\n h=content-transfer-encoding:in-reply-to:from:content-language\n :references:cc:to:subject:user-agent:mime-version:date:message-id\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=WLt5Lw9aq/9ABW2A33jJRsd3xdWrCQgJaLCgUXfcQuw=;\n b=QHhwi8L3rijgrTQb1dgKwhZEZBTwr3PLnM10Hf+d03KzgfVTQS20O6jkVFxMfYrYb8\n 6pWqlT37/xmv5PKTf1v7xv/bjVRUUQ/KIW+Xc9cnVyiuZz/OqHYQpMyKGBs54mqwbbZM\n 0Ibfdx9pp61SXAsNv3mcWchHgk4FAwA+dWpd2ZXBKys74o91ydHwsyXXg6K18pAR/FHR\n 8vm8c88GhI72I7CextCaZ0712cRxqKXePqF3JJ4bm3Gs2ijPIsgeLqQ4YelvZtciKghR\n /ay/y3Pm54clAGDR3nWnmO6drkr4oZ49dyZGYFSkE5Az5G/SLeCgNetnUtdSx51oM/9V\n ampw==","X-Gm-Message-State":"AOJu0YwveneJ4Ao5Gdqv7hsiSf5WXodH3JnxbCyq5X29C/QKp8lp0qqo\n gkBeN/D706uJYeF0BEtPzEcXNFZSOVzKb4uvB1+GXrLnxpR3kDWA8pvGx5uiPJKI62EIHqkPccC\n OKsj4uf6AdYZroe8SRwvW8lFYyWr5KCoYR25tjrDLWj6WDv4rcEgPo6rea16UQS8S11qcxg==","X-Gm-Gg":"AeBDieuPuDppoELpAwx2+I3B5amzOUYECnKaYz+IUWbiUdrged5IMKlMcbqKIYJjGh2\n 9ey7p7WeuowtDX+3xDz8IQv6Dq9K0BhJZ0N0zVtLpeXEknMtkfnnBYFSK6J5HR6lnbVf0t9gbre\n /UcdKl9kCxoX8uL+Gv4EmTnWsp7SddWgcwlL6kJEltUX4XfzNs+YoJgBr9M3I/eQZqinXadSH3p\n ua4HWXX73gG6jSnSsp2xG9zpVYyXLpTSm5q2kUChGXpnjZz/mC0YgRdi0xDjRf+ktwwqww5Z+55\n xqhIAojYxNy3IKCsMvzGdaIChLKeFzaQuSQpDk5OuZaPRnMQEak9goP9qgs90eHUBOHXyyuM4MD\n J3iv0eoAVjHaKaHrwVtNa+HRqO8t3YCTINckZ64/AI9Kb9nXSkSdkjGrxvtuKHJFwiJROXv89X2\n xRQIbiCcfM2dGtMptEYUvTptCRs9U4jxGILbcd86mQnA==","X-Received":["by 2002:a05:6214:2027:b0:8ac:7e8d:859b with SMTP id\n 6a1803df08f44-8b6665f1c0cmr1097256d6.16.1777650867306;\n Fri, 01 May 2026 08:54:27 -0700 (PDT)","by 2002:a05:6214:2027:b0:8ac:7e8d:859b with SMTP id\n 6a1803df08f44-8b6665f1c0cmr1096586d6.16.1777650866581;\n Fri, 01 May 2026 08:54:26 -0700 (PDT)"],"Message-ID":"<44d8281e-6529-4844-95fe-70edea1a4a70@redhat.com>","Date":"Fri, 1 May 2026 11:54:25 -0400","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] c, c++, v2: Introduce -Wconstant-logical-operand warning\n [PR125081]","To":"Jakub Jelinek <jakub@redhat.com>, \"Joseph S. Myers\"\n <josmyers@redhat.com>, Marek Polacek <polacek@redhat.com>","Cc":"gcc-patches@gcc.gnu.org","References":"<afMPwPZBZlyCU7TG@tucnak>\n <8d188ded-0e3a-426d-b3ef-6357cc98440f@redhat.com> <afNwI0F3WFI9i1bL@tucnak>\n <9acfb25a-8cb0-45f1-8059-d959d8e88b2a@redhat.com> <afO3cl6JJrYYVMVu@tucnak>","From":"Jason Merrill <jason@redhat.com>","In-Reply-To":"<afO3cl6JJrYYVMVu@tucnak>","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"EsnEVRZ5druwiORx61s9QTmr91CXM1LN8kPa6varcyg_1777650869","X-Mimecast-Originator":"redhat.com","Content-Language":"en-US","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}}]