From cdfe92b7538213fac47e90cfe4c2b2fff3236471 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 6 Aug 2016 10:27:00 +0200 Subject: [PATCH] Fixed #7657 (False positive: Function parameter 'c' should be passed by reference.) --- lib/symboldatabase.cpp | 8 +++++--- test/testsymboldatabase.cpp | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 17a3db837..3f925c242 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2781,10 +2781,12 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s return; } while (tok->str() != "," && tok->str() != ")" && tok->str() != "="); - const Token *typeTok = startTok->tokAt(startTok->str() == "const" ? 1 : 0); - if (typeTok->str() == "struct" || typeTok->str() == "enum") + const Token *typeTok = startTok; + // skip over stuff to get to type + while (Token::Match(typeTok, "const|enum|struct|::")) typeTok = typeTok->next(); - if (Token::Match(typeTok, "%type% ::")) + // skip over qualification + while (Token::Match(typeTok, "%type% ::")) typeTok = typeTok->tokAt(2); // check for argument with no name or missing varid diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 67ad7f565..b8b55172a 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -186,6 +186,7 @@ private: TEST_CASE(functionArgs6); // #7651 TEST_CASE(functionArgs7); // #7652 TEST_CASE(functionArgs8); // #7653 + TEST_CASE(functionArgs9); // #7657 TEST_CASE(namespaces1); TEST_CASE(namespaces2); @@ -1732,6 +1733,28 @@ private: } } + void functionArgs9() { // #7657 + GET_SYMBOL_DB("struct A {\n" + " struct B {\n" + " enum C { };\n" + " };\n" + "};\n" + "void foo(A::B::C c) { }"); + ASSERT_EQUALS(true, db != nullptr); + if (db) { + const Token *f = Token::findsimplematch(tokenizer.tokens(), "foo ("); + ASSERT_EQUALS(true, f && f->function()); + if (f && f->function()) { + const Function *func = f->function(); + ASSERT_EQUALS(true, func->argumentList.size() == 1 && func->argumentList.front().type()); + if (func->argumentList.size() == 1 && func->argumentList.front().type()) { + const Type * type = func->argumentList.front().type(); + ASSERT_EQUALS(true, type->isEnumType()); + } + } + } + } + void namespaces1() { GET_SYMBOL_DB("namespace fred {\n" " namespace barney {\n"