Skip to content

Commit 085cc68

Browse files
authored
Fix #14535: false positive: unreadVariable (array access after pointer cast) (danmar#8324)
1 parent 01fd500 commit 085cc68

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

lib/astutils.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3696,21 +3696,27 @@ bool isGlobalData(const Token *expr)
36963696
globalData = true;
36973697
return ChildrenToVisit::none;
36983698
}
3699-
if (Token::Match(tok, "[*[]") && tok->astOperand1() && tok->astOperand1()->variable()) {
3699+
if (Token::Match(tok, "[*[]") && tok->astOperand1()) {
37003700
// TODO check if pointer points at local data
3701-
const Variable *lhsvar = tok->astOperand1()->variable();
3702-
const ValueType *lhstype = tok->astOperand1()->valueType();
3703-
if (lhsvar->isPointer() || !lhstype || lhstype->type == ValueType::Type::ITERATOR) {
3704-
globalData = true;
3705-
return ChildrenToVisit::none;
3706-
}
3707-
if (lhsvar->isArgument() && lhsvar->isArray()) {
3708-
globalData = true;
3709-
return ChildrenToVisit::none;
3701+
const Token *lhs = tok->astOperand1();
3702+
if (lhs->isCast()) {
3703+
lhs = lhs->astOperand2() ? lhs->astOperand2() : lhs->astOperand1();
37103704
}
3711-
if (lhsvar->isArgument() && lhstype->type <= ValueType::Type::VOID && !lhstype->container) {
3712-
globalData = true;
3713-
return ChildrenToVisit::none;
3705+
if (lhs && lhs->variable()) {
3706+
const Variable *lhsvar = lhs->variable();
3707+
const ValueType *lhstype = lhs->valueType();
3708+
if (lhsvar->isPointer() || !lhstype || lhstype->type == ValueType::Type::ITERATOR) {
3709+
globalData = true;
3710+
return ChildrenToVisit::none;
3711+
}
3712+
if (lhsvar->isArgument() && lhsvar->isArray()) {
3713+
globalData = true;
3714+
return ChildrenToVisit::none;
3715+
}
3716+
if (lhsvar->isArgument() && lhstype->type <= ValueType::Type::VOID && !lhstype->container) {
3717+
globalData = true;
3718+
return ChildrenToVisit::none;
3719+
}
37143720
}
37153721
}
37163722
if (tok->varId() == 0 && tok->isName() && tok->strAt(-1) != ".") {

test/testunusedvar.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ class TestUnusedVar : public TestFixture {
271271
TEST_CASE(globalData);
272272

273273
TEST_CASE(structuredBinding); // #13269
274+
275+
TEST_CASE(pointerCast1); // #14535
276+
TEST_CASE(pointerCast2);
274277
}
275278

276279
struct FunctionVariableUsageOptions
@@ -7359,6 +7362,24 @@ class TestUnusedVar : public TestFixture {
73597362
"}\n");
73607363
ASSERT_EQUALS("", errout_str());
73617364
}
7365+
7366+
void pointerCast1() { // #14535
7367+
functionVariableUsage("void f(int* p)\n"
7368+
"{\n"
7369+
" int* p2 = p;\n"
7370+
" ((int *)(p2))[0] = 0;\n"
7371+
"}\n");
7372+
ASSERT_EQUALS("", errout_str());
7373+
}
7374+
7375+
void pointerCast2() {
7376+
functionVariableUsage("void f(int* p)\n"
7377+
"{\n"
7378+
" int* p2 = p;\n"
7379+
" static_cast<int*>(p2)[0] = 0;\n"
7380+
"}\n");
7381+
ASSERT_EQUALS("", errout_str());
7382+
}
73627383
};
73637384

73647385
REGISTER_TEST(TestUnusedVar)

0 commit comments

Comments
 (0)