Fix #11774 (False positive: passing struct pointer to function that initialize it) (#5162)

This commit is contained in:
Daniel Marjamäki 2023-06-16 18:43:32 +02:00 committed by GitHub
parent b689ca8d89
commit aca6c47024
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 9 deletions

View File

@ -2346,7 +2346,8 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti
const Token * const tok1 = tok;
// address of variable
if (tok->astParent() && tok->astParent()->isUnaryOp("&"))
const bool addressOf = tok->astParent() && tok->astParent()->isUnaryOp("&");
if (addressOf)
indirect++;
int argnr;
@ -2408,6 +2409,8 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti
if (indirect > 0) {
if (arg->isPointer() && !(arg->valueType() && arg->valueType()->isConst(indirect)))
return true;
if (indirect > 1 && addressOf && arg->isPointer() && (!arg->valueType() || !arg->valueType()->isConst(indirect-1)))
return true;
if (arg->isArray() || (!arg->isPointer() && (!arg->valueType() || arg->valueType()->type == ValueType::UNKNOWN_TYPE)))
return true;
}
@ -2482,16 +2485,15 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
}
const ValueType* vt = tok->variable() ? tok->variable()->valueType() : tok->valueType();
// If its already const then it cant be modified
if (vt) {
if (vt->isConst(indirect))
return false;
}
// Check addressof
if (tok2->astParent() && tok2->astParent()->isUnaryOp("&") &&
isVariableChanged(tok2->astParent(), indirect + 1, settings, depth - 1)) {
return true;
if (tok2->astParent() && tok2->astParent()->isUnaryOp("&")) {
if (isVariableChanged(tok2->astParent(), indirect + 1, settings, depth - 1))
return true;
} else {
// If its already const then it cant be modified
if (vt && vt->isConst(indirect))
return false;
}
if (cpp && Token::Match(tok2->astParent(), ">>|&") && astIsRHS(tok2) && isLikelyStreamRead(cpp, tok2->astParent()))

View File

@ -5543,6 +5543,17 @@ private:
"}";
values = tokenValues(code, "n )", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(0, values.size());
// #11774 - function call to init data
code = "struct id_struct { int id; };\n"
"int init(const id_struct **id);\n"
"void fp() {\n"
" const id_struct *id_st;\n"
" init(&id_st);\n"
" if (id_st->id > 0) {}\n"
"}\n";
values = tokenValues(code, ". id", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(0, values.size());
}
void valueFlowConditionExpressions() {