Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2231959/?format=api
{ "id": 2231959, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2231959/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/afTZmG0U0aOVnvuW@tucnak/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/1.1/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<afTZmG0U0aOVnvuW@tucnak>", "date": "2026-05-01T16:49:28", "name": "c, c++, v3: Introduce -Wconstant-logical-operand warning [PR125081]", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "c2f50dfa3ece8d2a7c29a2e3c3f73b20333ec601", "submitter": { "id": 671, "url": "http://patchwork.ozlabs.org/api/1.1/people/671/?format=api", "name": "Jakub Jelinek", "email": "jakub@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/afTZmG0U0aOVnvuW@tucnak/mbox/", "series": [ { "id": 502485, "url": "http://patchwork.ozlabs.org/api/1.1/series/502485/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=502485", "date": "2026-05-01T16:49:28", "name": "c, c++, v3: Introduce -Wconstant-logical-operand warning [PR125081]", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/502485/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2231959/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2231959/checks/", "tags": {}, "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=QH+tPu5a;\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=QH+tPu5a", "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 4g6cTz261fz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 02 May 2026 02:50:13 +1000 (AEST)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id B99B044115D0\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 1 May 2026 16:50:11 +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 C8F8043B5511\n for <gcc-patches@gcc.gnu.org>; Fri, 1 May 2026 16:49:34 +0000 (GMT)", "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-549-BsCMgMXoOAayJCOW4j-gSw-1; Fri,\n 01 May 2026 12:49:33 -0400", "from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 29FAB1800364\n for <gcc-patches@gcc.gnu.org>; Fri, 1 May 2026 16:49:32 +0000 (UTC)", "from tucnak.zalov.cz (unknown [10.44.34.21])\n by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with\n ESMTPS\n id 486921800446; Fri, 1 May 2026 16:49:31 +0000 (UTC)", "from tucnak.zalov.cz (localhost [127.0.0.1])\n by tucnak.zalov.cz (8.18.1/8.18.1) with ESMTPS id 641GnSDJ2677898\n (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT);\n Fri, 1 May 2026 18:49:28 +0200", "(from jakub@localhost)\n by tucnak.zalov.cz (8.18.1/8.18.1/Submit) id 641GnSW22677897;\n Fri, 1 May 2026 18:49:28 +0200" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org B99B044115D0", "OpenDKIM Filter v2.11.0 sourceware.org C8F8043B5511" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org C8F8043B5511", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org C8F8043B5511", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777654174; cv=none;\n b=AYZoJs0pxFoIfv1U/8GnQy6HVKtvuBV3hp9TSmR/mVRxyiLqnzxUQQUP+G4M5Rv2GkcfzJun/2aSHGDvdyFCvqsfQIO5z3nXXbVdvATHIvcYUFLZ4CgUokxD9hrytCYb+v4FAhBqMEGuiNcEawxsyF45Brfgj9UEnqg0r25qnuY=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777654174; c=relaxed/simple;\n bh=5YsR7kTPApb4mScJp6hrfVR1fSt0kChCH6PpD7l9gx8=;\n h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;\n b=RlqNBOBgcGgmx+YJaJfmBrqgTAZD4NfrGU2bi2OPRuKq96zMHOG8PopF7bS6qAcQfxRPI3W2DLCo7KPcivmpnyYpsuY/h/XCAYJbJP9ZsQ7YTMe7FeKB9FjkE4Sbcm1OYP3Xm8apZ87sdd92ZgvGdmSzI2FcVcU0OW+Ge+MqTls=", "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=1777654174;\n h=from:from:reply-to:reply-to:subject:subject:date:date:\n message-id:message-id:to:to:cc:cc:mime-version:mime-version:\n content-type:content-type:in-reply-to:in-reply-to: references:references;\n bh=6sLsDgA91SW32PhPOCzmkGRbkF0Nv6XHgW07QsUzyig=;\n b=QH+tPu5aTYn2yyu1++gpkNicsjj50znGPsqt5If2yWRdd4O0Odw4MMDL5/U4Y9l2aWVNab\n ioGbkg82I4u6B1Zf9qSV+PhqiLZT0hOTgb2DEHZPsJP7cWXiVk8B9wGPnx2hzWDGZg7k6h\n UB7+PpEG71yX/XaxW8fm1ryQW4c/fDY=", "X-MC-Unique": "BsCMgMXoOAayJCOW4j-gSw-1", "X-Mimecast-MFC-AGG-ID": "BsCMgMXoOAayJCOW4j-gSw_1777654172", "Date": "Fri, 1 May 2026 18:49:28 +0200", "From": "Jakub Jelinek <jakub@redhat.com>", "To": "Jason Merrill <jason@redhat.com>, \"Joseph S. Myers\" <josmyers@redhat.com>,\n Marek Polacek <polacek@redhat.com>", "Cc": "gcc-patches@gcc.gnu.org", "Subject": "[PATCH] c, c++, v3: Introduce -Wconstant-logical-operand warning\n [PR125081]", "Message-ID": "<afTZmG0U0aOVnvuW@tucnak>", "References": "<afMPwPZBZlyCU7TG@tucnak>\n <8d188ded-0e3a-426d-b3ef-6357cc98440f@redhat.com>\n <afNwI0F3WFI9i1bL@tucnak>\n <9acfb25a-8cb0-45f1-8059-d959d8e88b2a@redhat.com>\n <afO3cl6JJrYYVMVu@tucnak>\n <44d8281e-6529-4844-95fe-70edea1a4a70@redhat.com>", "MIME-Version": "1.0", "In-Reply-To": "<44d8281e-6529-4844-95fe-70edea1a4a70@redhat.com>", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.111", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "ZgiQFYmk2l3JRbFQMWNbqbcfmioytSh7J4sEbxuO51E_1777654172", "X-Mimecast-Originator": "redhat.com", "Content-Type": "text/plain; charset=us-ascii", "Content-Disposition": "inline", "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>", "Reply-To": "Jakub Jelinek <jakub@redhat.com>", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "On Fri, May 01, 2026 at 11:54:25AM -0400, Jason Merrill wrote:\n> This could also be factored into a lambda, rather than repeated? The C++\n> changes are OK either way.\n\nGood idea. Here is what I'll retest tonight (made it a lambda for both C\nand C++ FEs).\n\n2026-05-01 Jakub Jelinek <jakub@redhat.com>\n\n\tPR c++/125081\ngcc/doc/\n\t* invoke.texi (Wconstant-logical-operand): Document.\ngcc/c-family/\n\t* c.opt (Wconstant-logical-operand): New option.\n\t* c.opt.urls: Regenerate.\ngcc/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.\ngcc/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\n\n\tJakub", "diff": "--- gcc/doc/invoke.texi.jj\t2026-05-01 08:32:06.568296638 +0200\n+++ gcc/doc/invoke.texi\t2026-05-01 18:01:47.677452253 +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-05-01 08:32:06.541297102 +0200\n+++ gcc/c-family/c.opt\t2026-05-01 18:01:47.678956153 +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-05-01 08:32:06.544297050 +0200\n+++ gcc/c-family/c.opt.urls\t2026-05-01 18:01:47.679211324 +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-05-01 08:32:06.558296810 +0200\n+++ gcc/c/c-typeck.cc\t2026-05-01 18:07:09.140112204 +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,47 @@ 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+ auto diagnose_constant_logical_operand = [=] (tree val, tree type) {\n+\tif (TREE_CODE (val) != INTEGER_CST || integer_zerop (val))\n+\t return false;\n+\tif (integer_onep (val) && !enum_other_than_0_1 (type))\n+\t return false;\n+\tgcc_rich_location richloc (location);\n+\trichloc.add_fixit_replace (name + 1);\n+\tauto_diagnostic_group d;\n+\tif (warning_at (location, OPT_Wconstant_logical_operand,\n+\t\t\t\"use of logical %qs with constant operand %qE\",\n+\t\t\tname, val))\n+\t inform (&richloc, \"use %qs for bitwise operation\", name + 1);\n+\treturn true;\n+ };\n+ if (!diagnose_constant_logical_operand (arg2.value, type2))\n+\tdiagnose_constant_logical_operand (orig_arg1, type1);\n+ }\n+\n if (warn_tautological_compare)\n {\n tree lhs = arg1.value;\n--- gcc/c/c-parser.cc.jj\t2026-05-01 08:32:06.553296896 +0200\n+++ gcc/c/c-parser.cc\t2026-05-01 18:01:47.681792212 +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-05-01 08:32:06.553296896 +0200\n+++ gcc/c/c-tree.h\t2026-05-01 18:01:47.683085944 +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-05-01 08:32:06.562296741 +0200\n+++ gcc/cp/typeck.cc\t2026-05-01 18:08:40.955586883 +0200\n@@ -5953,6 +5953,44 @@ 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 auto diagnose_constant_logical_operand = [=] (tree val, tree type) {\n+\t if (TREE_CODE (val) != INTEGER_CST || integer_zerop (val))\n+\t return false;\n+\t if (integer_onep (val) && !enum_other_than_0_1 (type))\n+\t return false;\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, val))\n+\t inform (&richloc, \"use %qs for bitwise operation\", name + 1);\n+\t return true;\n+\t };\n+\t if (!diagnose_constant_logical_operand (cop1, orig_type1))\n+\t diagnose_constant_logical_operand (cop0, orig_type0);\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-05-01 18:01:47.684201405 +0200\n+++ gcc/testsuite/c-c++-common/Wconstant-logical-operand-1.c\t2026-05-01 18:01:47.684201405 +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-05-01 18:01:47.684304880 +0200\n+++ gcc/testsuite/c-c++-common/Wconstant-logical-operand-2.c\t2026-05-01 18:01:47.684304880 +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", "prefixes": [] }