Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1533,7 +1533,7 @@ void Tokenizer::simplifyTypedef()
Token *tok3 = tok2->next();

// handle missing variable name
if (tok2->strAt(3) == ")" || tok2->strAt(3) == ",")
if (tok2->strAt(3) == ")" || tok2->strAt(3) == "," || tok2->strAt(3) == "(")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably have written a Token::Match here. That is shorter code and should be faster. But I don't have a strong opinion about it so will merge anyway..

tok2 = tok2->tokAt(2);
else
tok2 = tok2->tokAt(3);
Expand All @@ -1544,12 +1544,15 @@ void Tokenizer::simplifyTypedef()
tok2 = tok2->tokAt(2);

// skip over function parameters
if (tok2->strAt(1) == "(") {
tok2 = tok2->linkAt(1);
if (tok2->str() == "(" )
tok2 = tok2->link();

if (tok2->strAt(1) == "const")
tok2 = tok2->next();
}
if (tok2->strAt(1) == "(")
tok2 = tok2->linkAt(1);

// skip over const/noexcept
while (Token::Match(tok2->next(), "const|noexcept"))
tok2 = tok2->next();

tok2->insertToken(")");
tok2 = tok2->next();
Expand Down
58 changes: 58 additions & 0 deletions test/testsimplifytypedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ class TestSimplifyTypedef : public TestFixture {
TEST_CASE(simplifyTypedef126); // ticket #5953
TEST_CASE(simplifyTypedef127); // ticket #8878
TEST_CASE(simplifyTypedef128); // ticket #9053
TEST_CASE(simplifyTypedef129);

TEST_CASE(simplifyTypedefFunction1);
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
Expand Down Expand Up @@ -2544,6 +2545,63 @@ class TestSimplifyTypedef : public TestFixture {
ASSERT_EQUALS(exp, tok(code, false));
}

void simplifyTypedef129() {
{
const char code[] = "class c {\n"
" typedef char foo[4];\n"
" foo &f ;\n"
"};";

const char exp [] = "class c { char ( & f ) [ 4 ] ; } ;";
ASSERT_EQUALS(exp, tok(code, false));
}

{
const char code[] = "class c {\n"
" typedef char foo[4];\n"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is C++ code. At least g++ 8.3.0 does not like it when I test. Which compiler do you use?

123.cpp:3:9: error: expected ‘;’ at end of member declaration
   foo & f const;
         ^

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. My brain switched off when I tried to add some more test cases. /o
I'll clean this up.

" const foo &f;\n"
"};";

const char exp [] = "class c { const char ( & f ) [ 4 ] ; } ;";
ASSERT_EQUALS(exp, tok(code, false));
}

{
const char code[] = "class c {\n"
" typedef char foo[4];\n"
" foo _a;\n"
" constexpr const foo &c_str() const noexcept { return _a; }\n"
"};";

const char exp [] = "class c { char _a [ 4 ] ; const const char ( & c_str ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is the correct expansion.. however I admit I don't understand this simplification. I'll trust you on this.

However I guess that for instance isFunctionHead won't handle this code well.. and then function handling does not work. If you run Cppcheck like cppcheck --debug -v 2211.cpp on this code then we can see that the function c_str() is not printed out. I wonder... do you want to look into this further later? I would suggest you do that in a separate PR.

ASSERT_EQUALS(exp, tok(code, false));
}

{
const char code[] = "class c {\n"
" typedef char foo[4];\n"
" foo _a;\n"
" constexpr operator foo &() const noexcept { return _a; }\n"
"};";

const char actual [] = "class c { char _a [ 4 ] ; const operatorchar ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
const char exp [] = "class c { char _a [ 4 ] ; const operator char ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
TODO_ASSERT_EQUALS(exp, actual, tok(code, false));
}

{
const char code[] = "class c {\n"
" typedef char foo[4];\n"
" foo _a;\n"
" constexpr operator const foo &() const noexcept { return _a; }\n"
"};";

const char actual [] = "class c { char _a [ 4 ] ; const operatorconstchar ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
const char exp [] = "class c { char _a [ 4 ] ; const operator const char ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
TODO_ASSERT_EQUALS(exp, actual, tok(code, false));
}
}

void simplifyTypedefFunction1() {
{
const char code[] = "typedef void (*my_func)();\n"
Expand Down