From 62a5d88eb022ae6541de0c4e4e0d41e00bb54501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 7 Feb 2015 18:14:22 +0100 Subject: [PATCH] ValueFlow: Improved handling of strings --- lib/valueflow.cpp | 38 ++++++++++++++++++++++++++++++++++++++ test/testvalueflow.cpp | 8 ++++++++ 2 files changed, 46 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index a6e421f30..165b668be 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -374,12 +374,29 @@ static void valueFlowNumber(TokenList *tokenlist) static void valueFlowString(TokenList *tokenlist) { + std::map constantStrings; + for (Token *tok = tokenlist->front(); tok; tok = tok->next()) { if (tok->type() == Token::eString) { ValueFlow::Value strvalue; strvalue.tokvalue = tok; setTokenValue(tok, strvalue); } + + if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) { + const Token *vartok = tok->tokAt(2); + const Token *strtok = tok->linkAt(3)->tokAt(2); + constantStrings[vartok->varId()] = strtok; + } + + if (tok->varId() > 0U) { + const std::map::const_iterator it = constantStrings.find(tok->varId()); + if (it != constantStrings.end()) { + ValueFlow::Value strvalue; + strvalue.tokvalue = it->second; + setTokenValue(tok, strvalue); + } + } } } @@ -1337,6 +1354,27 @@ static void execute(const Token *expr, execute(expr->astOperand2(), programMemory, result, error); } + else if (expr->str() == "[" && expr->astOperand1() && expr->astOperand2()) { + if (expr->astOperand1()->values.size() != 1U) { + *error = true; + return; + } + const ValueFlow::Value val = expr->astOperand1()->values.front(); + if (!val.tokvalue || !val.tokvalue->isLiteral()) { + *error = true; + return; + } + const std::string strValue = val.tokvalue->strValue(); + MathLib::bigint index = 0; + execute(expr->astOperand2(), programMemory, &index, error); + if (index >= 0 && index < (int)strValue.size()) + *result = strValue[index]; + else if (index == (int)strValue.size()) + *result = 0; + else + *error = true; + } + else *error = true; } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index f10fbbab0..40baa9e6b 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1244,6 +1244,14 @@ private: "}"; ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); + code = "void f() {\n" + " const char abc[] = \"abc\";\n" + " int x;\n" + " for (x = 0; abc[x] != '\\0'; x++) {}\n" + " a[x] = 0;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 5U, 3)); + code = "void f() {\n" // #5939 " int x;\n" " for (int x = 0; (x = do_something()) != 0;)\n"