Skip to content

Commit 5524bb4

Browse files
Fix #11634 Crash in TypedefSimplifier (#4938)
* Fix #11634 Crash in TypedefSimplifier * Call function * Format
1 parent 1ac6c3e commit 5524bb4

3 files changed

Lines changed: 66 additions & 4 deletions

File tree

lib/tokenize.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,47 @@ void Tokenizer::simplifyUsingToTypedef()
577577
}
578578
}
579579

580+
void Tokenizer::simplifyTypedefLHS()
581+
{
582+
if (!list.front())
583+
return;
584+
585+
for (Token* tok = list.front()->next(); tok; tok = tok->next()) {
586+
if (tok->str() == "typedef") {
587+
bool doSimplify = !Token::Match(tok->previous(), ";|{|}|:|public:|private:|protected:");
588+
if (doSimplify && Token::simpleMatch(tok->previous(), ")") && Token::Match(tok->linkAt(-1)->previous(), "if|for|while"))
589+
doSimplify = false;
590+
bool haveStart = false;
591+
Token* start{};
592+
if (!doSimplify && Token::simpleMatch(tok->previous(), "}")) {
593+
start = tok->linkAt(-1)->previous();
594+
while (Token::Match(start, "%name%")) {
595+
if (Token::Match(start, "class|struct|union|enum")) {
596+
start = start->previous();
597+
doSimplify = true;
598+
haveStart = true;
599+
break;
600+
}
601+
start = start->previous();
602+
}
603+
}
604+
if (doSimplify) {
605+
if (!haveStart) {
606+
start = tok;
607+
while (start && !Token::Match(start, "[;{}]"))
608+
start = start->previous();
609+
}
610+
if (start)
611+
start = start->next();
612+
else
613+
start = list.front();
614+
start->insertTokenBefore(tok->str());
615+
tok->deleteThis();
616+
}
617+
}
618+
}
619+
}
620+
580621
namespace {
581622
class TypedefSimplifier {
582623
private:
@@ -5423,6 +5464,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
54235464

54245465
reportUnknownMacros();
54255466

5467+
simplifyTypedefLHS();
5468+
54265469
// typedef..
54275470
if (mTimerResults) {
54285471
Timer t("Tokenizer::tokenize::simplifyTypedef", mSettings->showtime, mTimerResults);

lib/tokenize.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ class CPPCHECKLIB Tokenizer {
268268
*/
269269
void simplifyTypedef();
270270
void simplifyTypedefCpp();
271+
/**
272+
* Move typedef token to the left og the expression
273+
*/
274+
void simplifyTypedefLHS();
271275

272276
/**
273277
*/

test/testsimplifytypedef.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class TestSimplifyTypedef : public TestFixture {
211211
TEST_CASE(simplifyTypedef142); // T() when T is a pointer type
212212
TEST_CASE(simplifyTypedef143); // #11506
213213
TEST_CASE(simplifyTypedef144); // #9353
214+
TEST_CASE(simplifyTypedef145); // #9353
214215

215216
TEST_CASE(simplifyTypedefFunction1);
216217
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
@@ -2022,10 +2023,7 @@ class TestSimplifyTypedef : public TestFixture {
20222023
}
20232024

20242025
void simplifyTypedef76() { // ticket #2453 segmentation fault
2025-
const char code[] = "void f1(typedef int x) {}";
2026-
const char expected[] = "void f1 ( typedef int x ) { }";
2027-
ASSERT_EQUALS(expected, tok(code, true, cppcheck::Platform::Type::Native, false));
2028-
ASSERT_EQUALS("", errout.str());
2026+
ASSERT_THROW(checkSimplifyTypedef("void f1(typedef int x) {}"), InternalError);
20292027
}
20302028

20312029
void simplifyTypedef77() { // ticket #2554
@@ -3254,6 +3252,23 @@ class TestSimplifyTypedef : public TestFixture {
32543252
ASSERT_EQUALS("struct X { } ; std :: vector < X > v ;", tok(code));
32553253
}
32563254

3255+
void simplifyTypedef145() { // #11634
3256+
const char* code{};
3257+
code = "int typedef i;\n"
3258+
"i main() {}\n";
3259+
ASSERT_EQUALS("int main ( ) { }", tok(code));
3260+
3261+
code = "struct {} typedef S;\n"
3262+
"void f() {\n"
3263+
" S();\n"
3264+
"}\n";
3265+
ASSERT_EQUALS("struct S { } ; void f ( ) { struct S ( ) ; }", tok(code));
3266+
3267+
code = "struct {} typedef S;\n" // don't crash
3268+
"S();\n";
3269+
ASSERT_EQUALS("struct S { } ; struct S ( ) ;", tok(code));
3270+
}
3271+
32573272
void simplifyTypedefFunction1() {
32583273
{
32593274
const char code[] = "typedef void (*my_func)();\n"

0 commit comments

Comments
 (0)