This commit is contained in:
parent
c1f6132745
commit
33981fe42c
|
@ -2290,6 +2290,8 @@ static T* getTokenArgumentFunctionImpl(T* tok, int& argn)
|
||||||
tok = tok->astOperand1();
|
tok = tok->astOperand1();
|
||||||
while (tok && (tok->isUnaryOp("*") || tok->str() == "["))
|
while (tok && (tok->isUnaryOp("*") || tok->str() == "["))
|
||||||
tok = tok->astOperand1();
|
tok = tok->astOperand1();
|
||||||
|
if (Token::Match(tok, ". * %name%")) // bailout for pointer to member
|
||||||
|
return tok->tokAt(2);
|
||||||
while (Token::simpleMatch(tok, "."))
|
while (Token::simpleMatch(tok, "."))
|
||||||
tok = tok->astOperand2();
|
tok = tok->astOperand2();
|
||||||
while (Token::simpleMatch(tok, "::")) {
|
while (Token::simpleMatch(tok, "::")) {
|
||||||
|
@ -2630,6 +2632,8 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
|
||||||
if (!ftok->function() || !ftok->function()->isConst())
|
if (!ftok->function() || !ftok->function()->isConst())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (Token::Match(tok2->astParent(), ". * %name%")) // bailout
|
||||||
|
return true;
|
||||||
|
|
||||||
if (Token::simpleMatch(tok2, "[") && astIsContainer(tok) && vt && vt->container && vt->container->stdAssociativeLike)
|
if (Token::simpleMatch(tok2, "[") && astIsContainer(tok) && vt && vt->container && vt->container->stdAssociativeLike)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1390,6 +1390,8 @@ void CheckOther::checkConstVariable()
|
||||||
continue;
|
continue;
|
||||||
if (var->isVolatile())
|
if (var->isVolatile())
|
||||||
continue;
|
continue;
|
||||||
|
if (var->nameToken()->isExpandedMacro())
|
||||||
|
continue;
|
||||||
if (isStructuredBindingVariable(var)) // TODO: check all bound variables
|
if (isStructuredBindingVariable(var)) // TODO: check all bound variables
|
||||||
continue;
|
continue;
|
||||||
if (isVariableChanged(var, mSettings, mTokenizer->isCPP()))
|
if (isVariableChanged(var, mSettings, mTokenizer->isCPP()))
|
||||||
|
@ -1461,25 +1463,6 @@ void CheckOther::checkConstVariable()
|
||||||
if (usedInAssignment)
|
if (usedInAssignment)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Skip if we ever cast this variable to a pointer/reference to a non-const type
|
|
||||||
{
|
|
||||||
bool castToNonConst = false;
|
|
||||||
for (const Token* tok = var->nameToken(); tok != scope->bodyEnd && tok != nullptr; tok = tok->next()) {
|
|
||||||
if (tok->isCast()) {
|
|
||||||
if (!tok->valueType()) {
|
|
||||||
castToNonConst = true; // safe guess
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const bool isConst = tok->valueType()->isConst(tok->valueType()->pointer);
|
|
||||||
if (!isConst) {
|
|
||||||
castToNonConst = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (castToNonConst)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
constVariableError(var, hasFunction ? function : nullptr);
|
constVariableError(var, hasFunction ? function : nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -619,7 +619,7 @@ namespace {
|
||||||
bool mUsed = false;
|
bool mUsed = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TypedefSimplifier(Token* typedefToken, int &num) : mTypedefToken(typedefToken) {
|
explicit TypedefSimplifier(Token* typedefToken) : mTypedefToken(typedefToken) {
|
||||||
Token* start = typedefToken->next();
|
Token* start = typedefToken->next();
|
||||||
if (Token::simpleMatch(start, "typename"))
|
if (Token::simpleMatch(start, "typename"))
|
||||||
start = start->next();
|
start = start->next();
|
||||||
|
@ -641,7 +641,6 @@ namespace {
|
||||||
mRangeTypeQualifiers = rangeQualifiers;
|
mRangeTypeQualifiers = rangeQualifiers;
|
||||||
Token* typeName = rangeBefore.second->previous();
|
Token* typeName = rangeBefore.second->previous();
|
||||||
if (typeName->isKeyword()) {
|
if (typeName->isKeyword()) {
|
||||||
(void)num;
|
|
||||||
// TODO typeName->insertToken("T:" + std::to_string(num++));
|
// TODO typeName->insertToken("T:" + std::to_string(num++));
|
||||||
typeName->insertToken(nameToken->str());
|
typeName->insertToken(nameToken->str());
|
||||||
}
|
}
|
||||||
|
@ -1048,8 +1047,7 @@ void Tokenizer::simplifyTypedef()
|
||||||
std::map<std::string, int> numberOfTypedefs;
|
std::map<std::string, int> numberOfTypedefs;
|
||||||
for (Token* tok = list.front(); tok; tok = tok->next()) {
|
for (Token* tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (tok->str() == "typedef") {
|
if (tok->str() == "typedef") {
|
||||||
int dummy = 0;
|
TypedefSimplifier ts(tok);
|
||||||
TypedefSimplifier ts(tok, dummy);
|
|
||||||
if (!ts.fail())
|
if (!ts.fail())
|
||||||
numberOfTypedefs[ts.name()]++;
|
numberOfTypedefs[ts.name()]++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1057,7 +1055,6 @@ void Tokenizer::simplifyTypedef()
|
||||||
}
|
}
|
||||||
|
|
||||||
int indentlevel = 0;
|
int indentlevel = 0;
|
||||||
int typeNum = 1;
|
|
||||||
std::map<std::string, TypedefSimplifier> typedefs;
|
std::map<std::string, TypedefSimplifier> typedefs;
|
||||||
for (Token* tok = list.front(); tok; tok = tok->next()) {
|
for (Token* tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (!tok->isName()) {
|
if (!tok->isName()) {
|
||||||
|
@ -1069,7 +1066,7 @@ void Tokenizer::simplifyTypedef()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indentlevel == 0 && tok->str() == "typedef") {
|
if (indentlevel == 0 && tok->str() == "typedef") {
|
||||||
TypedefSimplifier ts(tok, typeNum);
|
TypedefSimplifier ts(tok);
|
||||||
if (!ts.fail() && numberOfTypedefs[ts.name()] == 1) {
|
if (!ts.fail() && numberOfTypedefs[ts.name()] == 1) {
|
||||||
if (mSettings->severity.isEnabled(Severity::portability) && ts.isInvalidConstFunctionType(typedefs))
|
if (mSettings->severity.isEnabled(Severity::portability) && ts.isInvalidConstFunctionType(typedefs))
|
||||||
reportError(tok->next(), Severity::portability, "invalidConstFunctionType",
|
reportError(tok->next(), Severity::portability, "invalidConstFunctionType",
|
||||||
|
|
|
@ -5238,7 +5238,7 @@ static const Scope* getLoopScope(const Token* tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
static void valueFlowConditionExpressions(TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger *errorLogger, const Settings &settings)
|
static void valueFlowConditionExpressions(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger *errorLogger, const Settings &settings)
|
||||||
{
|
{
|
||||||
for (const Scope * scope : symboldatabase.functionScopes) {
|
for (const Scope * scope : symboldatabase.functionScopes) {
|
||||||
if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) {
|
if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) {
|
||||||
|
@ -7482,7 +7482,7 @@ static void valueFlowInjectParameter(const TokenList& tokenlist,
|
||||||
settings);
|
settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void valueFlowSwitchVariable(TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
|
static void valueFlowSwitchVariable(const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
|
||||||
{
|
{
|
||||||
for (const Scope &scope : symboldatabase.scopeList) {
|
for (const Scope &scope : symboldatabase.scopeList) {
|
||||||
if (scope.type != Scope::ScopeType::eSwitch)
|
if (scope.type != Scope::ScopeType::eSwitch)
|
||||||
|
|
|
@ -4206,7 +4206,7 @@ void uninivar_istream_read(std::istream &f)
|
||||||
f.read(buffer, size);
|
f.read(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitvar_string_compare(std::string &teststr, std::wstring &testwstr)
|
void uninitvar_string_compare(const std::string &teststr, const std::wstring &testwstr)
|
||||||
{
|
{
|
||||||
const char *pStrUninit;
|
const char *pStrUninit;
|
||||||
// cppcheck-suppress uninitvar
|
// cppcheck-suppress uninitvar
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <wx/textctrl.h>
|
#include <wx/textctrl.h>
|
||||||
#include <wx/propgrid/property.h>
|
#include <wx/propgrid/property.h>
|
||||||
|
|
||||||
void uninitvar_wxRegEx_GetMatch(wxRegEx &obj, size_t *start, size_t *len, size_t index)
|
void uninitvar_wxRegEx_GetMatch(const wxRegEx &obj, size_t *start, size_t *len, size_t index)
|
||||||
{
|
{
|
||||||
size_t s,l;
|
size_t s,l;
|
||||||
size_t *sPtr,*lPtr;
|
size_t *sPtr,*lPtr;
|
||||||
|
|
|
@ -2873,7 +2873,7 @@ private:
|
||||||
" x.f();\n"
|
" x.f();\n"
|
||||||
" foo( static_cast<U2>(0) );\n"
|
" foo( static_cast<U2>(0) );\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
check("class a {\n"
|
check("class a {\n"
|
||||||
" void foo(const int& i) const;\n"
|
" void foo(const int& i) const;\n"
|
||||||
|
@ -3375,6 +3375,18 @@ private:
|
||||||
"[test.cpp:1]: (style) Parameter 's2' can be declared as reference to const\n",
|
"[test.cpp:1]: (style) Parameter 's2' can be declared as reference to const\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
|
check("void f(int& r) {\n" // #12214
|
||||||
|
" (void)(true);\n"
|
||||||
|
" if (r) {}\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'r' can be declared as reference to const\n", errout.str());
|
||||||
|
|
||||||
|
check("struct S { void f(int&); };\n" // #12216
|
||||||
|
"void g(S& s, int& r, void (S::* p2m)(int&)) {\n"
|
||||||
|
" (s.*p2m)(r);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("struct S {\n"
|
check("struct S {\n"
|
||||||
" void f(int& r) { p = &r; }\n"
|
" void f(int& r) { p = &r; }\n"
|
||||||
" int* p;\n"
|
" int* p;\n"
|
||||||
|
@ -10861,7 +10873,9 @@ private:
|
||||||
" for (auto &j : g(std::move(l))) { (void)j; }\n"
|
" for (auto &j : g(std::move(l))) { (void)j; }\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (warning) Access of moved variable 'l'.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'j' can be declared as reference to const\n"
|
||||||
|
"[test.cpp:4]: (warning) Access of moved variable 'l'.\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveCallback()
|
void moveCallback()
|
||||||
|
|
Loading…
Reference in New Issue