Fixed #3314 (cppcheck incorrectly reporting Syntax error.)
This commit is contained in:
parent
0dad8b64e8
commit
418c2e51a0
|
@ -619,13 +619,34 @@ void Tokenizer::simplifyTypedef()
|
|||
Token *namespaceEnd = nullptr;
|
||||
|
||||
// check for invalid input
|
||||
if (!tok->next()) {
|
||||
if (!tokOffset) {
|
||||
syntaxError(tok);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tok->next()->str() == "::" || Token::Match(tok->next(), "%type%")) {
|
||||
typeStart = tok->next();
|
||||
if (tokOffset->str() == "::") {
|
||||
typeStart = tokOffset;
|
||||
tokOffset = tokOffset->next();
|
||||
|
||||
while (Token::Match(tokOffset, "%type% ::"))
|
||||
tokOffset = tokOffset->tokAt(2);
|
||||
|
||||
typeEnd = tokOffset;
|
||||
|
||||
if (Token::Match(tokOffset, "%type%"))
|
||||
tokOffset = tokOffset->next();
|
||||
} else if (Token::Match(tokOffset, "%type% ::")) {
|
||||
typeStart = tokOffset;
|
||||
|
||||
while (Token::Match(tokOffset, "%type% ::"))
|
||||
tokOffset = tokOffset->tokAt(2);
|
||||
|
||||
typeEnd = tokOffset;
|
||||
|
||||
if (Token::Match(tokOffset, "%type%"))
|
||||
tokOffset = tokOffset->next();
|
||||
} else if (Token::Match(tokOffset, "%type%")) {
|
||||
typeStart = tokOffset;
|
||||
|
||||
while (Token::Match(tokOffset, "const|signed|unsigned|struct|enum %type%") ||
|
||||
(tokOffset->next() && tokOffset->next()->isStandardType()))
|
||||
|
@ -738,18 +759,6 @@ void Tokenizer::simplifyTypedef()
|
|||
continue;
|
||||
}
|
||||
|
||||
// unhandled function pointer, skip it and continue
|
||||
// TODO: handle such typedefs. See ticket #3314
|
||||
else if (Token::Match(tokOffset, "( %type% ::") &&
|
||||
Token::Match(tokOffset->link()->tokAt(-3), ":: * %var% ) (")) {
|
||||
unsupportedTypedef(typeDef);
|
||||
tok = deleteInvalidTypedef(typeDef);
|
||||
if (tok == list.front())
|
||||
//now the next token to process is 'tok', not 'tok->next()';
|
||||
goback = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// function pointer
|
||||
else if (Token::Match(tokOffset, "( * %var% ) (")) {
|
||||
// name token wasn't a name, it was part of the type
|
||||
|
|
|
@ -117,13 +117,6 @@ private:
|
|||
const char code[] ="enum ABC { A,B, typedef enum { C } };";
|
||||
ASSERT_THROW(checkCode(code), InternalError);
|
||||
}
|
||||
|
||||
{
|
||||
// #3314 - don't report syntax error.
|
||||
const char code[] ="struct A { typedef B::C (A::*f)(); };";
|
||||
checkCode(code);
|
||||
ASSERT_EQUALS("[test.cpp:1]: (debug) Failed to parse 'typedef B :: C ( A :: * f ) ( ) ;'. The checking continues anyway.\n", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
void wrong_syntax2() { // #3504
|
||||
|
|
|
@ -154,6 +154,7 @@ private:
|
|||
TEST_CASE(simplifyTypedefFunction6);
|
||||
TEST_CASE(simplifyTypedefFunction7);
|
||||
TEST_CASE(simplifyTypedefFunction8);
|
||||
TEST_CASE(simplifyTypedefFunction9);
|
||||
|
||||
TEST_CASE(simplifyTypedefShadow); // #4445 - shadow variable
|
||||
}
|
||||
|
@ -3033,6 +3034,92 @@ private:
|
|||
TODO_ASSERT_EQUALS("", "[test.cpp:2]: (debug) Function::addArguments found argument 'int' with varid 0.\n", errout.str()); // make sure that there is no internal error
|
||||
}
|
||||
|
||||
void simplifyTypedefFunction9() {
|
||||
{
|
||||
const char code[] = "typedef ::C (::C::* func1)();\n"
|
||||
"typedef ::C (::C::* func2)() const;\n"
|
||||
"typedef ::C (::C::* func3)() volatile;\n"
|
||||
"typedef ::C (::C::* func4)() const volatile;\n"
|
||||
"func1 f1;\n"
|
||||
"func2 f2;\n"
|
||||
"func3 f3;\n"
|
||||
"func4 f4;";
|
||||
|
||||
// The expected result..
|
||||
const std::string expected(":: C ( :: C :: * f1 ) ( ) ; "
|
||||
":: C ( :: C :: * f2 ) ( ) const ; "
|
||||
":: C ( :: C :: * f3 ) ( ) ; "
|
||||
":: C ( :: C :: * f4 ) ( ) const ;");
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
|
||||
checkSimplifyTypedef(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "typedef B::C (B::C::* func1)();\n"
|
||||
"typedef B::C (B::C::* func2)() const;\n"
|
||||
"typedef B::C (B::C::* func3)() volatile;\n"
|
||||
"typedef B::C (B::C::* func4)() const volatile;\n"
|
||||
"func1 f1;\n"
|
||||
"func2 f2;\n"
|
||||
"func3 f3;\n"
|
||||
"func4 f4;";
|
||||
|
||||
// The expected result..
|
||||
const std::string expected("B :: C * f1 ; "
|
||||
"B :: C ( B :: C :: * f2 ) ( ) const ; "
|
||||
"B :: C * f3 ; "
|
||||
"B :: C ( B :: C :: * f4 ) ( ) const ;");
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
|
||||
checkSimplifyTypedef(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "typedef ::B::C (::B::C::* func1)();\n"
|
||||
"typedef ::B::C (::B::C::* func2)() const;\n"
|
||||
"typedef ::B::C (::B::C::* func3)() volatile;\n"
|
||||
"typedef ::B::C (::B::C::* func4)() const volatile;\n"
|
||||
"func1 f1;\n"
|
||||
"func2 f2;\n"
|
||||
"func3 f3;\n"
|
||||
"func4 f4;";
|
||||
|
||||
// The expected result..
|
||||
const std::string expected(":: B :: C ( :: B :: C :: * f1 ) ( ) ; "
|
||||
":: B :: C ( :: B :: C :: * f2 ) ( ) const ; "
|
||||
":: B :: C ( :: B :: C :: * f3 ) ( ) ; "
|
||||
":: B :: C ( :: B :: C :: * f4 ) ( ) const ;");
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
|
||||
checkSimplifyTypedef(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "typedef A::B::C (A::B::C::* func1)();\n"
|
||||
"typedef A::B::C (A::B::C::* func2)() const;\n"
|
||||
"typedef A::B::C (A::B::C::* func3)() volatile;\n"
|
||||
"typedef A::B::C (A::B::C::* func4)() const volatile;\n"
|
||||
"func1 f1;\n"
|
||||
"func2 f2;\n"
|
||||
"func3 f3;\n"
|
||||
"func4 f4;";
|
||||
|
||||
// The expected result..
|
||||
const std::string expected("A :: B :: C * f1 ; "
|
||||
"A :: B :: C ( A :: B :: C :: * f2 ) ( ) const ; "
|
||||
"A :: B :: C * f3 ; "
|
||||
"A :: B :: C ( A :: B :: C :: * f4 ) ( ) const ;");
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
|
||||
checkSimplifyTypedef(code);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
void simplifyTypedefShadow() { // shadow variable (#4445)
|
||||
const char code[] = "typedef struct { int x; } xyz;;\n"
|
||||
"void f(){\n"
|
||||
|
|
Loading…
Reference in New Issue