Skip to content

Commit 9c8507f

Browse files
Fix #14913 FN duplicateExpression with parenthesized subexpression (#8727)
1 parent 6640862 commit 9c8507f

3 files changed

Lines changed: 41 additions & 1 deletion

File tree

lib/astutils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1700,7 +1700,7 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se
17001700
compare = true;
17011701
}
17021702
}
1703-
if (compare && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings))
1703+
if (compare && varTok1 != varTok2 && astIsBoolLike(varTok1, settings) && astIsBoolLike(varTok2, settings))
17041704
return isSameExpression(macro, varTok1, varTok2, settings, pure, followVar, errors);
17051705

17061706
}

lib/checkother.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3058,6 +3058,16 @@ void CheckOtherImpl::checkDuplicateExpression()
30583058
checkDuplicate(ast1->astOperand1(), tok->astOperand2(), ast1);
30593059
ast1 = ast1->astOperand1();
30603060
}
3061+
if (tok->str() != "=") {
3062+
const Token* par = tok->astParent();
3063+
while (par && tok->str() == par->str() && precedes(par->astOperand1(), tok)) { // chain of identical operators with parentheses
3064+
checkDuplicate(par->astOperand1(), tok->astOperand1(), par);
3065+
checkDuplicate(par->astOperand1(), tok->astOperand2(), par);
3066+
checkDuplicate(par->astOperand2(), tok->astOperand1(), par);
3067+
checkDuplicate(par->astOperand2(), tok->astOperand2(), par);
3068+
par = par->astParent();
3069+
}
3070+
}
30613071
}
30623072
}
30633073
} else if (tok->astOperand1() && tok->astOperand2() && tok->str() == ":" && tok->astParent() && tok->astParent()->str() == "?") {

test/testother.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ class TestOther : public TestFixture {
201201
TEST_CASE(duplicateExpression19);
202202
TEST_CASE(duplicateExpression20);
203203
TEST_CASE(duplicateExpression21);
204+
TEST_CASE(duplicateExpression22);
204205
TEST_CASE(duplicateExpressionLoop);
205206
TEST_CASE(duplicateValueTernary);
206207
TEST_CASE(duplicateValueTernarySizeof); // #13773
@@ -8366,6 +8367,35 @@ class TestOther : public TestFixture {
83668367
ASSERT_EQUALS("", errout_str());
83678368
}
83688369

8370+
void duplicateExpression22() {
8371+
check("int f() {\n" // #14913
8372+
" return 0x1 | (0x2 | 0x4) | 0x1;\n"
8373+
"}\n"
8374+
"int g() {\n"
8375+
" return 0x1 | (0x2 | 0x1);\n"
8376+
"}\n"
8377+
"int h() {\n"
8378+
" return 0x1 | (0x1 | 0x2);\n"
8379+
"}\n"
8380+
"int i() {\n"
8381+
" return 0x2 | (0x4 | 0x1) | 0x1;\n"
8382+
"}\n"
8383+
"int j() {\n"
8384+
" return 0x2 | (0x1 | 0x4) | 0x1;\n"
8385+
"}\n");
8386+
ASSERT_EQUALS("[test.cpp:2:30]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n"
8387+
"[test.cpp:5:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n"
8388+
"[test.cpp:8:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n"
8389+
"[test.cpp:11:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n"
8390+
"[test.cpp:14:23]: (style) Same expression '0x1' found multiple times in chain of '|' operators. [duplicateExpression]\n",
8391+
errout_str());
8392+
8393+
check("bool f(const int** a, const int** b) {\n"
8394+
" return (a[0] != nullptr) != (b[0] != nullptr);\n"
8395+
"}\n");
8396+
ASSERT_EQUALS("", errout_str());
8397+
}
8398+
83698399
void duplicateExpressionLoop() {
83708400
check("void f() {\n"
83718401
" int a = 1;\n"

0 commit comments

Comments
 (0)