Fix #11634 Crash in TypedefSimplifier (#4938)

* Fix #11634 Crash in TypedefSimplifier

* Call function

* Format
This commit is contained in:
chrchr-github 2023-04-07 11:09:13 +02:00 committed by GitHub
parent 1ac6c3e2ea
commit 5524bb4e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 4 deletions

View File

@ -577,6 +577,47 @@ void Tokenizer::simplifyUsingToTypedef()
}
}
void Tokenizer::simplifyTypedefLHS()
{
if (!list.front())
return;
for (Token* tok = list.front()->next(); tok; tok = tok->next()) {
if (tok->str() == "typedef") {
bool doSimplify = !Token::Match(tok->previous(), ";|{|}|:|public:|private:|protected:");
if (doSimplify && Token::simpleMatch(tok->previous(), ")") && Token::Match(tok->linkAt(-1)->previous(), "if|for|while"))
doSimplify = false;
bool haveStart = false;
Token* start{};
if (!doSimplify && Token::simpleMatch(tok->previous(), "}")) {
start = tok->linkAt(-1)->previous();
while (Token::Match(start, "%name%")) {
if (Token::Match(start, "class|struct|union|enum")) {
start = start->previous();
doSimplify = true;
haveStart = true;
break;
}
start = start->previous();
}
}
if (doSimplify) {
if (!haveStart) {
start = tok;
while (start && !Token::Match(start, "[;{}]"))
start = start->previous();
}
if (start)
start = start->next();
else
start = list.front();
start->insertTokenBefore(tok->str());
tok->deleteThis();
}
}
}
}
namespace {
class TypedefSimplifier {
private:
@ -5423,6 +5464,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
reportUnknownMacros();
simplifyTypedefLHS();
// typedef..
if (mTimerResults) {
Timer t("Tokenizer::tokenize::simplifyTypedef", mSettings->showtime, mTimerResults);

View File

@ -268,6 +268,10 @@ public:
*/
void simplifyTypedef();
void simplifyTypedefCpp();
/**
* Move typedef token to the left og the expression
*/
void simplifyTypedefLHS();
/**
*/

View File

@ -211,6 +211,7 @@ private:
TEST_CASE(simplifyTypedef142); // T() when T is a pointer type
TEST_CASE(simplifyTypedef143); // #11506
TEST_CASE(simplifyTypedef144); // #9353
TEST_CASE(simplifyTypedef145); // #9353
TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@ -2022,10 +2023,7 @@ private:
}
void simplifyTypedef76() { // ticket #2453 segmentation fault
const char code[] = "void f1(typedef int x) {}";
const char expected[] = "void f1 ( typedef int x ) { }";
ASSERT_EQUALS(expected, tok(code, true, cppcheck::Platform::Type::Native, false));
ASSERT_EQUALS("", errout.str());
ASSERT_THROW(checkSimplifyTypedef("void f1(typedef int x) {}"), InternalError);
}
void simplifyTypedef77() { // ticket #2554
@ -3254,6 +3252,23 @@ private:
ASSERT_EQUALS("struct X { } ; std :: vector < X > v ;", tok(code));
}
void simplifyTypedef145() { // #11634
const char* code{};
code = "int typedef i;\n"
"i main() {}\n";
ASSERT_EQUALS("int main ( ) { }", tok(code));
code = "struct {} typedef S;\n"
"void f() {\n"
" S();\n"
"}\n";
ASSERT_EQUALS("struct S { } ; void f ( ) { struct S ( ) ; }", tok(code));
code = "struct {} typedef S;\n" // don't crash
"S();\n";
ASSERT_EQUALS("struct S { } ; struct S ( ) ;", tok(code));
}
void simplifyTypedefFunction1() {
{
const char code[] = "typedef void (*my_func)();\n"