Fixed #9909 (False positive: knownArgument for calculation 'self->maxsize * sizeof(intptr_t)')
This commit is contained in:
parent
bca3605f77
commit
107ee57e7a
|
@ -3113,13 +3113,18 @@ void CheckOther::checkKnownArgument()
|
||||||
if (isVariableExpression(tok2))
|
if (isVariableExpression(tok2))
|
||||||
continue;
|
continue;
|
||||||
// ensure that there is a integer variable in expression with unknown value
|
// ensure that there is a integer variable in expression with unknown value
|
||||||
bool intvar = false;
|
std::string varexpr;
|
||||||
visitAstNodes(tok, [&intvar](const Token *child) {
|
visitAstNodes(tok, [&varexpr](const Token *child) {
|
||||||
if (child->varId() && child->valueType() && child->valueType()->isIntegral() && child->values().empty())
|
if (Token::Match(child, "%var%|.|[")) {
|
||||||
intvar = true;
|
if (child->valueType() && child->valueType()->isIntegral() && child->values().empty()) {
|
||||||
|
varexpr = child->expressionString();
|
||||||
|
return ChildrenToVisit::done;
|
||||||
|
}
|
||||||
|
return ChildrenToVisit::none;
|
||||||
|
}
|
||||||
return ChildrenToVisit::op1_and_op2;
|
return ChildrenToVisit::op1_and_op2;
|
||||||
});
|
});
|
||||||
if (!intvar)
|
if (varexpr.empty())
|
||||||
continue;
|
continue;
|
||||||
// ensure that function name does not contain "assert"
|
// ensure that function name does not contain "assert"
|
||||||
std::string funcname = tok->astParent()->previous()->str();
|
std::string funcname = tok->astParent()->previous()->str();
|
||||||
|
@ -3128,18 +3133,18 @@ void CheckOther::checkKnownArgument()
|
||||||
});
|
});
|
||||||
if (funcname.find("assert") != std::string::npos)
|
if (funcname.find("assert") != std::string::npos)
|
||||||
continue;
|
continue;
|
||||||
knownArgumentError(tok, tok->astParent()->previous(), &tok->values().front());
|
knownArgumentError(tok, tok->astParent()->previous(), &tok->values().front(), varexpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckOther::knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value)
|
void CheckOther::knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value, const std::string &varexpr)
|
||||||
{
|
{
|
||||||
MathLib::bigint intvalue = value ? value->intvalue : 0;
|
MathLib::bigint intvalue = value ? value->intvalue : 0;
|
||||||
const std::string expr = tok ? tok->expressionString() : std::string("x");
|
const std::string expr = tok ? tok->expressionString() : varexpr;
|
||||||
const std::string fun = ftok ? ftok->str() : std::string("f");
|
const std::string fun = ftok ? ftok->str() : std::string("f");
|
||||||
|
|
||||||
const std::string errmsg = "Argument '" + expr + "' to function " + fun + " is always " + std::to_string(intvalue);
|
const std::string errmsg = "Argument '" + expr + "' to function " + fun + " is always " + std::to_string(intvalue) + ". It does not matter what value '" + varexpr + "' has.";
|
||||||
const ErrorPath errorPath = getErrorPath(tok, value, errmsg);
|
const ErrorPath errorPath = getErrorPath(tok, value, errmsg);
|
||||||
reportError(errorPath, Severity::style, "knownArgument", errmsg, CWE570, false);
|
reportError(errorPath, Severity::style, "knownArgument", errmsg, CWE570, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,7 @@ private:
|
||||||
void funcArgNamesDifferent(const std::string & functionName, nonneg int index, const Token* declaration, const Token* definition);
|
void funcArgNamesDifferent(const std::string & functionName, nonneg int index, const Token* declaration, const Token* definition);
|
||||||
void funcArgOrderDifferent(const std::string & functionName, const Token * declaration, const Token * definition, const std::vector<const Token*> & declarations, const std::vector<const Token*> & definitions);
|
void funcArgOrderDifferent(const std::string & functionName, const Token * declaration, const Token * definition, const std::vector<const Token*> & declarations, const std::vector<const Token*> & definitions);
|
||||||
void shadowError(const Token *var, const Token *shadowed, std::string type);
|
void shadowError(const Token *var, const Token *shadowed, std::string type);
|
||||||
void knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value);
|
void knownArgumentError(const Token *tok, const Token *ftok, const ValueFlow::Value *value, const std::string &varexpr);
|
||||||
void comparePointersError(const Token *tok, const ValueFlow::Value *v1, const ValueFlow::Value *v2);
|
void comparePointersError(const Token *tok, const ValueFlow::Value *v1, const ValueFlow::Value *v2);
|
||||||
void checkModuloOfOneError(const Token *tok);
|
void checkModuloOfOneError(const Token *tok);
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ private:
|
||||||
c.shadowError(nullptr, nullptr, "variable");
|
c.shadowError(nullptr, nullptr, "variable");
|
||||||
c.shadowError(nullptr, nullptr, "function");
|
c.shadowError(nullptr, nullptr, "function");
|
||||||
c.shadowError(nullptr, nullptr, "argument");
|
c.shadowError(nullptr, nullptr, "argument");
|
||||||
c.knownArgumentError(nullptr, nullptr, nullptr);
|
c.knownArgumentError(nullptr, nullptr, nullptr, "x");
|
||||||
c.comparePointersError(nullptr, nullptr, nullptr);
|
c.comparePointersError(nullptr, nullptr, nullptr);
|
||||||
c.redundantAssignmentError(nullptr, nullptr, "var", false);
|
c.redundantAssignmentError(nullptr, nullptr, "var", false);
|
||||||
c.redundantInitializationError(nullptr, nullptr, "var", false);
|
c.redundantInitializationError(nullptr, nullptr, "var", false);
|
||||||
|
@ -411,7 +411,8 @@ private:
|
||||||
"- function declaration and definition argument order different.\n"
|
"- function declaration and definition argument order different.\n"
|
||||||
"- shadow variable.\n"
|
"- shadow variable.\n"
|
||||||
"- variable can be declared const.\n"
|
"- variable can be declared const.\n"
|
||||||
"- calculating modulo of one.\n";
|
"- calculating modulo of one.\n"
|
||||||
|
"- known function argument, suspicious calculation.";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -8745,13 +8745,13 @@ private:
|
||||||
"void f(int x) {\n"
|
"void f(int x) {\n"
|
||||||
" g((x & 0x01) >> 7);\n"
|
" g((x & 0x01) >> 7);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(x&0x01)>>7' to function g is always 0\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(x&0x01)>>7' to function g is always 0. It does not matter what value 'x' has.\n", errout.str());
|
||||||
|
|
||||||
check("void g(int);\n"
|
check("void g(int);\n"
|
||||||
"void f(int x) {\n"
|
"void f(int x) {\n"
|
||||||
" g((int)((x & 0x01) >> 7));\n"
|
" g((int)((x & 0x01) >> 7));\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(int)((x&0x01)>>7)' to function g is always 0\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Argument '(int)((x&0x01)>>7)' to function g is always 0. It does not matter what value 'x' has.\n", errout.str());
|
||||||
|
|
||||||
check("void g(int);\n"
|
check("void g(int);\n"
|
||||||
"void f(int x) {\n"
|
"void f(int x) {\n"
|
||||||
|
@ -8842,6 +8842,17 @@ private:
|
||||||
" std::cout << std::setw(heading.length());\n"
|
" std::cout << std::setw(heading.length());\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// #9909 - struct member with known value
|
||||||
|
check("struct LongStack {\n"
|
||||||
|
" int maxsize;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"void growLongStack(LongStack* self) {\n"
|
||||||
|
" self->maxsize = 32;\n"
|
||||||
|
" dostuff(self->maxsize * sizeof(intptr_t));\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkComparePointers() {
|
void checkComparePointers() {
|
||||||
|
|
Loading…
Reference in New Issue