diff --git a/lib/checkio.cpp b/lib/checkio.cpp index be9085009..3a88e9cef 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -823,9 +823,19 @@ bool CheckIO::getArgumentInfo(const Token * tok, const Variable **var, const Tok if (varTok) { const Variable *variableInfo = varTok->variable(); *var = variableInfo; - *typeTok = variableInfo ? variableInfo->typeStartToken() : NULL; - *func = 0; element = tok1->previous()->str() == "]"; + + // look for std::vector operator [] and use template type as return type + if (variableInfo) { + if (element && Token::Match(variableInfo->typeStartToken(), "std :: vector|array <")) { + *typeTok = variableInfo->typeStartToken()->tokAt(4); + element = false; // not really an array element + } else + *typeTok = variableInfo->typeStartToken(); + } else + *typeTok = NULL; + + *func = 0; return true; } } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 24e523951..1b917fbea 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2499,6 +2499,18 @@ const Function* Scope::findFunction(const Token *tok) const } } + // check in base classes + if (isClassOrStruct() && definedType && !definedType->derivedFrom.empty()) { + for (std::size_t i = 0; i < definedType->derivedFrom.size(); ++i) { + const Type *base = definedType->derivedFrom[i].type; + if (base && base->classScope) { + const Function * func = base->classScope->findFunction(tok); + if (func) + return func; + } + } + } + return 0; } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 5529eec60..88defc5d2 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5507,7 +5507,7 @@ void Tokenizer::simplifyPlatformTypes() tok->insertToken("*"); tok->insertToken("wchar_t"); } - } else if (Token::Match(tok, "ULONG64|DWORD64")) { + } else if (Token::Match(tok, "ULONG64|DWORD64|ULONGLONG")) { tok->isUnsigned(true); tok->isLong(true); tok->str("long"); diff --git a/test/testio.cpp b/test/testio.cpp index 1485279f7..0184e8997 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -1039,6 +1039,20 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:4]: (warning) %f in format string (no. 1) requires a floating point number given in the argument list.\n", errout.str()); + check("struct Base { int length() { } };\n" + "struct Derived : public Base { };\n" + "void foo(Derived * d) {\n" + " printf(\"%f\", d.length());\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (warning) %f in format string (no. 1) requires a floating point number given in the argument list.\n", errout.str()); + + check("std::vector v;\n" + "void foo() {\n" + " printf(\"%d %u %f\", v[0], v[0], v[0]);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires an unsigned integer given in the argument list.\n" + "[test.cpp:3]: (warning) %f in format string (no. 3) requires a floating point number given in the argument list.\n", errout.str()); + } void testPosixPrintfScanfParameterPosition() { // #4900 - No support for parameters in format strings