Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3670,21 +3670,27 @@ bool isGlobalData(const Token *expr)
globalData = true;
return ChildrenToVisit::none;
}
if (Token::Match(tok, "[*[]") && tok->astOperand1() && tok->astOperand1()->variable()) {
if (Token::Match(tok, "[*[]") && tok->astOperand1()) {
// TODO check if pointer points at local data
const Variable *lhsvar = tok->astOperand1()->variable();
const ValueType *lhstype = tok->astOperand1()->valueType();
if (lhsvar->isPointer() || !lhstype || lhstype->type == ValueType::Type::ITERATOR) {
globalData = true;
return ChildrenToVisit::none;
}
if (lhsvar->isArgument() && lhsvar->isArray()) {
globalData = true;
return ChildrenToVisit::none;
const Token *lhs = tok->astOperand1();
if (!lhs->variable() && Token::Match(lhs, "( %type%")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably better to check lhs->isCast() && !lhs->astOperand2(). That should also handle (::Type).

lhs = lhs->astOperand1();
}
if (lhsvar->isArgument() && lhstype->type <= ValueType::Type::VOID && !lhstype->container) {
globalData = true;
return ChildrenToVisit::none;
if (lhs && lhs->variable()) {
const Variable *lhsvar = lhs->variable();
const ValueType *lhstype = lhs->valueType();
if (lhsvar->isPointer() || !lhstype || lhstype->type == ValueType::Type::ITERATOR) {
globalData = true;
return ChildrenToVisit::none;
}
if (lhsvar->isArgument() && lhsvar->isArray()) {
globalData = true;
return ChildrenToVisit::none;
}
if (lhsvar->isArgument() && lhstype->type <= ValueType::Type::VOID && !lhstype->container) {
globalData = true;
return ChildrenToVisit::none;
}
}
}
if (tok->varId() == 0 && tok->isName() && tok->strAt(-1) != ".") {
Expand Down
11 changes: 11 additions & 0 deletions test/testunusedvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ class TestUnusedVar : public TestFixture {
TEST_CASE(globalData);

TEST_CASE(structuredBinding); // #13269

TEST_CASE(pointerCast); // #14535
}

struct FunctionVariableUsageOptions
Expand Down Expand Up @@ -7308,6 +7310,15 @@ class TestUnusedVar : public TestFixture {
"}\n");
ASSERT_EQUALS("", errout_str());
}

void pointerCast() { // #14535
functionVariableUsage("void f(int* p)\n"
"{\n"
" int* p2 = p;\n"
" ((int *)(p2))[0] = 0; // remove cast for warning to disappear\n"
"}\n");
ASSERT_EQUALS("", errout_str());
}
};

REGISTER_TEST(TestUnusedVar)
Loading