From f934d6e5d0d02dc774e0439061774c1be3c232da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 15 Jun 2023 14:42:58 +0200 Subject: [PATCH] Fix #11767 (False positive: uninitialized member after assignment) (#5157) --- lib/astutils.cpp | 10 +++++++++- test/testvalueflow.cpp | 14 +++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 20305a7d3..876c8665b 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2432,7 +2432,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, int derefs = 0; while (Token::simpleMatch(tok2->astParent(), "*") || (Token::simpleMatch(tok2->astParent(), ".") && !Token::simpleMatch(tok2->astParent()->astParent(), "(")) || - (tok2->astParent() && tok2->astParent()->isUnaryOp("&") && !tok2->astParent()->astOperand2() && Token::simpleMatch(tok2->astParent()->astParent(), ".") && tok2->astParent()->astParent()->originalName()=="->") || + (tok2->astParent() && tok2->astParent()->isUnaryOp("&") && Token::simpleMatch(tok2->astParent()->astParent(), ".") && tok2->astParent()->astParent()->originalName()=="->") || (Token::simpleMatch(tok2->astParent(), "[") && tok2 == tok2->astParent()->astOperand1())) { if (tok2->astParent() && (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->"))) derefs++; @@ -2443,6 +2443,14 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, tok2 = tok2->astParent(); } + if (tok2->astParent() && tok2->astParent()->isUnaryOp("&")) { + const Token* parent = tok2->astParent(); + while (parent->astParent() && parent->astParent()->isCast()) + parent = parent->astParent(); + if (parent->astParent() && parent->astParent()->isUnaryOp("*")) + tok2 = parent->astParent(); + } + while ((Token::simpleMatch(tok2, ":") && Token::simpleMatch(tok2->astParent(), "?")) || (Token::simpleMatch(tok2->astParent(), ":") && Token::simpleMatch(tok2->astParent()->astParent(), "?"))) tok2 = tok2->astParent(); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 1f5cb95a8..d079be41e 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5295,7 +5295,7 @@ private: // initialization code = "int foo() {\n" " int x;\n" - " *((int *)(&x)) = 12;" + " *((int *)(&x)) = 12;\n" " a = x + 1;\n" "}"; values = tokenValues(code, "x +"); @@ -5304,6 +5304,18 @@ private: // ASSERT(values.front().isIntValue()); // ASSERT_EQUALS(12, values.front().intvalue); + code = "struct AB { int a; };\n" // 11767 + "void fp(void) {\n" + " struct AB ab;\n" + " *((int*)(&(ab.a))) = 1;\n" + " x = ab.a + 1;\n" // <- not uninitialized + "}\n"; + values = tokenValues(code, "ab . a +"); + ASSERT_EQUALS(0, values.size()); + // ASSERT_EQUALS(1U, values.size()); + // ASSERT(values.front().isIntValue()); + // ASSERT_EQUALS(1, values.front().intvalue); + // #8036 code = "void foo() {\n" " int x;\n"