From 2c73f8fbe8ece44642a11de84f1b0b284fedc969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 11 Mar 2026 12:04:25 +0100 Subject: [PATCH 1/2] Add tests --- test/testunusedvar.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 75fe4e85e1d..0c79be59f42 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -271,6 +271,9 @@ class TestUnusedVar : public TestFixture { TEST_CASE(globalData); TEST_CASE(structuredBinding); // #13269 + + TEST_CASE(pointerCast1); // #14535 + TEST_CASE(pointerCast2); } struct FunctionVariableUsageOptions @@ -7324,6 +7327,24 @@ class TestUnusedVar : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); } + + void pointerCast1() { // #14535 + functionVariableUsage("void f(int* p)\n" + "{\n" + " int* p2 = p;\n" + " ((int *)(p2))[0] = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + + void pointerCast2() { + functionVariableUsage("void f(int* p)\n" + "{\n" + " int* p2 = p;\n" + " static_cast(p2)[0] = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } }; REGISTER_TEST(TestUnusedVar) From ab0eba60aa12083d100a570c77f0e690c0822702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20Gunne=20Lindstr=C3=B6m?= Date: Wed, 11 Mar 2026 11:44:02 +0100 Subject: [PATCH 2/2] Fix #14353 --- lib/astutils.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index f16144310ac..a77dd5c4af1 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3671,21 +3671,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() && lhs->isCast()) { + 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) != ".") {