Try to clarify ErrorPath texts

This commit is contained in:
Daniel Marjamäki 2017-05-20 08:47:35 +02:00
parent 55ae206ecc
commit 82a372a380
2 changed files with 41 additions and 23 deletions

View File

@ -1972,7 +1972,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
std::list<ValueFlow::Value> values = tok->astOperand2()->values(); std::list<ValueFlow::Value> values = tok->astOperand2()->values();
for (std::list<ValueFlow::Value>::iterator it = values.begin(); it != values.end(); ++it) { for (std::list<ValueFlow::Value>::iterator it = values.begin(); it != values.end(); ++it) {
std::string info = "Assignment, " + it->infoString(); const std::string info = "Assignment '" + tok->expressionString() + "', assigned value is " + it->infoString();
it->errorPath.push_back(ErrorPathItem(tok->astOperand2(), info)); it->errorPath.push_back(ErrorPathItem(tok->astOperand2(), info));
} }
const bool constValue = tok->astOperand2()->isNumber(); const bool constValue = tok->astOperand2()->isNumber();
@ -2536,7 +2536,7 @@ static void valueFlowForLoopSimplifyAfter(Token *fortok, unsigned int varid, con
std::list<ValueFlow::Value> values; std::list<ValueFlow::Value> values;
values.push_back(ValueFlow::Value(num)); values.push_back(ValueFlow::Value(num));
values.back().errorPath.push_back(ErrorPathItem(fortok,"After for loop, " + values.back().infoString())); values.back().errorPath.push_back(ErrorPathItem(fortok,"After for loop, " + var->name() + " has value " + values.back().infoString()));
valueFlowForward(fortok->linkAt(1)->linkAt(1)->next(), valueFlowForward(fortok->linkAt(1)->linkAt(1)->next(),
endToken, endToken,
@ -2731,8 +2731,8 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
if (!Token::Match(tok, "%name% (")) if (!Token::Match(tok, "%name% ("))
continue; continue;
const Function * const currentFunction = tok->function(); const Function * const calledFunction = tok->function();
if (!currentFunction) { if (!calledFunction) {
// library function? // library function?
const std::string& returnValue(settings->library.returnValue(tok)); const std::string& returnValue(settings->library.returnValue(tok));
if (!returnValue.empty()) if (!returnValue.empty())
@ -2740,16 +2740,15 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
continue; continue;
} }
// Function scope.. const Scope * const calledFunctionScope = calledFunction->functionScope;
const Scope * const functionScope = currentFunction->functionScope; if (!calledFunctionScope)
if (!functionScope)
continue; continue;
const std::vector<const Token *> &callArguments = getArguments(tok); const std::vector<const Token *> &callArguments = getArguments(tok);
for (unsigned int argnr = 0U; argnr < callArguments.size(); ++argnr) { for (unsigned int argnr = 0U; argnr < callArguments.size(); ++argnr) {
const Token *argtok = callArguments[argnr]; const Token *argtok = callArguments[argnr];
// Get function argument // Get function argument
const Variable * const argvar = currentFunction->getArgumentVar(argnr); const Variable * const argvar = calledFunction->getArgumentVar(argnr);
if (!argvar) if (!argvar)
break; break;
@ -2766,15 +2765,34 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
continue; continue;
// Error path.. // Error path..
for (std::list<ValueFlow::Value>::iterator it = argvalues.begin(); it != argvalues.end(); ++it) for (std::list<ValueFlow::Value>::iterator it = argvalues.begin(); it != argvalues.end(); ++it) {
it->errorPath.push_back(ErrorPathItem(argtok, "Function argument, " + it->infoString())); std::string nr = MathLib::toString(argnr + 1);
if (argnr==0)
nr += "st";
else if (argnr==1)
nr += "nd";
else if (argnr==2)
nr += "rd";
else
nr += "th";
it->errorPath.push_back(ErrorPathItem(argtok,
"Calling function '" +
calledFunction->name() +
"', " +
nr +
" argument '" +
argvar->name() +
"' value is " +
it->infoString()));
}
// passed values are not "known".. // passed values are not "known"..
for (std::list<ValueFlow::Value>::iterator it = argvalues.begin(); it != argvalues.end(); ++it) { for (std::list<ValueFlow::Value>::iterator it = argvalues.begin(); it != argvalues.end(); ++it) {
it->changeKnownToPossible(); it->changeKnownToPossible();
} }
valueFlowInjectParameter(tokenlist, errorLogger, settings, argvar, functionScope, argvalues); valueFlowInjectParameter(tokenlist, errorLogger, settings, argvar, calledFunctionScope, argvalues);
} }
} }
} }
@ -2934,22 +2952,22 @@ ValueFlow::Value::Value(const Token *c, long long val)
defaultArg(false), defaultArg(false),
valueKind(ValueKind::Possible) valueKind(ValueKind::Possible)
{ {
errorPath.push_back(ErrorPathItem(c, "Condition '" + c->expressionString() + "'")); errorPath.push_back(ErrorPathItem(c, "Assuming that condition '" + c->expressionString() + "' is not redundant"));
} }
std::string ValueFlow::Value::infoString() const std::string ValueFlow::Value::infoString() const
{ {
switch (valueType) { switch (valueType) {
case INT: case INT:
return "integer value " + MathLib::toString(intvalue); return MathLib::toString(intvalue);
case TOK: case TOK:
return "value " + tokvalue->str(); return tokvalue->str();
case FLOAT: case FLOAT:
return "float value " + MathLib::toString(floatValue); return MathLib::toString(floatValue);
case MOVED: case MOVED:
return "value <Moved>"; return "<Moved>";
case UNINIT: case UNINIT:
return "value <Uninit>"; return "<Uninit>";
}; };
throw InternalError(nullptr, "Invalid ValueFlow Value type"); throw InternalError(nullptr, "Invalid ValueFlow Value type");
} }

View File

@ -595,7 +595,7 @@ private:
" int x = 53;\n" " int x = 53;\n"
" a = x;\n" " a = x;\n"
"}\n"; "}\n";
ASSERT_EQUALS("2,Assignment, integer value 53\n", ASSERT_EQUALS("2,Assignment 'x=53', assigned value is 53\n",
getErrorPathForX(code, 3U)); getErrorPathForX(code, 3U));
code = "void f(int y) {\n" code = "void f(int y) {\n"
@ -604,8 +604,8 @@ private:
" y += 12;\n" " y += 12;\n"
" if (y == 32) {}" " if (y == 32) {}"
"}\n"; "}\n";
ASSERT_EQUALS("5,Condition 'y==32'\n" ASSERT_EQUALS("5,Assuming that condition 'y==32' is not redundant\n"
"2,Assignment, integer value 20\n", "2,Assignment 'x=y', assigned value is 20\n",
getErrorPathForX(code, 3U)); getErrorPathForX(code, 3U));
code = "void f1(int x) {\n" code = "void f1(int x) {\n"
@ -615,8 +615,8 @@ private:
" int x = 3;\n" " int x = 3;\n"
" f1(x+1);\n" " f1(x+1);\n"
"}\n"; "}\n";
ASSERT_EQUALS("5,Assignment, integer value 3\n" ASSERT_EQUALS("5,Assignment 'x=3', assigned value is 3\n"
"6,Function argument, integer value 4\n", "6,Calling function 'f1', 1st argument 'x' value is 4\n",
getErrorPathForX(code, 2U)); getErrorPathForX(code, 2U));
code = "void f(int a) {\n" code = "void f(int a) {\n"
@ -624,7 +624,7 @@ private:
" for (x = a; x < 50; x++) {}\n" " for (x = a; x < 50; x++) {}\n"
" b = x;\n" " b = x;\n"
"}\n"; "}\n";
ASSERT_EQUALS("3,After for loop, integer value 50\n", ASSERT_EQUALS("3,After for loop, x has value 50\n",
getErrorPathForX(code, 4U)); getErrorPathForX(code, 4U));
} }