Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2230915/?format=api
{ "id": 2230915, "url": "http://patchwork.ozlabs.org/api/patches/2230915/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/afMPwPZBZlyCU7TG@tucnak/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/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, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<afMPwPZBZlyCU7TG@tucnak>", "list_archive_url": null, "date": "2026-04-30T08:16:00", "name": "c, c++: Introduce -Wconstant-logical-operand warning [PR125081]", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "f246fc984cfcfcc1567a8d520b38adcabfa0d9d7", "submitter": { "id": 671, "url": "http://patchwork.ozlabs.org/api/people/671/?format=api", "name": "Jakub Jelinek", "email": "jakub@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/afMPwPZBZlyCU7TG@tucnak/mbox/", "series": [ { "id": 502230, "url": "http://patchwork.ozlabs.org/api/series/502230/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=502230", "date": "2026-04-30T08:16:00", "name": "c, c++: Introduce -Wconstant-logical-operand warning [PR125081]", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/502230/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2230915/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2230915/checks/", "tags": {}, "related": [], "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=eO+xsHLx;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.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=eO+xsHLx", "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.133.124" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org [38.145.34.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 4g5n7r541kz1yHZ\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 18:16:40 +1000 (AEST)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id D9EEE49002C0\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 08:16:38 +0000 (GMT)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id 21B254B9DB5B\n for <gcc-patches@gcc.gnu.org>; Thu, 30 Apr 2026 08:16:08 +0000 (GMT)", "from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-340-y3XL3C2oOVKAH9lp4g0RBQ-1; Thu,\n 30 Apr 2026 04:16:05 -0400", "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\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-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 9F9FF1956067\n for <gcc-patches@gcc.gnu.org>; Thu, 30 Apr 2026 08:16:04 +0000 (UTC)", "from tucnak.zalov.cz (unknown [10.44.34.21])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with\n ESMTPS\n id B10F11955D84; Thu, 30 Apr 2026 08:16:03 +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 63U8G1Ok3466221\n (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT);\n Thu, 30 Apr 2026 10:16:01 +0200", "(from jakub@localhost)\n by tucnak.zalov.cz (8.18.1/8.18.1/Submit) id 63U8G0U03466220;\n Thu, 30 Apr 2026 10:16:00 +0200" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org D9EEE49002C0", "OpenDKIM Filter v2.11.0 sourceware.org 21B254B9DB5B" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 21B254B9DB5B", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 21B254B9DB5B", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777536968; cv=none;\n b=a5GaJEO7IIXu1QoGWC4h85FRWWRmRTZiyfidMltHfZhM7PBuStYlD+NfkR/RW9F5rNnyu5GiqiWW1ik0nGeyEUYoZT4CbVz8U+TkiWlm2cxHYDqJ20E9/Nu2v5pLUhIS+2VHAmzk2pEWwbF3T9a7nm3v2bFhzHDKwcKz6pMglaY=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777536968; c=relaxed/simple;\n bh=30zTg4Dlv+ycomWd3R2z4O39VBFaiL07fiYIdydHQAM=;\n h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;\n b=Sxyu5veoe9CwPTseeuRpvbKGpNKnyT3Dl/3l4++ng/J/iMJKJ+WRtASMzdQ99/HJAmlC5AhRmuGqnCVXJFzpkaT2CJ/aPNSfFugfpKBPWbUFRO4KF14e3wstz8pkF+5AqoMjFa3IPIoBS563FA4fn59Hqo3tVhGnYnfwn6ui3nM=", "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=1777536967;\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; bh=E1nLri23SfEX+ljYiT6DY9aWzWhPCrvLzCJ1psZBXHg=;\n b=eO+xsHLxhGf0NcuIy79FyoKHesXmJQnAqtaygnuBeXLEPkSYZfqtKnQPk/CoC9NCTiI83p\n hQy55irKvPiJEo4FIOP6el+md2cRm+nlECTZdzJknYQqXCzeX0Qyqu4Gktaok9+oX74Tyu\n 0SHaJGvD+DCxfrejic3nFKuSr4z5FSA=", "X-MC-Unique": "y3XL3C2oOVKAH9lp4g0RBQ-1", "X-Mimecast-MFC-AGG-ID": "y3XL3C2oOVKAH9lp4g0RBQ_1777536964", "Date": "Thu, 30 Apr 2026 10:16:00 +0200", "From": "Jakub Jelinek <jakub@redhat.com>", "To": "\"Joseph S. Myers\" <josmyers@redhat.com>,\n Marek Polacek <polacek@redhat.com>, Jason Merrill <jason@redhat.com>,\n Patrick Palka <ppalka@redhat.com>", "Cc": "gcc-patches@gcc.gnu.org", "Subject": "[PATCH] c, c++: Introduce -Wconstant-logical-operand warning\n [PR125081]", "Message-ID": "<afMPwPZBZlyCU7TG@tucnak>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "D3KzytuGI4P5F_QYeJdUfyhJUeN9A9VyLqA25ZMLdFo_1777536964", "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": "Hi!\n\nGiven the recent (data->flags && ff_genericize) vs.\n(data->flags & ff_genericize) typo, I've looked at warning in similar\ncases.\nWe don't warn for cases like that at all, clang/clang++ has\n-Wconstant-logical-operand warning enabled by default.\nTheir behavior is:\n1) only warns for rhs of &&/|| (why?)\n2) don't warn if rhs is bool\n3) for C++ warn if rhs is constant or folds into constant,\n for C warn if rhs is constant or folds into constant and\n that constant is not 0 or 1\n4) I think it doesn't warn if rhs comes from a macro\nThe following patch implements similar warning with similar wording,\njust provides the value of the constant, but\n1) warns for lhs and rhs\n2) doesn't warn if either lhs or rhs is bool\n3) doesn't warn if lhs or rhs is or folds to constant 0 or 1\n4) doesn't care if it comes from a macro or not\nI think 64 && x is similarly suspicious to x && 64 and both\nare likely to be meant 64 & x or x & 64. I think having\n&& 1 or && 0 is common even in C++, people don't always write\n&& true or && false etc. and don't see why C++ would be different\nin that from C, I think people sometimes write\n if (1\n #ifdef ABC\n && ABC\n #endif\n #ifdef DEF\n && DEF\n #endif\n && 1)\nand similar (or similarly with 0/true/false or ||). And the warning\nis only enabled in -Wall, not by default. This won't warn about\nthe ff_genericize case, because that is actually data->flags && 1\nand I think that isn't that suspicious.\n\nBootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?\n\n2026-04-30 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\tJakub", "diff": "--- gcc/doc/invoke.texi.jj\t2026-04-29 23:16:25.362254169 +0200\n+++ gcc/doc/invoke.texi\t2026-04-30 10:01:13.536648220 +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,20 @@ 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+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-03-27 10:17:13.717337544 +0100\n+++ gcc/c-family/c.opt\t2026-04-29 14:52:19.388186620 +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-07 22:47:11.962384081 +0200\n+++ gcc/c-family/c.opt.urls\t2026-04-30 10:13:35.324592323 +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-22 07:54:22.051902257 +0200\n+++ gcc/c/c-typeck.cc\t2026-04-29 17:13:04.643477877 +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,44 @@ 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+ if (TREE_CODE (arg2.value) == INTEGER_CST\n+\t && !integer_zerop (arg2.value)\n+\t && !integer_onep (arg2.value))\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))\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-03-27 10:17:13.000000000 +0100\n+++ gcc/c/c-parser.cc\t2026-04-29 17:02:08.668498743 +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-03-27 10:17:13.729337348 +0100\n+++ gcc/c/c-tree.h\t2026-04-29 17:02:53.961737782 +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-16 18:56:51.670066768 +0200\n+++ gcc/cp/typeck.cc\t2026-04-29 15:58:27.207052842 +0200\n@@ -5953,6 +5953,41 @@ 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 if (TREE_CODE (cop1) == INTEGER_CST\n+\t && !integer_zerop (cop1)\n+\t && !integer_onep (cop1))\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 {\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+\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-29 16:10:13.755923439 +0200\n+++ gcc/testsuite/c-c++-common/Wconstant-logical-operand-1.c\t2026-04-29 17:18:45.563746358 +0200\n@@ -0,0 +1,64 @@\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+\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+}\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-29 17:18:56.304562864 +0200\n+++ gcc/testsuite/c-c++-common/Wconstant-logical-operand-2.c\t2026-04-29 17:19:04.412424351 +0200\n@@ -0,0 +1,64 @@\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+\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+}\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": [] }