diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 0cf7e41ff..8f7f9d9e1 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2241,6 +2241,18 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, if (Token::Match(tok2->astParent(), "++|--")) return true; + auto skipRedundantPtrOp = [](const Token* tok, const Token* parent) { + const Token* gparent = parent ? parent->astParent() : nullptr; + while (parent && gparent && ((parent->isUnaryOp("*") && gparent->isUnaryOp("&")) || ((parent->isUnaryOp("&") && gparent->isUnaryOp("*"))))) { + tok = gparent; + parent = gparent->astParent(); + if (parent) + gparent = parent->astParent(); + } + return tok; + }; + tok2 = skipRedundantPtrOp(tok2, tok2->astParent()); + if (tok2->astParent() && tok2->astParent()->isAssignmentOp()) { if (tok2 == tok2->astParent()->astOperand1()) return true; diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 6e6c91d9b..d878092ba 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -6373,6 +6373,17 @@ private: " x.push_back(a);\n" "}\n"); ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: a\n", errout.str()); + + valueFlowUninit("struct S { struct T { int* p; } t[2]; };\n" // #11018 + "void f() {\n" + " S s;\n" + " *&s.t[0].p = 0;\n" + "}\n" + "void g() {\n" + " S s;\n" + " ((*&(*&s.t[0].p))) = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void ctu_(const char* file, int line, const char code[]) {