From 2ebfe419c89c49e47bba7d60ac3490328e249ff6 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Jul 2026 13:51:44 +0200 Subject: [PATCH 1/6] Update checkother.cpp --- lib/checkother.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index d8f2f6ff6f4..9dd91477489 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3054,6 +3054,14 @@ void CheckOtherImpl::checkDuplicateExpression() checkDuplicate(ast1->astOperand1(), tok->astOperand2(), ast1); ast1 = ast1->astOperand1(); } + if (tok->str() != "=") { + const Token* par = tok->astParent(); + while (par && tok->str() == par->str() && precedes(par, tok)) { // chain of identical operators with parentheses + checkDuplicate(par->astOperand1(), tok->astOperand1(), par); + checkDuplicate(par->astOperand1(), tok->astOperand2(), par); + par = par->astParent(); + } + } } } } else if (tok->astOperand1() && tok->astOperand2() && tok->str() == ":" && tok->astParent() && tok->astParent()->str() == "?") { From 7d609df70625597c42daa9f5b4c96a0cb07bf649 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Jul 2026 13:52:57 +0200 Subject: [PATCH 2/6] Update testother.cpp --- test/testother.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/testother.cpp b/test/testother.cpp index 0b87a07f160..be4bf09cae6 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -201,6 +201,7 @@ class TestOther : public TestFixture { TEST_CASE(duplicateExpression19); TEST_CASE(duplicateExpression20); TEST_CASE(duplicateExpression21); + TEST_CASE(duplicateExpression22); TEST_CASE(duplicateExpressionLoop); TEST_CASE(duplicateValueTernary); TEST_CASE(duplicateValueTernarySizeof); // #13773 @@ -8358,6 +8359,22 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void duplicateExpression22() { + check("int f() {\n" // #14913 + " return 0x1 | (0x2 | 0x4) | 0x1;\n" + "}\n" + "int g() {\n" + " return 0x1 | (0x2 | 0x1);\n" + "}\n" + "int h() {\n" + " return 0x1 | (0x1 | 0x2);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:30]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" + "[test.cpp:5:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" + "[test.cpp:8:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n", + errout_str()); + } + void duplicateExpressionLoop() { check("void f() {\n" " int a = 1;\n" From b4ebcb47d4204a49b0336abf240562b94b650c05 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Jul 2026 14:20:50 +0200 Subject: [PATCH 3/6] Update checkother.cpp --- lib/checkother.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 9dd91477489..cfdcff515f6 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -3056,9 +3056,11 @@ void CheckOtherImpl::checkDuplicateExpression() } if (tok->str() != "=") { const Token* par = tok->astParent(); - while (par && tok->str() == par->str() && precedes(par, tok)) { // chain of identical operators with parentheses + while (par && tok->str() == par->str() && precedes(par->astOperand1(), tok)) { // chain of identical operators with parentheses checkDuplicate(par->astOperand1(), tok->astOperand1(), par); checkDuplicate(par->astOperand1(), tok->astOperand2(), par); + checkDuplicate(par->astOperand2(), tok->astOperand1(), par); + checkDuplicate(par->astOperand2(), tok->astOperand2(), par); par = par->astParent(); } } From da4e73b683e905fd3a49ce3bb82fead12fdc3db3 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Jul 2026 14:21:36 +0200 Subject: [PATCH 4/6] Update testother.cpp --- test/testother.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/testother.cpp b/test/testother.cpp index be4bf09cae6..46bff840b3b 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -8368,10 +8368,18 @@ class TestOther : public TestFixture { "}\n" "int h() {\n" " return 0x1 | (0x1 | 0x2);\n" + "}\n" + "int i() {\n" + " return 0x2 | (0x4 | 0x1) | 0x1;\n" + "}\n" + "int j() {\n" + " return 0x2 | (0x1 | 0x4) | 0x1;\n" "}\n"); ASSERT_EQUALS("[test.cpp:2:30]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" "[test.cpp:5:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" - "[test.cpp:8:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n", + "[test.cpp:8:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" + "[test.cpp:11:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" + "[test.cpp:14:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n", errout_str()); } From a181ec2939c5f667e4ece6d8474a88a51bc4af18 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:31:12 +0200 Subject: [PATCH 5/6] Update astutils.cpp [skip ci] --- lib/astutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 27a01ab0382..3133b837fd8 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1700,7 +1700,7 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se compare = true; } } - if (compare && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings)) + if (compare && varTok1 != varTok2 && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings)) return isSameExpression(macro, varTok1, varTok2, settings, pure, followVar, errors); } From f1637c7b5a7f026f19b5d0222c27e346b9f35a95 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:32:46 +0200 Subject: [PATCH 6/6] Update testother.cpp --- test/testother.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/testother.cpp b/test/testother.cpp index 46bff840b3b..5cad15ded04 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -8381,6 +8381,11 @@ class TestOther : public TestFixture { "[test.cpp:11:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n" "[test.cpp:14:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n", errout_str()); + + check("bool f(const int** a, const int** b) {\n" + " return (a[0] != nullptr) != (b[0] != nullptr);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void duplicateExpressionLoop() {