Fix #12026 (simplifyTypedef: not handled properly when typedef and enum constant has same name) (#5500)

This commit is contained in:
Daniel Marjamäki 2023-10-01 21:26:54 +02:00 committed by GitHub
parent 6773cdb34b
commit 6a8f787915
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 8 deletions

View File

@ -921,11 +921,7 @@ namespace {
}
}
bool canReplace(const Token* tok) {
if (mNameToken == tok)
return false;
if (!Token::Match(tok->previous(), "%name%|;|{|}|(|,|<") && !Token::Match(tok->previous(), "!!. %name% ("))
return false;
static int canReplaceStatic(const Token* tok) {
if (!Token::Match(tok, "%name% %name%|*|&|&&|;|(|)|,|::")) {
if (Token::Match(tok->previous(), "( %name% =") && Token::Match(tok->linkAt(-1), ") %name%|{") && !tok->tokAt(-2)->isKeyword())
return true;
@ -933,8 +929,19 @@ namespace {
return true;
if (Token::Match(tok->previous(), "new %name% ["))
return true;
if (Token::Match(tok->previous(), "< %name% >"))
if (Token::Match(tok->previous(), "< %name%") && tok->previous()->findClosingBracket())
return true;
if (Token::Match(tok->previous(), ", %name% >|>>")) {
for (const Token* prev = tok->previous(); prev; prev = prev->previous()) {
if (Token::Match(prev, "[;{}(]"))
break;
if (prev->str() == "<" && prev->findClosingBracket() == tok->next())
return true;
if (prev->str() == ")")
prev = prev->link();
}
return true;
}
if (Token::Match(tok->previous(), "public|protected|private"))
return true;
if (Token::Match(tok->previous(), ", %name% :")) {
@ -951,6 +958,19 @@ namespace {
}
return false;
}
return -1;
}
bool canReplace(const Token* tok) {
if (mNameToken == tok)
return false;
if (!Token::Match(tok->previous(), "%name%|;|{|}|(|,|<") && !Token::Match(tok->previous(), "!!. %name% ("))
return false;
{
const int res = canReplaceStatic(tok);
if (res == 0 || res == 1)
return res != 0;
}
if (Token::Match(tok->previous(), "%name%") && !tok->previous()->isKeyword())
return false;
if (Token::simpleMatch(tok->next(), "(") && Token::Match(tok->linkAt(1), ") %name%|{"))
@ -1843,7 +1863,7 @@ void Tokenizer::simplifyTypedefCpp()
} else if (Token::Match(tok2->tokAt(-2), "%type% *|&")) {
// Ticket #5868: Don't substitute variable names
} else if (tok2->previous()->str() != ".") {
simplifyType = true;
simplifyType = (TypedefSimplifier::canReplaceStatic(tok2) != 0);
}
}
}

View File

@ -812,7 +812,7 @@ private:
}
void garbageCode85() { // #6784
ASSERT_THROW(checkCode("{ } { } typedef void ( *VoidFunc() ) ( ) ; VoidFunc"), InternalError); // do not crash
checkCode("{ } { } typedef void ( *VoidFunc() ) ( ) ; VoidFunc"); // do not crash
}
void garbageCode86() { // #6785

View File

@ -49,6 +49,7 @@ private:
TEST_CASE(canreplace1);
TEST_CASE(canreplace2);
TEST_CASE(canreplace3);
TEST_CASE(canreplace4);
TEST_CASE(cconst);
TEST_CASE(cstruct1);
TEST_CASE(cstruct2);
@ -353,6 +354,14 @@ private:
ASSERT_EQUALS("struct S { const char * g ( ) const { return s . c_str ( ) ; } std :: string s ; } ;", simplifyTypedefC(code1));
}
void canreplace4() {
const char code1[] = "typedef std::vector<int> X;\n" // #12026
"struct S {\n"
" enum E { X };\n"
"};\n";
ASSERT_EQUALS("struct S { enum E { X } ; } ;", simplifyTypedef(code1));
}
void cconst() {
const char code1[] = "typedef void* HWND;\n"
"const HWND x;";