fix extra qualification check for same class name in different namespaces
This commit is contained in:
parent
be57aa5ad5
commit
eaf836b323
|
@ -9788,40 +9788,52 @@ void Tokenizer::simplifyOperatorName()
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove unnecessary member qualification..
|
// remove unnecessary member qualification..
|
||||||
struct ClassInfo
|
|
||||||
{
|
|
||||||
std::string className;
|
|
||||||
Token *end;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Tokenizer::removeUnnecessaryQualification()
|
void Tokenizer::removeUnnecessaryQualification()
|
||||||
{
|
{
|
||||||
std::stack<ClassInfo> classInfo;
|
std::vector<Space> classInfo;
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
if (Token::Match(tok, "class|struct %type% :|{") &&
|
if (Token::Match(tok, "class|struct|namespace %type% :|{") &&
|
||||||
(!tok->previous() || (tok->previous() && tok->previous()->str() != "enum")))
|
(!tok->previous() || (tok->previous() && tok->previous()->str() != "enum")))
|
||||||
{
|
{
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
ClassInfo info;
|
Space info;
|
||||||
|
info.isNamespace = tok->str() == "namespace";
|
||||||
info.className = tok->str();
|
info.className = tok->str();
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
while (tok && tok->str() != "{")
|
while (tok && tok->str() != "{")
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
if (!tok)
|
if (!tok)
|
||||||
return;
|
return;
|
||||||
info.end = tok->link();
|
info.classEnd = tok->link();
|
||||||
classInfo.push(info);
|
classInfo.push_back(info);
|
||||||
}
|
}
|
||||||
else if (!classInfo.empty())
|
else if (!classInfo.empty())
|
||||||
{
|
{
|
||||||
if (tok == classInfo.top().end)
|
if (tok == classInfo.back().classEnd)
|
||||||
classInfo.pop();
|
classInfo.pop_back();
|
||||||
else if (tok->str() == classInfo.top().className &&
|
else if (tok->str() == classInfo.back().className &&
|
||||||
Token::Match(tok, "%type% :: %type% (") &&
|
Token::Match(tok, "%type% :: %type% (") &&
|
||||||
Token::Match(tok->tokAt(3)->link(), ") const| {|;") &&
|
Token::Match(tok->tokAt(3)->link(), ") const| {|;") &&
|
||||||
tok->previous()->str() != ":")
|
tok->previous()->str() != ":")
|
||||||
{
|
{
|
||||||
|
std::string qualification = tok->str() + "::";
|
||||||
|
|
||||||
|
// check for extra qualification
|
||||||
|
/** @todo this should be made more generic to handle more levels */
|
||||||
|
if (Token::Match(tok->tokAt(-2), "%type% ::"))
|
||||||
|
{
|
||||||
|
if (classInfo.size() >= 2)
|
||||||
|
{
|
||||||
|
if (classInfo.at(classInfo.size() - 2).className != tok->strAt(-2))
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
qualification = tok->strAt(-2) + "::" + qualification;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
std::list<ErrorLogger::ErrorMessage::FileLocation> locationList;
|
||||||
ErrorLogger::ErrorMessage::FileLocation loc;
|
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||||
loc.line = tok->linenr();
|
loc.line = tok->linenr();
|
||||||
|
@ -9830,7 +9842,7 @@ void Tokenizer::removeUnnecessaryQualification()
|
||||||
|
|
||||||
const ErrorLogger::ErrorMessage errmsg(locationList,
|
const ErrorLogger::ErrorMessage errmsg(locationList,
|
||||||
Severity::portability,
|
Severity::portability,
|
||||||
"Extra qualification \'" + tok->str() + "::\' unnecessary and considered an error by many compilers.",
|
"Extra qualification \'" + qualification + "\' unnecessary and considered an error by many compilers.",
|
||||||
"portability",
|
"portability",
|
||||||
false);
|
false);
|
||||||
|
|
||||||
|
|
|
@ -350,6 +350,9 @@ private:
|
||||||
|
|
||||||
TEST_CASE(removeUnnecessaryQualification1);
|
TEST_CASE(removeUnnecessaryQualification1);
|
||||||
TEST_CASE(removeUnnecessaryQualification2);
|
TEST_CASE(removeUnnecessaryQualification2);
|
||||||
|
TEST_CASE(removeUnnecessaryQualification3);
|
||||||
|
TEST_CASE(removeUnnecessaryQualification4);
|
||||||
|
TEST_CASE(removeUnnecessaryQualification5);
|
||||||
|
|
||||||
TEST_CASE(simplifyIfNotNull);
|
TEST_CASE(simplifyIfNotNull);
|
||||||
TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault
|
TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault
|
||||||
|
@ -6970,6 +6973,64 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeUnnecessaryQualification3()
|
||||||
|
{
|
||||||
|
const char code[] = "namespace one {\n"
|
||||||
|
" class c {\n"
|
||||||
|
" public:\n"
|
||||||
|
" void function() {}\n"
|
||||||
|
" };\n"
|
||||||
|
"}\n"
|
||||||
|
"namespace two {\n"
|
||||||
|
" class c : public one::c {\n"
|
||||||
|
" public:\n"
|
||||||
|
" void function() {\n"
|
||||||
|
" one::c::function();\n"
|
||||||
|
" }\n"
|
||||||
|
" };\n"
|
||||||
|
"}\n";
|
||||||
|
tok(code, false);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeUnnecessaryQualification4()
|
||||||
|
{
|
||||||
|
const char code[] = "namespace one {\n"
|
||||||
|
" class c {\n"
|
||||||
|
" public:\n"
|
||||||
|
" void function() {}\n"
|
||||||
|
" };\n"
|
||||||
|
"}\n"
|
||||||
|
"class c : public one::c {\n"
|
||||||
|
"public:\n"
|
||||||
|
" void function() {\n"
|
||||||
|
" one::c::function();\n"
|
||||||
|
" }\n"
|
||||||
|
"};\n";
|
||||||
|
tok(code, false);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeUnnecessaryQualification5()
|
||||||
|
{
|
||||||
|
const char code[] = "namespace one {\n"
|
||||||
|
" class c {\n"
|
||||||
|
" public:\n"
|
||||||
|
" void function() {}\n"
|
||||||
|
" };\n"
|
||||||
|
"}\n"
|
||||||
|
"namespace two {\n"
|
||||||
|
" class c : public one::c {\n"
|
||||||
|
" public:\n"
|
||||||
|
" void function() {\n"
|
||||||
|
" two::c::function();\n"
|
||||||
|
" }\n"
|
||||||
|
" };\n"
|
||||||
|
"}\n";
|
||||||
|
tok(code, false);
|
||||||
|
ASSERT_EQUALS("[test.cpp:11]: (portability) Extra qualification 'two::c::' unnecessary and considered an error by many compilers.\n", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void simplifyIfNotNull()
|
void simplifyIfNotNull()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue