fix #8284: False positive: "Label 'class' is not used." for anonymous… (#1011)

* fix #8284: False positive: "Label 'class' is not used." for anonymous C++ class

Add support for annonymous derived structures and classes.

* Fix travis build (use findsimplematch).

* Fix bug in simplifyLabelsCaseDefault which was inserting ; in wrong place.
This commit is contained in:
IOBYTE 2017-12-05 10:50:04 -05:00 committed by amai2012
parent 0d4744c317
commit 026d8f6859
2 changed files with 21 additions and 2 deletions

View File

@ -2178,6 +2178,7 @@ const Token * Tokenizer::startOfExecutableScope(const Token * tok)
void Tokenizer::simplifyLabelsCaseDefault() void Tokenizer::simplifyLabelsCaseDefault()
{ {
const bool cpp = isCPP();
bool executablescope = false; bool executablescope = false;
unsigned int indentLevel = 0; unsigned int indentLevel = 0;
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
@ -2233,8 +2234,10 @@ void Tokenizer::simplifyLabelsCaseDefault()
syntaxError(tok); syntaxError(tok);
} }
} else if (Token::Match(tok, "[;{}] %name% : !!;")) { } else if (Token::Match(tok, "[;{}] %name% : !!;")) {
tok = tok->tokAt(2); if (!cpp || !Token::Match(tok->next(), "class|struct")) {
tok->insertToken(";"); tok = tok->tokAt(2);
tok->insertToken(";");
}
} }
} }
} }
@ -8506,6 +8509,8 @@ void Tokenizer::simplifyFuncInWhile()
void Tokenizer::simplifyStructDecl() void Tokenizer::simplifyStructDecl()
{ {
const bool cpp = isCPP();
// A counter that is used when giving unique names for anonymous structs. // A counter that is used when giving unique names for anonymous structs.
unsigned int count = 0; unsigned int count = 0;
@ -8523,6 +8528,13 @@ void Tokenizer::simplifyStructDecl()
tok->insertToken("Anonymous" + MathLib::toString(count++)); tok->insertToken("Anonymous" + MathLib::toString(count++));
} }
} }
// check for derived anonymous class/struct
else if (cpp && Token::Match(tok, "class|struct :")) {
const Token *tok1 = Token::findsimplematch(tok, "{");
if (tok1 && Token::Match(tok1->link(), "} *|&| %type% ,|;|[|(|{")) {
tok->insertToken("Anonymous" + MathLib::toString(count++));
}
}
// check for anonymous enum // check for anonymous enum
else if ((Token::simpleMatch(tok, "enum {") && Token::Match(tok->next()->link(), "} %type%| ,|;|[|(|{")) || else if ((Token::simpleMatch(tok, "enum {") && Token::Match(tok->next()->link(), "} %type%| ,|;|[|(|{")) ||
(Token::Match(tok, "enum : %type% {") && Token::Match(tok->linkAt(3), "} %type%| ,|;|[|(|{"))) { (Token::Match(tok, "enum : %type% {") && Token::Match(tok->linkAt(3), "} %type%| ,|;|[|(|{"))) {

View File

@ -3067,6 +3067,13 @@ private:
const char expected[] = "void f ( ) { int A ; A = 1 ; int B ; B = 2 ; int C ; C = 3 ; int D ; int E ; E = 5 ; int F ; F = 6 ; }"; const char expected[] = "void f ( ) { int A ; A = 1 ; int B ; B = 2 ; int C ; C = 3 ; int D ; int E ; E = 5 ; int F ; F = 6 ; }";
ASSERT_EQUALS(expected, tok(code, false)); ASSERT_EQUALS(expected, tok(code, false));
} }
// ticket #8284
{
const char code[] = "void f() { class : foo<int> { } abc; }";
const char expected[] = "void f ( ) { class Anonymous0 : foo < int > { } ; Anonymous0 abc ; }";
ASSERT_EQUALS(expected, tok(code, false));
}
} }
void simplifyStructDecl2() { // ticket #2479 (segmentation fault) void simplifyStructDecl2() { // ticket #2479 (segmentation fault)