Skip to content

Commit 62a5d88

Browse files
committed
ValueFlow: Improved handling of strings
1 parent dd70b6e commit 62a5d88

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

lib/valueflow.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,29 @@ static void valueFlowNumber(TokenList *tokenlist)
374374

375375
static void valueFlowString(TokenList *tokenlist)
376376
{
377+
std::map<unsigned int, const Token *> constantStrings;
378+
377379
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
378380
if (tok->type() == Token::eString) {
379381
ValueFlow::Value strvalue;
380382
strvalue.tokvalue = tok;
381383
setTokenValue(tok, strvalue);
382384
}
385+
386+
if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) {
387+
const Token *vartok = tok->tokAt(2);
388+
const Token *strtok = tok->linkAt(3)->tokAt(2);
389+
constantStrings[vartok->varId()] = strtok;
390+
}
391+
392+
if (tok->varId() > 0U) {
393+
const std::map<unsigned int, const Token *>::const_iterator it = constantStrings.find(tok->varId());
394+
if (it != constantStrings.end()) {
395+
ValueFlow::Value strvalue;
396+
strvalue.tokvalue = it->second;
397+
setTokenValue(tok, strvalue);
398+
}
399+
}
383400
}
384401
}
385402

@@ -1337,6 +1354,27 @@ static void execute(const Token *expr,
13371354
execute(expr->astOperand2(), programMemory, result, error);
13381355
}
13391356

1357+
else if (expr->str() == "[" && expr->astOperand1() && expr->astOperand2()) {
1358+
if (expr->astOperand1()->values.size() != 1U) {
1359+
*error = true;
1360+
return;
1361+
}
1362+
const ValueFlow::Value val = expr->astOperand1()->values.front();
1363+
if (!val.tokvalue || !val.tokvalue->isLiteral()) {
1364+
*error = true;
1365+
return;
1366+
}
1367+
const std::string strValue = val.tokvalue->strValue();
1368+
MathLib::bigint index = 0;
1369+
execute(expr->astOperand2(), programMemory, &index, error);
1370+
if (index >= 0 && index < (int)strValue.size())
1371+
*result = strValue[index];
1372+
else if (index == (int)strValue.size())
1373+
*result = 0;
1374+
else
1375+
*error = true;
1376+
}
1377+
13401378
else
13411379
*error = true;
13421380
}

test/testvalueflow.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,14 @@ class TestValueFlow : public TestFixture {
12441244
"}";
12451245
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
12461246

1247+
code = "void f() {\n"
1248+
" const char abc[] = \"abc\";\n"
1249+
" int x;\n"
1250+
" for (x = 0; abc[x] != '\\0'; x++) {}\n"
1251+
" a[x] = 0;\n"
1252+
"}";
1253+
ASSERT_EQUALS(true, testValueOfX(code, 5U, 3));
1254+
12471255
code = "void f() {\n" // #5939
12481256
" int x;\n"
12491257
" for (int x = 0; (x = do_something()) != 0;)\n"

0 commit comments

Comments
 (0)