Fix issue 8910: Regression: ValueFlow: wrong conditional tokvalue

This fixes issue in:

```cpp
void f()
{
    char stack[512];
    RGNDATA *data;

    if (data_size > sizeof (stack))
        data = malloc (data_size);
    else
        data = (RGNDATA *)stack;

    if ((char *)data != stack)
            free (data); // <- data is not stack
}
```

It seems the `ProgramMemory` can't handle two known values(such as int and tok) together. So instead `ValueFlowAfterAssign` runs `ValueFlowForward` with tok values and then runs it with the other values.
This commit is contained in:
Paul Fultz II 2018-12-29 09:31:21 +01:00 committed by Daniel Marjamäki
parent d18f5d8709
commit e4677ae640
2 changed files with 31 additions and 2 deletions

View File

@ -534,8 +534,9 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
continue;
if (value2.isTokValue() && (!parent->isComparisonOp() || value2.tokvalue->tokType() != Token::eString || value1.isTokValue()))
continue;
if (known || value1.varId == 0U || value2.varId == 0U ||
(value1.varId == value2.varId && value1.varvalue == value2.varvalue && value1.isIntValue() && value2.isIntValue())) {
if (value1.isKnown() || value2.isKnown() || value1.varId == 0U || value2.varId == 0U ||
(value1.varId == value2.varId && value1.varvalue == value2.varvalue && value1.isIntValue() &&
value2.isIntValue())) {
ValueFlow::Value result(0);
combineValueProperties(value1, value2, &result);
const float floatValue1 = value1.isIntValue() ? value1.intvalue : value1.floatValue;
@ -3131,6 +3132,24 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
// Skip RHS
const Token * nextExpression = nextAfterAstRightmostLeaf(tok);
if (std::any_of(values.begin(), values.end(), std::mem_fn(&ValueFlow::Value::isTokValue))) {
std::list<ValueFlow::Value> tokvalues;
std::copy_if(values.begin(),
values.end(),
std::back_inserter(tokvalues),
std::mem_fn(&ValueFlow::Value::isTokValue));
valueFlowForward(const_cast<Token *>(nextExpression),
endOfVarScope,
var,
varid,
tokvalues,
constValue,
false,
tokenlist,
errorLogger,
settings);
values.remove_if(std::mem_fn(&ValueFlow::Value::isTokValue));
}
valueFlowForward(const_cast<Token *>(nextExpression), endOfVarScope, var, varid, values, constValue, false, tokenlist, errorLogger, settings);
}
}

View File

@ -649,6 +649,16 @@ private:
" delete static_cast<SwFmtFld*>(&pTxtFld->GetAttr());\n"
"}");
ASSERT_EQUALS("", errout.str());
// #8910
check("void f() {\n"
" char stack[512];\n"
" RGNDATA *data;\n"
" if (data_size > sizeof (stack)) data = malloc (data_size);\n"
" else data = (RGNDATA *)stack;\n"
" if ((char *)data != stack) free (data);\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void testinvaliddealloc_C() {