optimized `CheckOther::checkDuplicateBranch()` a bit (#4542)

This commit is contained in:
Oliver Stöneberg 2022-10-09 20:48:54 +02:00 committed by GitHub
parent 94c3108494
commit fa7e08a29f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 13 deletions

View File

@ -2176,29 +2176,43 @@ void CheckOther::checkDuplicateBranch()
if (macro)
continue;
const Token * const tokIf = scope.bodyStart->next();
const Token * const tokElse = scope.bodyEnd->tokAt(3);
// compare first tok before stringifying the whole blocks
const std::string tokIfStr = tokIf->stringify(false, true, false);
if (tokIfStr.empty())
continue;
const std::string tokElseStr = tokElse->stringify(false, true, false);
if (tokIfStr == tokElseStr) {
// save if branch code
const std::string branch1 = scope.bodyStart->next()->stringifyList(scope.bodyEnd);
const std::string branch1 = tokIf->stringifyList(scope.bodyEnd);
if (branch1.empty())
continue;
// save else branch code
const std::string branch2 = scope.bodyEnd->tokAt(3)->stringifyList(scope.bodyEnd->linkAt(2));
const std::string branch2 = tokElse->stringifyList(scope.bodyEnd->linkAt(2));
ErrorPath errorPath;
// check for duplicates
if (branch1 == branch2) {
duplicateBranchError(scope.classDef, scope.bodyEnd->next(), errorPath);
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);

View File

@ -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"