Fixed #9280 (False positive: unreadVariable on assignment to fixed address volatile struct member)

This commit is contained in:
Daniel Marjamäki 2020-02-15 17:18:21 +01:00
parent 8c0ad6a1b9
commit 67b495fc50
2 changed files with 26 additions and 0 deletions

View File

@ -1970,6 +1970,18 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
return Result(Result::Type::NONE); return Result(Result::Type::NONE);
} }
static bool hasVolatileCast(const Token *expr)
{
bool ret = false;
visitAstNodes(expr,
[&ret](const Token *tok) {
if (Token::simpleMatch(tok, "( volatile"))
ret = true;
return ret ? ChildrenToVisit::none : ChildrenToVisit::op1_and_op2;
});
return ret;
}
bool FwdAnalysis::isGlobalData(const Token *expr) const bool FwdAnalysis::isGlobalData(const Token *expr) const
{ {
bool globalData = false; bool globalData = false;
@ -2114,6 +2126,8 @@ bool FwdAnalysis::hasOperand(const Token *tok, const Token *lhs) const
const Token *FwdAnalysis::reassign(const Token *expr, const Token *startToken, const Token *endToken) const Token *FwdAnalysis::reassign(const Token *expr, const Token *startToken, const Token *endToken)
{ {
if (hasVolatileCast(expr))
return nullptr;
mWhat = What::Reassign; mWhat = What::Reassign;
Result result = check(expr, startToken, endToken); Result result = check(expr, startToken, endToken);
return result.type == FwdAnalysis::Result::Type::WRITE ? result.token : nullptr; return result.type == FwdAnalysis::Result::Type::WRITE ? result.token : nullptr;
@ -2123,6 +2137,8 @@ bool FwdAnalysis::unusedValue(const Token *expr, const Token *startToken, const
{ {
if (isEscapedAlias(expr)) if (isEscapedAlias(expr))
return false; return false;
if (hasVolatileCast(expr))
return false;
mWhat = What::UnusedValue; mWhat = What::UnusedValue;
Result result = check(expr, startToken, endToken); Result result = check(expr, startToken, endToken);
return (result.type == FwdAnalysis::Result::Type::NONE || result.type == FwdAnalysis::Result::Type::RETURN) && !possiblyAliased(expr, startToken); return (result.type == FwdAnalysis::Result::Type::NONE || result.type == FwdAnalysis::Result::Type::RETURN) && !possiblyAliased(expr, startToken);

View File

@ -207,6 +207,7 @@ private:
TEST_CASE(argument); TEST_CASE(argument);
TEST_CASE(argumentClass); TEST_CASE(argumentClass);
TEST_CASE(escapeAlias); // #9150 TEST_CASE(escapeAlias); // #9150
TEST_CASE(volatileData); // #9280
} }
void checkStructMemberUsage(const char code[]) { void checkStructMemberUsage(const char code[]) {
@ -4640,6 +4641,15 @@ private:
); );
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void volatileData() {
functionVariableUsage(
"struct Data { unsigned int n; };\n"
"int main() {\n"
" (*(volatile struct Data*)0x4200).n = 1;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
}; };
REGISTER_TEST(TestUnusedVar) REGISTER_TEST(TestUnusedVar)