diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 4cdff0674..d91359c13 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2176,29 +2176,43 @@ void CheckOther::checkDuplicateBranch() if (macro) continue; - // save if branch code - const std::string branch1 = scope.bodyStart->next()->stringifyList(scope.bodyEnd); + const Token * const tokIf = scope.bodyStart->next(); + const Token * const tokElse = scope.bodyEnd->tokAt(3); - if (branch1.empty()) + // compare first tok before stringifying the whole blocks + const std::string tokIfStr = tokIf->stringify(false, true, false); + if (tokIfStr.empty()) continue; - // save else branch code - const std::string branch2 = scope.bodyEnd->tokAt(3)->stringifyList(scope.bodyEnd->linkAt(2)); + const std::string tokElseStr = tokElse->stringify(false, true, false); - ErrorPath errorPath; - // check for duplicates - if (branch1 == branch2) { - duplicateBranchError(scope.classDef, scope.bodyEnd->next(), errorPath); - continue; + if (tokIfStr == tokElseStr) { + // save if branch code + const std::string branch1 = tokIf->stringifyList(scope.bodyEnd); + + if (branch1.empty()) + continue; + + // save else branch code + const std::string branch2 = tokElse->stringifyList(scope.bodyEnd->linkAt(2)); + + // check for duplicates + if (branch1 == branch2) { + duplicateBranchError(scope.classDef, scope.bodyEnd->next(), ErrorPath{}); + continue; + } } // check for duplicates using isSameExpression - const Token * branchTop1 = getSingleExpressionInBlock(scope.bodyStart->next()); - const Token * branchTop2 = getSingleExpressionInBlock(scope.bodyEnd->tokAt(3)); - if (!branchTop1 || !branchTop2) + const Token * branchTop1 = getSingleExpressionInBlock(tokIf); + if (!branchTop1) + continue; + const Token * branchTop2 = getSingleExpressionInBlock(tokElse); + if (!branchTop2) continue; if (branchTop1->str() != branchTop2->str()) continue; + ErrorPath errorPath; if (isSameExpression(mTokenizer->isCPP(), false, branchTop1->astOperand1(), branchTop2->astOperand1(), mSettings->library, true, true, &errorPath) && isSameExpression(mTokenizer->isCPP(), false, branchTop1->astOperand2(), branchTop2->astOperand2(), mSettings->library, true, true, &errorPath)) duplicateBranchError(scope.classDef, scope.bodyEnd->next(), errorPath); diff --git a/test/testother.cpp b/test/testother.cpp index 68922a7e0..b5aec968f 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -152,6 +152,8 @@ private: TEST_CASE(duplicateBranch2); // empty macro TEST_CASE(duplicateBranch3); TEST_CASE(duplicateBranch4); + TEST_CASE(duplicateBranch5); // make sure the Token attributes are compared + TEST_CASE(duplicateBranch6); TEST_CASE(duplicateExpression1); TEST_CASE(duplicateExpression2); // ticket #2730 TEST_CASE(duplicateExpression3); // ticket #3317 @@ -5441,6 +5443,72 @@ private: ASSERT_EQUALS("", errout.str()); } + void duplicateBranch5() { + check("void f(bool b) {\n" + " int j;\n" + " if (b) {\n" + " unsigned int i = 0;\n" + " j = i;\n" + " } else {\n" + " unsigned int i = 0;\n" + " j = i;\n" + " }\n" + "}"); + ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:3]: (style, inconclusive) Found duplicate branches for 'if' and 'else'.\n", errout.str()); + + check("void f(bool b) {\n" + " int j;\n" + " if (b) {\n" + " unsigned int i = 0;\n" + " j = i;\n" + " } else {\n" + " unsigned int i = 0;\n" + " j = 1;\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(bool b) {\n" + " int j;\n" + " if (b) {\n" + " unsigned int i = 0;\n" + " } else {\n" + " int i = 0;\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(bool b) {\n" + " int j;\n" + " if (b) {\n" + " unsigned int i = 0;\n" + " j = i;\n" + " } else {\n" + " int i = 0;\n" + " j = i;\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + + void duplicateBranch6() { + check("void f(bool b) {\n" + " if (b) {\n" + " } else {\n" + " int i = 0;\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(bool b) {\n" + " if (b) {\n" + " int i = 0;\n" + " } else {\n" + " }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void duplicateExpression1() { check("void foo(int a) {\n" " if (a == a) { }\n"