Fixed: Tokenizer::simplifyLabelCaseDefault was careless with '?:' operator near 'case' adding the semicolon after the ternary colon.

This commit is contained in:
Edoardo Prezioso 2012-10-12 20:51:13 +02:00
parent e1e154721a
commit d4a3c1617a
2 changed files with 40 additions and 0 deletions

View File

@ -2353,6 +2353,29 @@ void Tokenizer::arraySize()
} }
} }
static Token *skipTernaryOp(Token *);
static Token *skipTernaryOp(Token *tok)
{
if (!tok || tok->str() != "?")
return tok;
unsigned int colonlevel = 1;
while (NULL != (tok = tok->next())) {
if (tok->str() == "?") {
++colonlevel;
} else if (tok->str() == ":") {
--colonlevel;
if (colonlevel == 0) {
tok = tok->next();
break;
}
}
if (Token::Match(tok->next(), "[{};]"))
break;
}
return tok;
}
/** simplify labels and case|default in the code: add a ";" if not already in.*/ /** simplify labels and case|default in the code: add a ";" if not already in.*/
bool Tokenizer::simplifyLabelsCaseDefault() bool Tokenizer::simplifyLabelsCaseDefault()
@ -2389,6 +2412,8 @@ bool Tokenizer::simplifyLabelsCaseDefault()
while (NULL != (tok = tok->next())) { while (NULL != (tok = tok->next())) {
if (tok->str() == "(" || tok->str() == "[") { if (tok->str() == "(" || tok->str() == "[") {
tok = tok->link(); tok = tok->link();
} else if (tok->str() == "?") {
tok = skipTernaryOp(tok);
} }
if (Token::Match(tok->next(),"[:{};]")) if (Token::Match(tok->next(),"[:{};]"))
break; break;

View File

@ -732,6 +732,12 @@ private:
tokenizeAndStringify("void f() {switch (n) { case 0:; break;}}"); tokenizeAndStringify("void f() {switch (n) { case 0:; break;}}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
tokenizeAndStringify("void f() {switch (n) { case 0?1:2 : z(); break;}}");
ASSERT_EQUALS("", errout.str());
tokenizeAndStringify("void f() {switch (n) { case 0?(1?3:4):2 : z(); break;}}");
ASSERT_EQUALS("", errout.str());
//'b' can be or a macro or an undefined enum //'b' can be or a macro or an undefined enum
tokenizeAndStringify("void f() {switch (n) { case b: z(); break;}}"); tokenizeAndStringify("void f() {switch (n) { case b: z(); break;}}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
@ -764,6 +770,15 @@ private:
tokenizeAndStringify("void f() {switch (n) { case {}: z(); break;}}"); tokenizeAndStringify("void f() {switch (n) { case {}: z(); break;}}");
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());
tokenizeAndStringify("void f() {switch (n) { case 0?{1}:{2} : z(); break;}}");
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());
tokenizeAndStringify("void f() {switch (n) { case 0?1;:{2} : z(); break;}}");
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());
tokenizeAndStringify("void f() {switch (n) { case 0?(1?{3:4}):2 : z(); break;}}");
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());
//ticket #4234 //ticket #4234
tokenizeAndStringify("( ) { switch break ; { switch ( x ) { case } y break ; : } }"); tokenizeAndStringify("( ) { switch break ; { switch ( x ) { case } y break ; : } }");
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str()); ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());