diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index 3d6078c2d..93c06c627 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -364,6 +364,8 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const const Result &result1 = checkRecursive(expr, tok->tokAt(2), tok->linkAt(1), exprVarIds, local, inInnerClass, depth); if (result1.type == Result::Type::READ || result1.type == Result::Type::BAILOUT) return result1; + if (mWhat == What::UnusedValue && result1.type == Result::Type::WRITE && expr->variable() && expr->variable()->isReference()) + return result1; if (mWhat == What::ValueFlow && result1.type == Result::Type::WRITE) mValueFlowKnown = false; if (mWhat == What::Reassign && result1.type == Result::Type::BREAK) { @@ -530,6 +532,10 @@ bool FwdAnalysis::possiblyAliased(const Token *expr, const Token *startToken) co addrOf = tok->astOperand1(); else if (Token::simpleMatch(tok, "std :: ref (")) addrOf = tok->tokAt(3)->astOperand2(); + else if (tok->valueType() && tok->valueType()->pointer && + (Token::Match(tok, "%var% = %var% ;") || Token::Match(tok, "%var% {|( %var% }|)")) && + Token::Match(expr->previous(), "%varid% [", tok->tokAt(2)->varId())) + addrOf = tok->tokAt(2); else continue; diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 6bccad45f..49c024c3a 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -165,6 +165,8 @@ private: TEST_CASE(localvaralias19); // ticket #9828 TEST_CASE(localvaralias20); // ticket #10966 TEST_CASE(localvaralias21); + TEST_CASE(localvaralias22); + TEST_CASE(localvaralias23); TEST_CASE(localvarasm); TEST_CASE(localvarstatic); TEST_CASE(localvarextern); @@ -5037,6 +5039,36 @@ private: ASSERT_EQUALS("", errout.str()); } + void localvaralias22() { // #11139 + functionVariableUsage("int f() {\n" + " int x[1], *p = x;\n" + " x[0] = 42;\n" + " return *p;\n" + "}\n" + "int g() {\n" + " int x[1], *p{ x };\n" + " x[0] = 42;\n" + " return *p;\n" + "}\n" + "int h() {\n" + " int x[1], *p(x);\n" + " x[0] = 42;\n" + " return *p;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + + void localvaralias23() { // #11817 + functionVariableUsage("void f(int& r, bool a, bool b) {\n" + " int& e = r;\n" + " if (a)\n" + " e = 42;\n" + " else if (b)\n" + " e = 1;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void localvarasm() { functionVariableUsage("void foo(int &b)\n"