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.. // Combine tokens..
for (Token *tok = list.front(); tok && tok->next(); tok = tok->next()) { 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()) for (Token *tok = list.front(); tok; tok = tok->next()) {
simplifyAddBracesToCommand(tok); Token const * tokRet=simplifyAddBracesToCommand(tok);
if (!tokRet)
return false;
}
return true;
} }
Token *Tokenizer::simplifyAddBracesToCommand(Token *tok) Token *Tokenizer::simplifyAddBracesToCommand(Token *tok)
@ -4082,13 +4087,17 @@ Token *Tokenizer::simplifyAddBracesToCommand(Token *tok)
// before the "while" // before the "while"
if (tokEnd) { if (tokEnd) {
tokEnd=tokEnd->next(); tokEnd=tokEnd->next();
if (!tokEnd) if (!tokEnd) {
// no while return input token // no while return input token
tokEnd=tok; syntaxError(tok);
return NULL;
}
} }
} }
} else if (tok->str()=="if") { } else if (tok->str()=="if") {
tokEnd=simplifyAddBracesPair(tok,true); tokEnd=simplifyAddBracesPair(tok,true);
if (!tokEnd)
return NULL;
Token * tokEndNext=tokEnd->next(); Token * tokEndNext=tokEnd->next();
if (tokEndNext && tokEndNext->str()=="else") if (tokEndNext && tokEndNext->str()=="else")
tokEnd=simplifyAddBracesPair(tokEndNext,false); tokEnd=simplifyAddBracesPair(tokEndNext,false);
@ -4108,23 +4117,15 @@ Token *Tokenizer::simplifyAddBracesPair(Token *tok, bool commandWithCondition)
} }
if (tokCondition->str()=="(") if (tokCondition->str()=="(")
tokAfterCondition=tokCondition->link(); tokAfterCondition=tokCondition->link();
else if (tokCondition->type()==Token::eName) { else
// Macro condition without braces, e.g "if FAILED(hr) ... tokAfterCondition=NULL;
// see for example TestMemleakInFunction::switch4 if (!tokAfterCondition) {
tokAfterCondition=tokCondition;
tokAfterCondition=tokAfterCondition->next();
if (tokAfterCondition &&
tokAfterCondition->str()=="(")
tokAfterCondition=tokAfterCondition->link();
}
if (tokAfterCondition) {
if (tokAfterCondition->str()!=")") {
// Bad condition // Bad condition
return tok; syntaxError(tok);
return NULL;
} }
tokAfterCondition=tokAfterCondition->next(); tokAfterCondition=tokAfterCondition->next();
} }
}
if (!tokAfterCondition || if (!tokAfterCondition ||
((tokAfterCondition->type()==Token::eBracket || ((tokAfterCondition->type()==Token::eBracket ||
tokAfterCondition->type()==Token::eExtendedOp)&& tokAfterCondition->type()==Token::eExtendedOp)&&

View File

@ -283,18 +283,23 @@ public:
void simplifyComma(); void simplifyComma();
/** Add braces to an if-block, for-block, etc. /** 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. /** Add braces to an if-block, for-block, etc.
* for command starting at token including else-block * 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); Token * simplifyAddBracesToCommand(Token * tok);
/** Add pair of braces to an single if-block, else-block, for-block, etc. /** Add pair of braces to an single if-block, else-block, for-block, etc.
* for command starting at token * 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); Token * simplifyAddBracesPair(Token *tok, bool commandWithCondition);

View File

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

View File

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

View File

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