diff --git a/AUTHORS b/AUTHORS index e3610324298..4463df0c5ec 100644 --- a/AUTHORS +++ b/AUTHORS @@ -315,6 +315,7 @@ Ryan Pavlik Samir Aguiar Sam Truscott Samuel Degrande +Samuel Poláček Sandeep Dutta Savvas Etairidis Scott Furry diff --git a/cfg/posix.cfg b/cfg/posix.cfg index f07f8fe8b44..7cde306a3ad 100644 --- a/cfg/posix.cfg +++ b/cfg/posix.cfg @@ -2197,7 +2197,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - + @@ -2209,7 +2209,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - + @@ -2221,7 +2221,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - + diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index d76edbf9114..0848f483cd7 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -1031,7 +1031,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) else if ((def || mSettings.preprocessOnly) && !maxconfigs) mSettings.maxConfigs = 1U; - if (mSettings.checks.isEnabled(Checks::unusedFunction) && mSettings.jobs > 1) { + if (mSettings.checks.isEnabled(Checks::unusedFunction) && mSettings.jobs > 1 && mSettings.buildDir.empty()) { printMessage("unusedFunction check can't be used with '-j' option. Disabling unusedFunction check."); } diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 3652eefbe0d..94307ab276f 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -2196,7 +2196,7 @@ T* getTokenArgumentFunctionImpl(T* tok, int& argn) parent = parent->astParent(); // passing variable to subfunction? - if (Token::Match(parent, "[(,{]")) + if (Token::Match(parent, "[[(,{]")) ; else if (Token::simpleMatch(parent, ":")) { while (Token::Match(parent, "[?:]")) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index abf8319241c..a8573b2c8c5 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2582,7 +2582,7 @@ void CheckClass::checkConstError2(const Token *tok1, const Token *tok2, const st "passed to the function. This change should not cause compiler errors but it does not " "necessarily make sense conceptually. Think about your design and the task of the function first - " "is it a function that must not access members of class instances? And maybe it is more appropriate " - "to move this function to a unnamed namespace.", CWE398, Certainty::inconclusive); + "to move this function to an unnamed namespace.", CWE398, Certainty::inconclusive); } //--------------------------------------------------------------------------- diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 41d99055f45..14e7ece42ad 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1107,7 +1107,7 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass) continue; bool isTemplateArg = false; - if (tok->next()->str() != "(") { + if (!Token::Match(tok->next(), "(|{")) { const Token *start = tok; while (Token::Match(start->tokAt(-2), "%name% ::")) start = start->tokAt(-2); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 4bb7268f5d9..302c202316c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4757,7 +4757,8 @@ void Tokenizer::setVarIdPass1() continue; } - if (!scopeStack.top().isEnum || !(Token::Match(tok->previous(), "{|,") && Token::Match(tok->next(), ",|=|}"))) { + if ((!scopeStack.top().isEnum || !(Token::Match(tok->previous(), "{|,") && Token::Match(tok->next(), ",|=|}"))) && + !Token::simpleMatch(tok->next(), ": ;")) { const std::map::const_iterator it = variableMap.map(globalNamespace).find(tok->str()); if (it != variableMap.map(globalNamespace).end()) { tok->varId(it->second); @@ -5249,7 +5250,8 @@ void Tokenizer::createLinks2() } else if (token->str() == "<" && ((token->previous() && (token->previous()->isTemplate() || (token->previous()->isName() && !token->previous()->varId()) || - (token->strAt(-1) == "]" && (!Token::Match(token->linkAt(-1)->previous(), "%name%|)") || token->linkAt(-1)->previous()->isKeyword())))) || + (token->strAt(-1) == "]" && (!Token::Match(token->linkAt(-1)->previous(), "%name%|)") || token->linkAt(-1)->previous()->isKeyword())) || + (token->strAt(-1) == ")" && token->linkAt(-1)->strAt(-1) == "operator"))) || Token::Match(token->next(), ">|>>"))) { type.push(token); if (token->previous()->str() == "template") diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index b4af023ba0d..6a8a5edc858 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1747,7 +1747,7 @@ void TokenList::validateAst() const continue; } - if (const Token* lambdaEnd = findLambdaEndToken(tok)) { // skip lambda captures + if (findLambdaEndToken(tok)) { // skip lambda captures tok = tok->link(); continue; } diff --git a/test/cfg/posix.c b/test/cfg/posix.c index 3da4959536a..0621e983618 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -330,6 +330,13 @@ double nullPointer_erand48(unsigned short xsubi[3]) return erand48(xsubi); } +struct non_const_parameter_erand48_struct { unsigned short xsubi[3]; }; +// No warning is expected that dat can be const +double non_const_parameter_erand48(struct non_const_parameter_erand48_struct *dat) +{ + return erand48(dat->xsubi); +} + unsigned short *nullPointer_seed48(unsigned short seed16v[3]) { // cppcheck-suppress nullPointer diff --git a/test/testclass.cpp b/test/testclass.cpp index 53371d545c3..f79744666c7 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -6061,7 +6061,7 @@ class TestClass : public TestFixture { " int i{};\n" " S f() { return S{ &i }; }\n" "};\n"); - TODO_ASSERT_EQUALS("[test.cpp:7]: (style, inconclusive) Technically the member function 'C::f' can be const.\n", "", errout.str()); + ASSERT_EQUALS("[test.cpp:7]: (style, inconclusive) Technically the member function 'C::f' can be const.\n", errout.str()); checkConst("struct S {\n" " explicit S(const int* p) : mp(p) {}\n" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index fc8558bc921..2e0972d07b8 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -3531,6 +3531,25 @@ class TestTokenizer : public TestFixture { ASSERT_EQUALS(true, tok1->link() == tok2); ASSERT_EQUALS(true, tok2->link() == tok1); } + + { + const char code[] = "struct S {\n" // #11840 + " template\n" + " void operator() (int);\n" + "};\n" + "void f() {\n" + " S s;\n" + " s.operator()(1);\n" + "}\n"; + errout.str(""); + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + const Token* tok1 = Token::findsimplematch(tokenizer.tokens(), "< int"); + const Token* tok2 = Token::findsimplematch(tok1, "> ("); + ASSERT_EQUALS(true, tok1->link() == tok2); + ASSERT_EQUALS(true, tok2->link() == tok1); + } } void simplifyString() { diff --git a/test/testvarid.cpp b/test/testvarid.cpp index e0ffc150020..90dfeafe604 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -2785,6 +2785,17 @@ class TestVarID : public TestFixture { " break;\n" " }\n" "}", "test.c")); + + ASSERT_EQUALS("1: int * f ( ) {\n" // #11838 + "2: int * label@1 ; label@1 = 0 ;\n" + "3: label : ;\n" + "4: return label@1 ;\n" + "5: }\n", + tokenize("int* f() {\n" + " int* label = 0;\n" + "label:\n" + " return label;\n" + "}")); } void varid_structinit() { // #6406