From 5144307642ea6c4503a8e23389f8913f1692aa88 Mon Sep 17 00:00:00 2001 From: Frank Zingsheim Date: Tue, 5 Feb 2013 21:13:57 +0100 Subject: [PATCH] Raise syntax error for if-condition without parentheses according to #2518 #4171 --- lib/tokenize.cpp | 43 +++++++++++++++++++++--------------------- lib/tokenize.h | 11 ++++++++--- test/testmemleak.cpp | 3 ++- test/testtokenize.cpp | 2 +- test/testuninitvar.cpp | 2 +- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9dc1161c2..d81ef87f8 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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 || diff --git a/lib/tokenize.h b/lib/tokenize.h index 5d2ac53cb..5c05695ec 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -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); diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index dcb8eed15..077d9762b 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -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() { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index bb535595e..20f1af0c4 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -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()); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 6802c2d6f..8ae5c9d5e 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -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"