Fixed #1551 (false positive: The function 'A::vSet' can be const)

This commit is contained in:
Robert Reif 2010-04-01 16:59:35 +02:00 committed by Daniel Marjamäki
parent a8c9aa1f8d
commit 2c5fb55c3b
3 changed files with 22 additions and 7 deletions

View File

@ -1595,7 +1595,7 @@ void CheckClass::checkConst()
const Token *paramEnd = tok2; const Token *paramEnd = tok2;
// if nothing non-const was found. write error.. // if nothing non-const was found. write error..
if (checkConstFunc(varlist, paramEnd)) if (checkConstFunc(classname, varlist, paramEnd))
{ {
for (int i = nestInfo.size() - 2; i >= 0; i--) for (int i = nestInfo.size() - 2; i >= 0; i--)
classname = std::string(nestInfo[i].className + "::" + classname); classname = std::string(nestInfo[i].className + "::" + classname);
@ -1623,7 +1623,7 @@ void CheckClass::checkConst()
if (sameFunc(level, tok2, paramEnd)) if (sameFunc(level, tok2, paramEnd))
{ {
// if nothing non-const was found. write error.. // if nothing non-const was found. write error..
if (checkConstFunc(varlist, paramEnd)) if (checkConstFunc(classname, varlist, paramEnd))
{ {
for (int k = nestInfo.size() - 2; k >= 0; k--) for (int k = nestInfo.size() - 2; k >= 0; k--)
classname = std::string(nestInfo[k].className + "::" + classname); classname = std::string(nestInfo[k].className + "::" + classname);
@ -1836,7 +1836,7 @@ bool CheckClass::isMemberFunc(const Token *tok)
return false; return false;
} }
bool CheckClass::isMemberVar(const Var *varlist, const Token *tok) bool CheckClass::isMemberVar(const std::string &classname, const Var *varlist, const Token *tok)
{ {
while (tok->previous() && !Token::Match(tok->previous(), "}|{|;|public:|protected:|private:|return|:|?")) while (tok->previous() && !Token::Match(tok->previous(), "}|{|;|public:|protected:|private:|return|:|?"))
{ {
@ -1849,6 +1849,10 @@ bool CheckClass::isMemberVar(const Var *varlist, const Token *tok)
if (tok->str() == "this") if (tok->str() == "this")
return true; return true;
// ignore class namespace
if (tok->str() == classname && tok->next()->str() == "::")
tok = tok->tokAt(2);
for (const Var *var = varlist; var; var = var->next) for (const Var *var = varlist; var; var = var->next)
{ {
if (var->name == tok->str()) if (var->name == tok->str())
@ -1860,7 +1864,7 @@ bool CheckClass::isMemberVar(const Var *varlist, const Token *tok)
return false; return false;
} }
bool CheckClass::checkConstFunc(const Var *varlist, const Token *tok) bool CheckClass::checkConstFunc(const std::string &classname, const Var *varlist, const Token *tok)
{ {
// if the function doesn't have any assignment nor function call, // if the function doesn't have any assignment nor function call,
// it can be a const function.. // it can be a const function..
@ -1882,7 +1886,7 @@ bool CheckClass::checkConstFunc(const Var *varlist, const Token *tok)
(tok1->str().find("=") == 1 && (tok1->str().find("=") == 1 &&
tok1->str().find_first_of("<!>") == std::string::npos)) tok1->str().find_first_of("<!>") == std::string::npos))
{ {
if (isMemberVar(varlist, tok1->previous())) if (isMemberVar(classname, varlist, tok1->previous()))
{ {
isconst = false; isconst = false;
break; break;

View File

@ -165,8 +165,8 @@ private:
bool sameFunc(int nest, const Token *firstEnd, const Token *secondEnd); bool sameFunc(int nest, const Token *firstEnd, const Token *secondEnd);
bool isMemberFunc(const Token *tok); bool isMemberFunc(const Token *tok);
bool isMemberVar(const Var *varlist, const Token *tok); bool isMemberVar(const std::string &classname, const Var *varlist, const Token *tok);
bool checkConstFunc(const Var *varlist, const Token *tok); bool checkConstFunc(const std::string &classname, const Var *varlist, const Token *tok);
// Reporting errors.. // Reporting errors..
void noConstructorError(const Token *tok, const std::string &classname, bool isStruct); void noConstructorError(const Token *tok, const std::string &classname, bool isStruct);

View File

@ -107,6 +107,7 @@ private:
TEST_CASE(const13); // ticket #1519 TEST_CASE(const13); // ticket #1519
TEST_CASE(const14); TEST_CASE(const14);
TEST_CASE(const15); TEST_CASE(const15);
TEST_CASE(const16); // ticket #1551
TEST_CASE(constoperator); // operator< can often be const TEST_CASE(constoperator); // operator< can often be const
TEST_CASE(constincdec); // increment/decrement => non-const TEST_CASE(constincdec); // increment/decrement => non-const
TEST_CASE(constReturnReference); TEST_CASE(constReturnReference);
@ -2777,6 +2778,16 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void const16()
{
// ticket #1551
checkConst("class Fred {\n"
" int a;\n"
" void set(int i) { Fred::a = i; }\n"
"};\n");
ASSERT_EQUALS("", errout.str());
}
// increment/decrement => not const // increment/decrement => not const
void constincdec() void constincdec()
{ {