Raise syntax error for if-condition without parentheses according to #2518 #4171

This commit is contained in:
Frank Zingsheim 2013-02-05 21:13:57 +01:00
parent 4ac5648656
commit 5144307642
5 changed files with 34 additions and 27 deletions

View File

@ -1666,7 +1666,8 @@ bool Tokenizer::tokenize(std::istream &code,
}
}
simplifyAddBraces();
if (!simplifyAddBraces())
return false;
// Combine tokens..
for (Token *tok = list.front(); tok && tok->next(); tok = tok->next()) {
@ -4051,10 +4052,14 @@ void Tokenizer::removeRedundantSemicolons()
}
void Tokenizer::simplifyAddBraces()
bool Tokenizer::simplifyAddBraces()
{
for (Token *tok = list.front(); tok; tok = tok->next())
simplifyAddBracesToCommand(tok);
for (Token *tok = list.front(); tok; tok = tok->next()) {
Token const * tokRet=simplifyAddBracesToCommand(tok);
if (!tokRet)
return false;
}
return true;
}
Token *Tokenizer::simplifyAddBracesToCommand(Token *tok)
@ -4082,13 +4087,17 @@ Token *Tokenizer::simplifyAddBracesToCommand(Token *tok)
// before the "while"
if (tokEnd) {
tokEnd=tokEnd->next();
if (!tokEnd)
if (!tokEnd) {
// no while return input token
tokEnd=tok;
syntaxError(tok);
return NULL;
}
}
}
} else if (tok->str()=="if") {
tokEnd=simplifyAddBracesPair(tok,true);
if (!tokEnd)
return NULL;
Token * tokEndNext=tokEnd->next();
if (tokEndNext && tokEndNext->str()=="else")
tokEnd=simplifyAddBracesPair(tokEndNext,false);
@ -4108,22 +4117,14 @@ Token *Tokenizer::simplifyAddBracesPair(Token *tok, bool commandWithCondition)
}
if (tokCondition->str()=="(")
tokAfterCondition=tokCondition->link();
else if (tokCondition->type()==Token::eName) {
// Macro condition without braces, e.g "if FAILED(hr) ...
// see for example TestMemleakInFunction::switch4
tokAfterCondition=tokCondition;
tokAfterCondition=tokAfterCondition->next();
if (tokAfterCondition &&
tokAfterCondition->str()=="(")
tokAfterCondition=tokAfterCondition->link();
}
if (tokAfterCondition) {
if (tokAfterCondition->str()!=")") {
// Bad condition
return tok;
}
tokAfterCondition=tokAfterCondition->next();
else
tokAfterCondition=NULL;
if (!tokAfterCondition) {
// Bad condition
syntaxError(tok);
return NULL;
}
tokAfterCondition=tokAfterCondition->next();
}
if (!tokAfterCondition ||
((tokAfterCondition->type()==Token::eBracket ||

View File

@ -283,18 +283,23 @@ public:
void simplifyComma();
/** Add braces to an if-block, for-block, etc.
* @return true if no syntax errors
*/
void simplifyAddBraces();
bool simplifyAddBraces();
/** Add braces to an if-block, for-block, etc.
* for command starting at token including else-block
* @return last token of command (or input token in case of error or no braces have been added)
* @return last token of command
* or input token in case of an error where no braces are added
* or NULL when syntaxError is called
*/
Token * simplifyAddBracesToCommand(Token * tok);
/** Add pair of braces to an single if-block, else-block, for-block, etc.
* for command starting at token
* @return last token of command (or input token in case of error or no braces have been added)
* @return last token of command
* or input token in case of an error where no braces are added
* or NULL when syntaxError is called
*/
Token * simplifyAddBracesPair(Token *tok, bool commandWithCondition);

View File

@ -1353,6 +1353,7 @@ private:
}
void switch4() {
// See tickets #2518 #2555 #4171
check("void f() {\n"
" switch MAKEWORD(1)\n"
" {\n"
@ -1360,7 +1361,7 @@ private:
" return;\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (error) syntax error\n", errout.str());
}
void ret5() {

View File

@ -748,7 +748,7 @@ private:
}
void wrong_syntax_if_macro() {
// #2518
// #2518 #4171
const std::string code("void f() { if MACRO(); }");
tokenizeAndStringify(code.c_str(), false);
ASSERT_EQUALS("[test.cpp:1]: (error) syntax error\n", errout.str());

View File

@ -561,7 +561,7 @@ private:
"{\n"
" return if\n"
"}\n");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (error) syntax error\n", errout.str());
// Ticket #3873 (false positive)
checkUninitVar("MachineLoopRange *MachineLoopRanges::getLoopRange(const MachineLoop *Loop) {\n"