Conditions: Better handling of function calls

This commit is contained in:
Daniel Marjamäki 2018-07-08 15:58:04 +02:00
parent c2f0828a61
commit 03faa25d12
3 changed files with 35 additions and 8 deletions

View File

@ -164,11 +164,24 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2
if (tok1->isSigned() != tok2->isSigned()) if (tok1->isSigned() != tok2->isSigned())
return false; return false;
if (pure && tok1->isName() && tok1->next()->str() == "(" && tok1->str() != "sizeof") { if (pure && tok1->isName() && tok1->next()->str() == "(" && tok1->str() != "sizeof") {
if (!tok1->function() && !Token::Match(tok1->previous(), ".|::") && !library.isFunctionConst(tok1->str(), true) && !tok1->isAttributeConst() && !tok1->isAttributePure()) if (!tok1->function()) {
if (!Token::Match(tok1->previous(), ".|::") && !library.isFunctionConst(tok1) && !tok1->isAttributeConst() && !tok1->isAttributePure())
return false; return false;
else if (tok1->function() && !tok1->function()->isConst() && !tok1->function()->isAttributeConst() && !tok1->function()->isAttributePure()) if (Token::simpleMatch(tok1->previous(), ".")) {
const Token *lhs = tok1->previous();
while (Token::Match(lhs, "(|.|["))
lhs = lhs->astOperand1();
bool lhsIsConst = (lhs->variable() && lhs->variable()->isConst()) ||
(lhs->valueType() && lhs->valueType()->constness > 0) ||
(Token::Match(lhs, "%var% . %name% (") && library.isFunctionConst(lhs->tokAt(2)));
if (!lhsIsConst)
return false; return false;
} }
} else {
if (tok1->function() && !tok1->function()->isConst() && !tok1->function()->isAttributeConst() && !tok1->function()->isAttributePure())
return false;
}
}
// templates/casts // templates/casts
if ((Token::Match(tok1, "%name% <") && tok1->next()->link()) || if ((Token::Match(tok1, "%name% <") && tok1->next()->link()) ||
(Token::Match(tok2, "%name% <") && tok2->next()->link())) { (Token::Match(tok2, "%name% <") && tok2->next()->link())) {

View File

@ -546,6 +546,20 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
{
check("void f(Class &c) {\n"
" if (c.dostuff() == 3) {}\n"
" else { if (c.dostuff() == 3) {} }\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f(const Class &c) {\n"
" if (c.dostuff() == 3) {}\n"
" else { if (c.dostuff() == 3) {} }\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout.str());
}
check("void f(int a, int &b) {\n" check("void f(int a, int &b) {\n"
" x = x / 2;\n" " x = x / 2;\n"
" if (x < 100) { b = 1; }\n" " if (x < 100) { b = 1; }\n"
@ -2091,7 +2105,7 @@ private:
ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: a. '!a || (a && b)' is equivalent to '!a || b'\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: a. '!a || (a && b)' is equivalent to '!a || b'\n", errout.str());
check("void f() {\n" check("void f(const Token *tok) {\n"
" if (!tok->next()->function() || \n" " if (!tok->next()->function() || \n"
" (tok->next()->function() && tok->next()->function()->isConstructor()));\n" " (tok->next()->function() && tok->next()->function()->isConstructor()));\n"
"}"); "}");
@ -2109,7 +2123,7 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n" check("void f(const Token *tok) {\n"
" if (!tok->next(1)->function(1) || \n" " if (!tok->next(1)->function(1) || \n"
" (tok->next(1)->function(1) && tok->next(1)->function(1)->isConstructor()));\n" " (tok->next(1)->function(1) && tok->next(1)->function(1)->isConstructor()));\n"
"}"); "}");

View File

@ -3645,7 +3645,7 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n" check("void f(const Bar &bar) {\n"
" bool a = bar.isSet() && bar->isSet();\n" " bool a = bar.isSet() && bar->isSet();\n"
" bool b = bar.isSet() && bar.isSet();\n" " bool b = bar.isSet() && bar.isSet();\n"
"}"); "}");
@ -6124,7 +6124,7 @@ private:
check("bool isInUnoIncludeFile(StringRef name) {" check("bool isInUnoIncludeFile(StringRef name) {"
" return name.startswith(SRCDIR \"/com/\") || name.startswith(SRCDIR \"/uno/\");\n" " return name.startswith(SRCDIR \"/com/\") || name.startswith(SRCDIR \"/uno/\");\n"
"};", "test.cpp", false, false); "};", "test.cpp", false, false);
TODO_ASSERT_EQUALS("", "[test.cpp:1] -> [test.cpp:1]: (style) Same expression on both sides of '||'.\n", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void raceAfterInterlockedDecrement() { void raceAfterInterlockedDecrement() {