From 1bfe98447a85ccb78d592b39503add5e4f807520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 15 Dec 2018 11:54:00 +0100 Subject: [PATCH] FwdAnalysis: Tweak possiblyAliased --- lib/astutils.cpp | 20 +++++++++++++------- test/testunusedvar.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 69f685b35..0454792bb 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1296,14 +1296,20 @@ bool FwdAnalysis::possiblyAliased(const Token *expr, const Token *startToken) co const bool followVar = false; for (const Token *tok = startToken; tok; tok = tok->previous()) { if (tok->str() == "{" && tok->scope()->type == Scope::eFunction) + break; + + const Token *addrOf = nullptr; + if (Token::Match(tok, "& %name% =")) + addrOf = tok->tokAt(2)->astOperand2(); + else if (tok->isUnaryOp("&")) + addrOf = tok->astOperand1(); + else if (Token::simpleMatch(tok, "std :: ref (")) + addrOf = tok->tokAt(3)->astOperand2(); + else continue; - if (isSameExpression(mCpp, macro, expr, tok, mLibrary, pure, followVar)) { - const Token *parent = tok->astParent(); - if (parent && parent->isUnaryOp("&")) - return true; - if (parent && Token::Match(parent->tokAt(-2), "& %name% =")) - return true; - if (parent && Token::simpleMatch(parent->tokAt(-3), "std :: ref (")) + + for (const Token *subexpr = expr; subexpr; subexpr = subexpr->astOperand1()) { + if (isSameExpression(mCpp, macro, subexpr, addrOf, mLibrary, pure, followVar)) return true; } } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index eb42ce20e..691843dfb 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -150,6 +150,7 @@ private: TEST_CASE(localvarStruct3); TEST_CASE(localvarStruct5); TEST_CASE(localvarStruct6); + TEST_CASE(localvarStruct7); TEST_CASE(localvarStructArray); TEST_CASE(localvarOp); // Usage with arithmetic operators @@ -3279,6 +3280,46 @@ private: ASSERT_EQUALS("", errout.str()); } + void localvarStruct7() { + functionVariableUsage("struct IMAPARG {\n" + " void *text;\n" + "};\n" + "\n" + "void fun() {\n" + " IMAPARG *args, aatt;\n" + " args = &aatt;\n" + " aatt.text = tmp;\n" + " dostuff(args);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + functionVariableUsage("struct ARG {\n" + " void *a;\n" + " void *b;\n" + "};\n" + "\n" + "void fun() {\n" + " ARG aatt;\n" + " int *p = &aatt.b;\n" + " aatt.a = 123;\n" + " dostuff(p);\n" + "}"); + ASSERT_EQUALS("[test.cpp:9]: (style) Variable 'aatt.a' is assigned a value that is never used.\n", errout.str()); + + functionVariableUsage("struct AB {\n" + " int a;\n" + " int b;\n" + "};\n" + "\n" + "void fun() {\n" + " AB ab;\n" + " int &a = ab.a;\n" + " ab.a = 123;\n" + " dostuff(a);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void localvarStructArray() { // #3633 - detect that struct array is assigned a value functionVariableUsage("void f() {\n"