From 78b32955196b33e20d674d0ab07fff464586f775 Mon Sep 17 00:00:00 2001 From: chrchr Date: Wed, 22 Nov 2023 14:41:20 +0100 Subject: [PATCH 1/2] Fix #12218 syntaxError with typedef in namespace --- lib/tokenize.cpp | 2 ++ test/testsimplifytypedef.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 26255413810..46529a0a12f 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1945,6 +1945,8 @@ void Tokenizer::simplifyTypedefCpp() tok2 = tok2->next(); tok2->next()->insertToken("0"); } + if (Token::Match(tok2->tokAt(-1), "class|struct|union") && tok2->strAt(-1) == typeStart->str()) + tok2->deletePrevious(); tok2->str(typeStart->str()); // restore qualification if it was removed diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 89a38f394e9..d321026a384 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -212,6 +212,7 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedef146); TEST_CASE(simplifyTypedef147); TEST_CASE(simplifyTypedef148); + TEST_CASE(simplifyTypedef149); TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -3443,6 +3444,18 @@ class TestSimplifyTypedef : public TestFixture { ASSERT_EQUALS("int & r = i ;", tok(code)); } + void simplifyTypedef149() { // #12218 + const char* code{}; + code = "namespace N {\n" + " typedef struct S {} S;\n" + "}\n" + "void g(int);\n" + "void f() {\n" + " g(sizeof(struct N::S));\n" + "}\n"; + ASSERT_EQUALS("namespace N { struct S { } ; } void g ( int ) ; void f ( ) { g ( sizeof ( struct N :: S ) ) ; }", tok(code)); + } + void simplifyTypedefFunction1() { { const char code[] = "typedef void (*my_func)();\n" From c2298e0f789b185d99a2e0a5477c74f9e202286f Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Mon, 27 Nov 2023 13:00:20 +0100 Subject: [PATCH 2/2] Fix #12218: class and union --- lib/tokenize.cpp | 2 +- test/testsimplifytypedef.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 46529a0a12f..7bb3f3af635 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1950,7 +1950,7 @@ void Tokenizer::simplifyTypedefCpp() tok2->str(typeStart->str()); // restore qualification if it was removed - if (typeStart->str() == "struct" || structRemoved) { + if (Token::Match(typeStart, "class|struct|union") || structRemoved) { if (structRemoved) tok2 = tok2->previous(); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index d321026a384..8d3f0bb883c 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -3454,6 +3454,33 @@ class TestSimplifyTypedef : public TestFixture { " g(sizeof(struct N::S));\n" "}\n"; ASSERT_EQUALS("namespace N { struct S { } ; } void g ( int ) ; void f ( ) { g ( sizeof ( struct N :: S ) ) ; }", tok(code)); + + code = "namespace N {\n" + " typedef class C {} C;\n" + "}\n" + "void g(int);\n" + "void f() {\n" + " g(sizeof(class N::C));\n" + "}\n"; + ASSERT_EQUALS("namespace N { class C { } ; } void g ( int ) ; void f ( ) { g ( sizeof ( class N :: C ) ) ; }", tok(code)); + + code = "namespace N {\n" + " typedef union U {} U;\n" + "}\n" + "void g(int);\n" + "void f() {\n" + " g(sizeof(union N::U));\n" + "}\n"; + ASSERT_EQUALS("namespace N { union U { } ; } void g ( int ) ; void f ( ) { g ( sizeof ( union N :: U ) ) ; }", tok(code)); + + code = "namespace N {\n" + " typedef enum E {} E;\n" + "}\n" + "void g(int);\n" + "void f() {\n" + " g(sizeof(enum N::E));\n" + "}\n"; + ASSERT_EQUALS("namespace N { enum E { } ; } void g ( int ) ; void f ( ) { g ( sizeof ( enum N :: E ) ) ; }", tok(code)); } void simplifyTypedefFunction1() {