Skip to content

Commit 8dad4aa

Browse files
fixup! Report overlapping inner conditions as identicalInnerCondition
1 parent 37deb79 commit 8dad4aa

3 files changed

Lines changed: 36 additions & 15 deletions

File tree

lib/checkcondition.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ void CheckCondition::multiCondition2()
760760
} else if (!isReturnVar && isSameExpression(true, firstCondition, cond2, *mSettings, true, true, &errorPath)) {
761761
identicalInnerConditionError(firstCondition, cond2, errorPath);
762762
} else if (!isReturnVar && isOverlappingCond(cond2, firstCondition, true)) {
763-
identicalInnerConditionError(firstCondition, cond2, errorPath);
763+
overlappingInnerConditionError(firstCondition, cond2, errorPath);
764764
}
765765
}
766766
return ChildrenToVisit::none;
@@ -881,6 +881,21 @@ void CheckCondition::oppositeInnerConditionError(const Token *tok1, const Token*
881881
reportError(std::move(errorPath), Severity::warning, "oppositeInnerCondition", msg, CWE398, Certainty::normal);
882882
}
883883

884+
void CheckCondition::overlappingInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath)
885+
{
886+
if (diag(tok1, tok2))
887+
return;
888+
const std::string s1(tok1 ? tok1->expressionString() : "x");
889+
const std::string s2(tok2 ? tok2->expressionString() : "x");
890+
const std::string innerSmt = innerSmtString(tok2);
891+
errorPath.emplace_back(tok1, "outer condition: " + s1);
892+
errorPath.emplace_back(tok2, "overlapping inner condition: " + s2);
893+
894+
const std::string msg("Overlapping inner '" + innerSmt + "' condition is always true.\n"
895+
"Overlapping inner '" + innerSmt + "' condition is always true (outer condition is '" + s1 + "' and inner condition is '" + s2 + "').");
896+
reportError(std::move(errorPath), Severity::warning, "overlappingInnerCondition", msg, CWE398, Certainty::normal);
897+
}
898+
884899
void CheckCondition::identicalInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath)
885900
{
886901
if (diag(tok1, tok2))
@@ -2113,6 +2128,7 @@ void CheckCondition::getErrorMessages(ErrorLogger *errorLogger, const Settings *
21132128
c.comparisonError(nullptr, "&", 6, "==", 1, false);
21142129
c.duplicateConditionError(nullptr, nullptr, ErrorPath{});
21152130
c.overlappingElseIfConditionError(nullptr, 1);
2131+
c.overlappingInnerConditionError(nullptr, nullptr, ErrorPath());
21162132
c.mismatchingBitAndError(nullptr, 0xf0, nullptr, 1);
21172133
c.oppositeInnerConditionError(nullptr, nullptr, ErrorPath{});
21182134
c.identicalInnerConditionError(nullptr, nullptr, ErrorPath{});

lib/checkcondition.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class CPPCHECKLIB CheckCondition : public Check {
130130
bool result);
131131
void duplicateConditionError(const Token *tok1, const Token *tok2, ErrorPath errorPath);
132132
void overlappingElseIfConditionError(const Token *tok, nonneg int line1);
133+
void overlappingInnerConditionError(const Token *tok1, const Token *tok2, ErrorPath errorPath);
133134
void oppositeElseIfConditionError(const Token *ifCond, const Token *elseIfCond, ErrorPath errorPath);
134135

135136
void oppositeInnerConditionError(const Token *tok1, const Token* tok2, ErrorPath errorPath);

test/testcondition.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class TestCondition : public TestFixture {
9494
TEST_CASE(identicalConditionAfterEarlyExit);
9595
TEST_CASE(innerConditionModified);
9696

97+
TEST_CASE(overlappingInnerCondition);
98+
9799
TEST_CASE(clarifyCondition1); // if (a = b() < 0)
98100
TEST_CASE(clarifyCondition2); // if (a & b == c)
99101
TEST_CASE(clarifyCondition3); // if (! a & b)
@@ -2834,20 +2836,6 @@ class TestCondition : public TestFixture {
28342836
" }\n"
28352837
"}\n");
28362838
ASSERT_EQUALS("[test.cpp:2:12] -> [test.cpp:4:13]: (warning) Identical inner 'if' condition is always true. [identicalInnerCondition]\n", errout_str());
2837-
2838-
check("void f(int x) {\n"
2839-
" if (x == 1) {\n"
2840-
" if (x & 7) {}\n"
2841-
" }\n"
2842-
"}");
2843-
ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:15]: (warning) Identical inner 'if' condition is always true. [identicalInnerCondition]\n", errout_str());
2844-
2845-
check("void f(int x) {\n"
2846-
" if (x & 7) {\n"
2847-
" if (x == 1) {}\n"
2848-
" }\n"
2849-
"}");
2850-
ASSERT_EQUALS("", errout_str());
28512839
}
28522840

28532841
void identicalConditionAfterEarlyExit() {
@@ -3036,6 +3024,22 @@ class TestCondition : public TestFixture {
30363024
ASSERT_EQUALS("", errout_str());
30373025
}
30383026

3027+
void overlappingInnerCondition() {
3028+
check("void f(int x) {\n"
3029+
" if (x == 1) {\n"
3030+
" if (x & 7) {}\n"
3031+
" }\n"
3032+
"}");
3033+
ASSERT_EQUALS("[test.cpp:2:11] -> [test.cpp:3:15]: (warning) Overlapping inner 'if' condition is always true. [overlappingInnerCondition]\n", errout_str());
3034+
3035+
check("void f(int x) {\n"
3036+
" if (x & 7) {\n"
3037+
" if (x == 1) {}\n"
3038+
" }\n"
3039+
"}");
3040+
ASSERT_EQUALS("", errout_str());
3041+
}
3042+
30393043
// clarify conditions with = and comparison
30403044
void clarifyCondition1() {
30413045
check("void f() {\n"

0 commit comments

Comments
 (0)