Fixed #1525 (false negative: the function can be declared as const (member declared as mutable))
This commit is contained in:
parent
307000b448
commit
45865f54a8
|
@ -112,6 +112,14 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo
|
|||
if (next->str() == "typedef")
|
||||
continue;
|
||||
|
||||
// Is it a mutable variable?
|
||||
bool isMutable = false;
|
||||
if (next->str() == "mutable")
|
||||
{
|
||||
isMutable = true;
|
||||
next = next->next();
|
||||
}
|
||||
|
||||
// Is it a variable declaration?
|
||||
if (Token::Match(next, "%type% %var% ;"))
|
||||
{
|
||||
|
@ -174,7 +182,7 @@ CheckClass::Var *CheckClass::getVarList(const Token *tok1, bool withClasses, boo
|
|||
// If the varname was set in one of the two if-block above, create a entry for this variable..
|
||||
if (!varname.empty() && varname != "operator")
|
||||
{
|
||||
Var *var = new Var(varname, false, priv, varlist);
|
||||
Var *var = new Var(varname, false, priv, isMutable, varlist);
|
||||
varlist = var;
|
||||
}
|
||||
}
|
||||
|
@ -1774,7 +1782,9 @@ bool CheckClass::isMemberVar(const Var *varlist, const Token *tok)
|
|||
for (const Var *var = varlist; var; var = var->next)
|
||||
{
|
||||
if (var->name == tok->str())
|
||||
return true;
|
||||
{
|
||||
return !var->isMutable;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -113,12 +113,13 @@ private:
|
|||
class Var
|
||||
{
|
||||
public:
|
||||
Var(const std::string &name_, bool init = false, bool priv = false, Var *next = 0)
|
||||
: name(name_)
|
||||
Var(const std::string &name_, bool init_ = false, bool priv_ = false, bool mutable_ = false, Var *next_ = 0)
|
||||
: name(name_),
|
||||
init(init_),
|
||||
priv(priv_),
|
||||
isMutable(mutable_),
|
||||
next(next_)
|
||||
{
|
||||
this->init = init;
|
||||
this->priv = priv;
|
||||
this->next = next;
|
||||
}
|
||||
|
||||
/** @brief name of variable */
|
||||
|
@ -130,6 +131,9 @@ private:
|
|||
/** @brief is this variable declared in the private section? */
|
||||
bool priv;
|
||||
|
||||
/** @brief is this variable mutable? */
|
||||
bool isMutable;
|
||||
|
||||
/** @brief next Var item */
|
||||
Var *next;
|
||||
};
|
||||
|
|
|
@ -1215,14 +1215,14 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
|
|||
Token::createMutualLinks(tok->tokAt(2), tok->tokAt(3));
|
||||
}
|
||||
|
||||
// Remove "volatile", "mutable" and "inline"
|
||||
while (Token::Match(_tokens, "volatile|mutable|inline"))
|
||||
// Remove "volatile" and "inline"
|
||||
while (Token::Match(_tokens, "volatile|inline"))
|
||||
{
|
||||
_tokens->deleteThis();
|
||||
}
|
||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||
{
|
||||
while (Token::Match(tok->next(), "volatile|mutable|inline"))
|
||||
while (Token::Match(tok->next(), "volatile|inline"))
|
||||
{
|
||||
tok->deleteNext();
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ private:
|
|||
TEST_CASE(const9); // ticket #1515
|
||||
TEST_CASE(const10); // ticket #1522
|
||||
TEST_CASE(const11); // ticket #1529
|
||||
TEST_CASE(const12); // ticket #1552
|
||||
TEST_CASE(constoperator); // operator< can often be const
|
||||
TEST_CASE(constincdec); // increment/decrement => non-const
|
||||
TEST_CASE(constReturnReference);
|
||||
|
@ -2229,6 +2230,18 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void const12()
|
||||
{
|
||||
// ticket #1525
|
||||
checkConst("class A {\n"
|
||||
"public:\n"
|
||||
" int foo() { x = 0; }\n"
|
||||
"private:\n"
|
||||
" mutable int x;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) The function 'A::foo' can be const\n", errout.str());
|
||||
}
|
||||
|
||||
// increment/decrement => not const
|
||||
void constincdec()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue