From f92b16706c1ff8856b035511e8b8f0b592cd7229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 19 May 2017 16:32:58 +0200 Subject: [PATCH] ValueFlow: Add ErrorPath info after for loop --- lib/valueflow.cpp | 24 ++++++++++++++++++++---- lib/valueflow.h | 2 ++ test/testvalueflow.cpp | 8 ++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 829fed58d..e074f2737 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1972,9 +1972,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat std::list values = tok->astOperand2()->values(); for (std::list::iterator it = values.begin(); it != values.end(); ++it) { - std::string info = "Assignment"; - if (it->isIntValue()) - info += ", integer value " + MathLib::toString(it->intvalue); + std::string info = "Assignment, " + it->infoString(); it->errorPath.push_back(ErrorPathItem(tok->astOperand2(), info)); } const bool constValue = tok->astOperand2()->isNumber(); @@ -2538,6 +2536,7 @@ static void valueFlowForLoopSimplifyAfter(Token *fortok, unsigned int varid, con std::list values; values.push_back(ValueFlow::Value(num)); + values.back().errorPath.push_back(ErrorPathItem(fortok,"After for loop, " + values.back().infoString())); valueFlowForward(fortok->linkAt(1)->linkAt(1)->next(), endToken, @@ -2768,7 +2767,7 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger, // Error path.. for (std::list::iterator it = argvalues.begin(); it != argvalues.end(); ++it) - it->errorPath.push_back(ErrorPathItem(argtok, "Function argument, integer value " + MathLib::toString(it->intvalue))); + it->errorPath.push_back(ErrorPathItem(argtok, "Function argument, " + it->infoString())); // passed values are not "known".. for (std::list::iterator it = argvalues.begin(); it != argvalues.end(); ++it) { @@ -2938,6 +2937,23 @@ ValueFlow::Value::Value(const Token *c, long long val) errorPath.push_back(ErrorPathItem(c, "Condition '" + c->expressionString() + "'")); } +std::string ValueFlow::Value::infoString() const +{ + switch (valueType) { + case INT: + return "integer value " + MathLib::toString(intvalue); + case TOK: + return "value " + tokvalue->str(); + case FLOAT: + return "float value " + MathLib::toString(floatValue); + case MOVED: + return "value "; + case UNINIT: + return "value "; + }; + throw InternalError(nullptr, "Invalid ValueFlow Value type"); +} + const ValueFlow::Value *ValueFlow::valueFlowConstantFoldAST(const Token *expr, const Settings *settings) { if (expr && expr->values().empty()) { diff --git a/lib/valueflow.h b/lib/valueflow.h index 147c36008..0293460b8 100644 --- a/lib/valueflow.h +++ b/lib/valueflow.h @@ -74,6 +74,8 @@ namespace ValueFlow { valueKind == rhs.valueKind; } + std::string infoString() const; + enum ValueType { INT, TOK, FLOAT, MOVED, UNINIT } valueType; bool isIntValue() const { return valueType == INT; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 8ce3323cd..f9a382b96 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -618,6 +618,14 @@ private: ASSERT_EQUALS("5,Assignment, integer value 3\n" "6,Function argument, integer value 4\n", getErrorPathForX(code, 2U)); + + code = "void f(int a) {\n" + " int x;\n" + " for (x = a; x < 50; x++) {}\n" + " b = x;\n" + "}\n"; + ASSERT_EQUALS("3,After for loop, integer value 50\n", + getErrorPathForX(code, 4U)); } void valueFlowBeforeCondition() {