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;
int classLevel = spaceInfo.size();
bool inTypeDef = false;
bool inEnumClass = false;
std::string removed;
std::string classPath;
for (size_t i = 1; i < spaceInfo.size(); ++i) {
@ -1121,6 +1122,7 @@ void Tokenizer::simplifyTypedef()
if (memberScope == 0)
inMemberFunc = false;
}
inEnumClass = false;
if (classLevel > 1 && tok2 == spaceInfo[classLevel - 1].bodyEnd2) {
--classLevel;
@ -1165,19 +1167,23 @@ void Tokenizer::simplifyTypedef()
// check for entering a new scope
else if (tok2->str() == "{") {
// check for entering a new namespace
if (isCPP() && tok2->strAt(-2) == "namespace") {
if (classLevel < spaceInfo.size() &&
spaceInfo[classLevel].isNamespace &&
spaceInfo[classLevel].className == tok2->previous()->str()) {
spaceInfo[classLevel].bodyEnd2 = tok2->link();
++classLevel;
pattern.clear();
for (int i = classLevel; i < spaceInfo.size(); ++i)
pattern += spaceInfo[i].className + " :: ";
if (isCPP()) {
if (tok2->strAt(-2) == "namespace") {
if (classLevel < spaceInfo.size() &&
spaceInfo[classLevel].isNamespace &&
spaceInfo[classLevel].className == tok2->previous()->str()) {
spaceInfo[classLevel].bodyEnd2 = tok2->link();
++classLevel;
pattern.clear();
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
@ -1303,6 +1309,8 @@ void Tokenizer::simplifyTypedef()
}
}
simplifyType = simplifyType && !inEnumClass;
if (simplifyType) {
mTypedefInfo.back().used = true;

View File

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

View File

@ -186,6 +186,7 @@ private:
TEST_CASE(simplifyTypedef137);
TEST_CASE(simplifyTypedef138);
TEST_CASE(simplifyTypedef139);
TEST_CASE(simplifyTypedef140); // #10798
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -3027,6 +3028,20 @@ private:
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() {
{
const char code[] = "typedef void (*my_func)();\n"