parent
59b955e014
commit
2a0143c8e1
|
@ -1336,6 +1336,13 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
|
||||||
}
|
}
|
||||||
// skip over enum
|
// skip over enum
|
||||||
tok = tok->linkAt(1);
|
tok = tok->linkAt(1);
|
||||||
|
} else if (Token::Match(tok, "%name% [{(] [)}]") && (tok->isStandardType() ||
|
||||||
|
(tok->variable() && tok->variable()->nameToken() == tok &&
|
||||||
|
(tok->variable()->isPointer() || (tok->variable()->valueType() && tok->variable()->valueType()->isIntegral()))))) {
|
||||||
|
ValueFlow::Value value(0);
|
||||||
|
if (!tok->isTemplateArg())
|
||||||
|
value.setKnown();
|
||||||
|
setTokenValue(tok->next(), std::move(value), settings, isInitList);
|
||||||
}
|
}
|
||||||
return tok->next();
|
return tok->next();
|
||||||
}
|
}
|
||||||
|
@ -5770,7 +5777,7 @@ static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> va
|
||||||
static bool isVariableInit(const Token *tok)
|
static bool isVariableInit(const Token *tok)
|
||||||
{
|
{
|
||||||
return (tok->str() == "(" || tok->str() == "{") &&
|
return (tok->str() == "(" || tok->str() == "{") &&
|
||||||
tok->isBinaryOp() &&
|
(tok->isBinaryOp() || (tok->astOperand1() && tok->link() == tok->next())) &&
|
||||||
tok->astOperand1()->variable() &&
|
tok->astOperand1()->variable() &&
|
||||||
tok->astOperand1()->variable()->nameToken() == tok->astOperand1() &&
|
tok->astOperand1()->variable()->nameToken() == tok->astOperand1() &&
|
||||||
tok->astOperand1()->variable()->valueType() &&
|
tok->astOperand1()->variable()->valueType() &&
|
||||||
|
@ -5803,7 +5810,8 @@ static void valueFlowAfterAssign(TokenList *tokenlist,
|
||||||
std::unordered_map<nonneg int, std::unordered_set<nonneg int>> backAssigns;
|
std::unordered_map<nonneg int, std::unordered_set<nonneg int>> backAssigns;
|
||||||
for (Token* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
|
for (Token* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
|
||||||
// Assignment
|
// Assignment
|
||||||
if (tok->str() != "=" && !isVariableInit(tok))
|
bool isInit = false;
|
||||||
|
if (tok->str() != "=" && !(isInit = isVariableInit(tok)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (tok->astParent() && !(tok->astParent()->str() == ";" && astIsLHS(tok)))
|
if (tok->astParent() && !(tok->astParent()->str() == ";" && astIsLHS(tok)))
|
||||||
|
@ -5815,11 +5823,14 @@ static void valueFlowAfterAssign(TokenList *tokenlist,
|
||||||
std::vector<const Variable*> vars = getLHSVariables(tok);
|
std::vector<const Variable*> vars = getLHSVariables(tok);
|
||||||
|
|
||||||
// Rhs values..
|
// Rhs values..
|
||||||
if (!tok->astOperand2() || tok->astOperand2()->values().empty())
|
Token* rhs = tok->astOperand2();
|
||||||
|
if (!rhs && isInit)
|
||||||
|
rhs = tok;
|
||||||
|
if (!rhs || rhs->values().empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::list<ValueFlow::Value> values = truncateValues(
|
std::list<ValueFlow::Value> values = truncateValues(
|
||||||
tok->astOperand2()->values(), tok->astOperand1()->valueType(), tok->astOperand2()->valueType(), settings);
|
rhs->values(), tok->astOperand1()->valueType(), rhs->valueType(), settings);
|
||||||
// Remove known values
|
// Remove known values
|
||||||
std::set<ValueFlow::Value::ValueType> types;
|
std::set<ValueFlow::Value::ValueType> types;
|
||||||
if (tok->astOperand1()->hasKnownValue()) {
|
if (tok->astOperand1()->hasKnownValue()) {
|
||||||
|
@ -5874,7 +5885,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist,
|
||||||
continue;
|
continue;
|
||||||
const bool init = vars.size() == 1 && (vars.front()->nameToken() == tok->astOperand1() || tok->isSplittedVarDeclEq());
|
const bool init = vars.size() == 1 && (vars.front()->nameToken() == tok->astOperand1() || tok->isSplittedVarDeclEq());
|
||||||
valueFlowForwardAssign(
|
valueFlowForwardAssign(
|
||||||
tok->astOperand2(), tok->astOperand1(), vars, values, init, tokenlist, errorLogger, settings);
|
rhs, tok->astOperand1(), vars, values, init, tokenlist, errorLogger, settings);
|
||||||
// Back propagate symbolic values
|
// Back propagate symbolic values
|
||||||
if (tok->astOperand1()->exprId() > 0) {
|
if (tok->astOperand1()->exprId() > 0) {
|
||||||
Token* start = nextAfterAstRightmostLeaf(tok);
|
Token* start = nextAfterAstRightmostLeaf(tok);
|
||||||
|
|
|
@ -5035,16 +5035,24 @@ private:
|
||||||
" return s == 0;\n" // <- known value
|
" return s == 0;\n" // <- known value
|
||||||
"}";
|
"}";
|
||||||
value = valueOfTok(code, "==");
|
value = valueOfTok(code, "==");
|
||||||
TODO_ASSERT_EQUALS(true, false, value.isKnown());
|
ASSERT_EQUALS(true, value.isKnown());
|
||||||
TODO_ASSERT_EQUALS(1, 0, value.intvalue);
|
ASSERT_EQUALS(1, value.intvalue);
|
||||||
|
|
||||||
code = "bool f() {\n"
|
code = "bool f() {\n"
|
||||||
" const int s = int();"
|
" const int s = int();"
|
||||||
" return s == 0;\n" // <- known value
|
" return s == 0;\n" // <- known value
|
||||||
"}";
|
"}";
|
||||||
value = valueOfTok(code, "==");
|
value = valueOfTok(code, "==");
|
||||||
TODO_ASSERT_EQUALS(true, false, value.isKnown());
|
ASSERT_EQUALS(true, value.isKnown());
|
||||||
TODO_ASSERT_EQUALS(1, 0, value.intvalue);
|
ASSERT_EQUALS(1, value.intvalue);
|
||||||
|
|
||||||
|
code = "bool f() {\n"
|
||||||
|
" const int s{};"
|
||||||
|
" return s == 0;\n" // <- known value
|
||||||
|
"}";
|
||||||
|
value = valueOfTok(code, "==");
|
||||||
|
ASSERT_EQUALS(true, value.isKnown());
|
||||||
|
ASSERT_EQUALS(1, value.intvalue);
|
||||||
|
|
||||||
// calculation with known result
|
// calculation with known result
|
||||||
code = "int f(int x) { a = x & 0; }"; // <- & is 0
|
code = "int f(int x) { a = x & 0; }"; // <- & is 0
|
||||||
|
|
Loading…
Reference in New Issue