From 519882816c942b6855ec5f58ed83f4d7c3902980 Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 6 Apr 2023 16:32:48 +0200 Subject: [PATCH 1/3] Fix #11634 Crash in TypedefSimplifier --- lib/tokenize.cpp | 76 ++++++++++++++++++++++++++++++++++++ lib/tokenize.h | 4 ++ test/testsimplifytypedef.cpp | 23 +++++++++-- 3 files changed, 99 insertions(+), 4 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7bf490f0c31..80cf2adc4a2 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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,41 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) reportUnknownMacros(); + if (list.front()) { + for (Token* tok = list.front()->next(); tok; tok = tok->next()) { + if (tok->str() == "typedef") {//if for while + bool doSimplify = !Token::Match(tok->previous(), ";|{|}|:|public:|private:|protected:"); + 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(); + } + } + } + } + // typedef.. if (mTimerResults) { Timer t("Tokenizer::tokenize::simplifyTypedef", mSettings->showtime, mTimerResults); diff --git a/lib/tokenize.h b/lib/tokenize.h index cc761e06678..de05fdfd4b5 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -268,6 +268,10 @@ class CPPCHECKLIB Tokenizer { */ void simplifyTypedef(); void simplifyTypedefCpp(); + /** + * Move typedef token to the left og the expression + */ + void simplifyTypedefLHS(); /** */ diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 6a1109232ad..ad7164acd28 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -211,6 +211,7 @@ class TestSimplifyTypedef : public TestFixture { 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 @@ class TestSimplifyTypedef : public TestFixture { } 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 @@ class TestSimplifyTypedef : public TestFixture { 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" From c46ca044c4624d2c7863aee5fa0e4ea8a9922114 Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 6 Apr 2023 16:34:52 +0200 Subject: [PATCH 2/3] Call function --- lib/tokenize.cpp | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 80cf2adc4a2..881f00a3ce8 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -5464,40 +5464,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) reportUnknownMacros(); - if (list.front()) { - for (Token* tok = list.front()->next(); tok; tok = tok->next()) { - if (tok->str() == "typedef") {//if for while - bool doSimplify = !Token::Match(tok->previous(), ";|{|}|:|public:|private:|protected:"); - 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(); - } - } - } - } + simplifyTypedefLHS(); // typedef.. if (mTimerResults) { From 1fabfadd420b33ce04ed9a37b60295ad550403cc Mon Sep 17 00:00:00 2001 From: chrchr Date: Thu, 6 Apr 2023 16:53:32 +0200 Subject: [PATCH 3/3] Format --- lib/tokenize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 881f00a3ce8..a3967cf083d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -580,7 +580,7 @@ void Tokenizer::simplifyUsingToTypedef() void Tokenizer::simplifyTypedefLHS() { if (!list.front()) - return; + return; for (Token* tok = list.front()->next(); tok; tok = tok->next()) { if (tok->str() == "typedef") {