Fix #10798 cppcheckError with enum class and typedefs (#3867)

* Fix #10798 cppcheckError with enum class and typedefs

* Format

* Format

* Leave enum class scope

* Remove comment
This commit is contained in:
chrchr-github 2022-03-02 07:46:15 +01:00 committed by GitHub
parent 43fb3dd047
commit 01de8256ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 11 deletions

View File

@ -1068,6 +1068,7 @@ void Tokenizer::simplifyTypedef()
bool globalScope = false; bool globalScope = false;
int classLevel = spaceInfo.size(); int classLevel = spaceInfo.size();
bool inTypeDef = false; bool inTypeDef = false;
bool inEnumClass = false;
std::string removed; std::string removed;
std::string classPath; std::string classPath;
for (size_t i = 1; i < spaceInfo.size(); ++i) { for (size_t i = 1; i < spaceInfo.size(); ++i) {
@ -1121,6 +1122,7 @@ void Tokenizer::simplifyTypedef()
if (memberScope == 0) if (memberScope == 0)
inMemberFunc = false; inMemberFunc = false;
} }
inEnumClass = false;
if (classLevel > 1 && tok2 == spaceInfo[classLevel - 1].bodyEnd2) { if (classLevel > 1 && tok2 == spaceInfo[classLevel - 1].bodyEnd2) {
--classLevel; --classLevel;
@ -1165,19 +1167,23 @@ void Tokenizer::simplifyTypedef()
// check for entering a new scope // check for entering a new scope
else if (tok2->str() == "{") { else if (tok2->str() == "{") {
// check for entering a new namespace // check for entering a new namespace
if (isCPP() && tok2->strAt(-2) == "namespace") { if (isCPP()) {
if (classLevel < spaceInfo.size() && if (tok2->strAt(-2) == "namespace") {
spaceInfo[classLevel].isNamespace && if (classLevel < spaceInfo.size() &&
spaceInfo[classLevel].className == tok2->previous()->str()) { spaceInfo[classLevel].isNamespace &&
spaceInfo[classLevel].bodyEnd2 = tok2->link(); spaceInfo[classLevel].className == tok2->previous()->str()) {
++classLevel; spaceInfo[classLevel].bodyEnd2 = tok2->link();
pattern.clear(); ++classLevel;
for (int i = classLevel; i < spaceInfo.size(); ++i) pattern.clear();
pattern += spaceInfo[i].className + " :: "; for (int i = classLevel; i < spaceInfo.size(); ++i)
pattern += spaceInfo[i].className + " :: ";
pattern += typeName->str(); pattern += typeName->str();
}
++scope;
} }
++scope; if (Token::Match(tok2->tokAt(-3), "enum class %name%"))
inEnumClass = true;
} }
// keep track of scopes within member function // keep track of scopes within member function
@ -1303,6 +1309,8 @@ void Tokenizer::simplifyTypedef()
} }
} }
simplifyType = simplifyType && !inEnumClass;
if (simplifyType) { if (simplifyType) {
mTypedefInfo.back().used = true; mTypedefInfo.back().used = true;

View File

@ -329,6 +329,7 @@ private:
TEST_CASE(simplifyKnownVariables60); // #6829 TEST_CASE(simplifyKnownVariables60); // #6829
TEST_CASE(simplifyKnownVariables61); // #7805 TEST_CASE(simplifyKnownVariables61); // #7805
TEST_CASE(simplifyKnownVariables62); // #5666 - p=&str[0] TEST_CASE(simplifyKnownVariables62); // #5666 - p=&str[0]
TEST_CASE(simplifyKnownVariables63); // #10798
TEST_CASE(simplifyKnownVariablesBailOutAssign1); TEST_CASE(simplifyKnownVariablesBailOutAssign1);
TEST_CASE(simplifyKnownVariablesBailOutAssign2); TEST_CASE(simplifyKnownVariablesBailOutAssign2);
TEST_CASE(simplifyKnownVariablesBailOutAssign3); // #4395 - nested assignments TEST_CASE(simplifyKnownVariablesBailOutAssign3); // #4395 - nested assignments
@ -6646,6 +6647,12 @@ private:
"}", /*simplify=*/ true)); "}", /*simplify=*/ true));
} }
void simplifyKnownVariables63() { // #10798
tokenizeAndStringify("typedef void (*a)();\n"
"enum class E { a };\n");
ASSERT_EQUALS("", errout.str()); // don't throw
}
void simplifyKnownVariablesBailOutAssign1() { void simplifyKnownVariablesBailOutAssign1() {
const char code[] = "int foo() {\n" const char code[] = "int foo() {\n"
" int i; i = 0;\n" " int i; i = 0;\n"

View File

@ -186,6 +186,7 @@ private:
TEST_CASE(simplifyTypedef137); TEST_CASE(simplifyTypedef137);
TEST_CASE(simplifyTypedef138); TEST_CASE(simplifyTypedef138);
TEST_CASE(simplifyTypedef139); TEST_CASE(simplifyTypedef139);
TEST_CASE(simplifyTypedef140); // #10798
TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685 TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -3027,6 +3028,20 @@ private:
tok(code)); tok(code));
} }
void simplifyTypedef140() { // #10798
{
const char code[] = "typedef void (*b)();\n"
"enum class E { a, b, c };\n";
ASSERT_EQUALS("enum class E { a , b , c } ;", tok(code));
}
{
const char code[] = "typedef int A;\n"
"enum class E { A };\n";
ASSERT_EQUALS("enum class E { A } ;", tok(code));
}
}
void simplifyTypedefFunction1() { void simplifyTypedefFunction1() {
{ {
const char code[] = "typedef void (*my_func)();\n" const char code[] = "typedef void (*my_func)();\n"