Better handle const/noexcept methods (#2211)
* Better handle const/noexcept methods/conversion operator const or noexcept in a method / (conversion) operator definition were badly parsed, ending in a bad ast. This patch tries to make it better, at least making the ast less bad, so as to avoid errors in later checks. * Fix parsing of some operator It is still very broken, but at least, it does not fail. Here is the previous error: ``` TestSimplifyTypedef::simplifyTypedef129 terminate called after throwing an instance of 'InternalError' Program received signal SIGABRT, Aborted. __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 #1 0x00007ffff612a801 in __GI_abort () at abort.c:79 #2 0x00007ffff6b1d957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x00007ffff6b23ab6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #4 0x00007ffff6b23af1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x00007ffff6b23d24 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #6 0x0000555556366bf8 in Tokenizer::cppcheckError (this=0x7fffffffc2d0, tok=0x607000006760) at ../lib/tokenize.cpp:8721 #7 0x000055555636a4bb in Tokenizer::validate (this=0x7fffffffc2d0) at ../lib/tokenize.cpp:9154 #8 0x000055555633e3aa in Tokenizer::simplifyTokenList1 (this=0x7fffffffc2d0, FileName=0x603000002d50 "test.cpp") at ../lib/tokenize.cpp:4477 #9 0x00005555563223ca in Tokenizer::simplifyTokens1 (this=0x7fffffffc2d0, configuration="") at ../lib/tokenize.cpp:2286 #10 0x00005555563235c8 in Tokenizer::tokenize (this=0x7fffffffc2d0, code=..., FileName=0x555556fda9a0 "test.cpp", configuration="") at ../lib/tokenize.cpp:2345 #11 0x00005555569410ea in TestSimplifyTypedef::tok[abi:cxx11](char const*, bool, cppcheck::Platform::PlatformType, bool) (this=0x555557728580 <(anonymous namespace)::instance_TestSimplifyTypedef>, code=0x7fffffffcb70 "class c {\n typedef char foo[4];\n foo _a;\n constexpr operator foo &() const noexcept { return _a; }\n};", simplify=false, type=cppcheck::Platform::Native, debugwarnings=true) at ../test/testsimplifytypedef.cpp:192 #12 0x000055555697239e in TestSimplifyTypedef::simplifyTypedef129 (this=0x555557728580 <(anonymous namespace)::instance_TestSimplifyTypedef>) at ../test/testsimplifytypedef.cpp:2599 #13 0x000055555694092c in TestSimplifyTypedef::run (this=0x555557728580 <(anonymous namespace)::instance_TestSimplifyTypedef>) at ../test/testsimplifytypedef.cpp:167 #14 0x00005555569cab84 in TestFixture::run (this=0x555557728580 <(anonymous namespace)::instance_TestSimplifyTypedef>, str="simplifyTypedef129") at ../test/testsuite.cpp:306 #15 0x00005555569cb445 in TestFixture::runTests (args=...) at ../test/testsuite.cpp:329 #16 0x000055555687bdfb in main (argc=2, argv=0x7fffffffd988) at ../test/testrunner.cpp:44 ``` * Replace some ASSERT_EQUALS with TODO_ASSERT_EQUALS when the actual result is still wrong * Remove invalid code from simplifyTypedef129 * Properly skip parentheses
This commit is contained in:
parent
19cf636a4a
commit
5a08ac361a
|
@ -1533,7 +1533,7 @@ void Tokenizer::simplifyTypedef()
|
||||||
Token *tok3 = tok2->next();
|
Token *tok3 = tok2->next();
|
||||||
|
|
||||||
// handle missing variable name
|
// handle missing variable name
|
||||||
if (tok2->strAt(3) == ")" || tok2->strAt(3) == ",")
|
if (tok2->strAt(3) == ")" || tok2->strAt(3) == "," || tok2->strAt(3) == "(")
|
||||||
tok2 = tok2->tokAt(2);
|
tok2 = tok2->tokAt(2);
|
||||||
else
|
else
|
||||||
tok2 = tok2->tokAt(3);
|
tok2 = tok2->tokAt(3);
|
||||||
|
@ -1544,12 +1544,15 @@ void Tokenizer::simplifyTypedef()
|
||||||
tok2 = tok2->tokAt(2);
|
tok2 = tok2->tokAt(2);
|
||||||
|
|
||||||
// skip over function parameters
|
// skip over function parameters
|
||||||
if (tok2->strAt(1) == "(") {
|
if (tok2->str() == "(" )
|
||||||
|
tok2 = tok2->link();
|
||||||
|
|
||||||
|
if (tok2->strAt(1) == "(")
|
||||||
tok2 = tok2->linkAt(1);
|
tok2 = tok2->linkAt(1);
|
||||||
|
|
||||||
if (tok2->strAt(1) == "const")
|
// skip over const/noexcept
|
||||||
|
while (Token::Match(tok2->next(), "const|noexcept"))
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
}
|
|
||||||
|
|
||||||
tok2->insertToken(")");
|
tok2->insertToken(")");
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
|
|
|
@ -164,6 +164,7 @@ private:
|
||||||
TEST_CASE(simplifyTypedef126); // ticket #5953
|
TEST_CASE(simplifyTypedef126); // ticket #5953
|
||||||
TEST_CASE(simplifyTypedef127); // ticket #8878
|
TEST_CASE(simplifyTypedef127); // ticket #8878
|
||||||
TEST_CASE(simplifyTypedef128); // ticket #9053
|
TEST_CASE(simplifyTypedef128); // ticket #9053
|
||||||
|
TEST_CASE(simplifyTypedef129);
|
||||||
|
|
||||||
TEST_CASE(simplifyTypedefFunction1);
|
TEST_CASE(simplifyTypedefFunction1);
|
||||||
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
|
TEST_CASE(simplifyTypedefFunction2); // ticket #1685
|
||||||
|
@ -2544,6 +2545,63 @@ private:
|
||||||
ASSERT_EQUALS(exp, tok(code, false));
|
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"
|
||||||
|
" 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 ; } } ;";
|
||||||
|
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() {
|
void simplifyTypedefFunction1() {
|
||||||
{
|
{
|
||||||
const char code[] = "typedef void (*my_func)();\n"
|
const char code[] = "typedef void (*my_func)();\n"
|
||||||
|
|
Loading…
Reference in New Issue