From a7d487f6db4a35045a1f91c71be8f7fea048d1e8 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 11 Aug 2023 18:45:58 +0200 Subject: [PATCH] Fix #11805 FP uninitvar for stringstream into deref pointer to uninit var / #11804 FP uninitvar for array in struct in struct (#5311) --- lib/astutils.cpp | 7 +++++-- lib/checkuninitvar.cpp | 2 +- test/testuninitvar.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index ca7c08af3..b1dc9900a 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -3142,11 +3142,14 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings) return getExprUsage(tok->astParent()->astParent(), indirect, settings); } if (indirect == 0) { - if (Token::Match(tok->astParent(), "%cop%|%assign%|++|--") && !Token::simpleMatch(tok->astParent(), "=") && + if (Token::Match(tok->astParent(), "%cop%|%assign%|++|--") && !Token::Match(tok->astParent(), "=|>>") && !tok->astParent()->isUnaryOp("&")) return ExprUsage::Used; - if (Token::simpleMatch(tok->astParent(), "=") && astIsRHS(tok)) + if (Token::simpleMatch(tok->astParent(), "=") && astIsRHS(tok)) { + if (tok->astParent()->astOperand1() && tok->astParent()->astOperand1()->variable() && tok->astParent()->astOperand1()->variable()->isReference()) + return ExprUsage::NotUsed; return ExprUsage::Used; + } // Function call or index if (((Token::simpleMatch(tok->astParent(), "(") && !tok->astParent()->isCast()) || (Token::simpleMatch(tok->astParent(), "[") && tok->valueType())) && (astIsLHS(tok) || Token::simpleMatch(tok->astParent(), "( )"))) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index e30dfebc1..887e38b61 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1579,7 +1579,7 @@ static bool isLeafDot(const Token* tok) const Token * parent = tok->astParent(); if (!Token::simpleMatch(parent, ".")) return false; - if (parent->astOperand2() == tok) + if (parent->astOperand2() == tok && !Token::simpleMatch(parent->astParent(), ".")) return true; return isLeafDot(parent); } diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 924ebcaa6..fdaad7eb1 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -6127,6 +6127,48 @@ private: " int *q = 1 ? &y : 0;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + valueFlowUninit("void f(std::stringstream& ss) {\n" // #11805 + " int x;\n" + " int* p = &x;\n" + " ss >> *p;\n" + "}\n" + "void g() {\n" + " int x;\n" + " int* p = &x;\n" + " int& r = *p;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + valueFlowUninit("void f(std::stringstream& ss) {\n" // #11805 + " int x;\n" + " int* p = &x;\n" + " ss >> *p;\n" + "}\n" + "void g() {\n" + " int x;\n" + " int* p = &x;\n" + " int& r = *p;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + valueFlowUninit("struct S1 { char a[10]; };\n" // #11804 + "struct S2 { struct S1 s1; };\n" + "void init(char* c);\n" + "void f() {\n" + " struct S2 s2;\n" + " init(s2.s1.a);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + valueFlowUninit("struct S { int i; };\n" // #11731 + "void f(const S*& p);\n" + "int g() {\n" + " const S* s;\n" + " f(s);\n" + " return s->i;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value