Fixed #7637 (FP syntax error assignment in switch)

This commit is contained in:
Daniel Marjamäki 2016-07-26 12:15:55 +02:00
parent 5c92c231b8
commit 7ff9545b10
4 changed files with 32 additions and 3 deletions

View File

@ -8086,13 +8086,13 @@ void Tokenizer::validate() const
const Token * Tokenizer::findGarbageCode() const const Token * Tokenizer::findGarbageCode() const
{ {
for (const Token *tok = tokens(); tok; tok = tok->next()) { for (const Token *tok = tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "if|while|for|switch")) { // switch (EXPR) { ... } if (Token::Match(tok, "if|while|for|switch")) { // if|while|for|switch (EXPR) { ... }
if (tok->previous() && !Token::Match(tok->previous(), ":|;|{|}|(|)|,|else|do")) if (tok->previous() && !Token::Match(tok->previous(), ":|;|{|}|(|)|,|else|do"))
return tok; return tok;
if (Token::Match(tok->previous(), "[(,]"))
continue;
if (!Token::Match(tok->next(), "( !!)")) if (!Token::Match(tok->next(), "( !!)"))
return tok; return tok;
if (tok->str() == "switch" && !Token::simpleMatch(tok->linkAt(1),") {"))
return tok->linkAt(1);
if (tok->str() != "for") { if (tok->str() != "for") {
if (isGarbageExpr(tok->next(), tok->linkAt(1))) if (isGarbageExpr(tok->next(), tok->linkAt(1)))
return tok; return tok;

View File

@ -239,6 +239,18 @@ void TestFixture::assertThrowFail(const char *filename, unsigned int linenr) con
} }
} }
void TestFixture::assertNoThrowFail(const char *filename, unsigned int linenr) const
{
++fails_counter;
if (gcc_style_errors) {
errmsg << filename << ':' << linenr << " Assertion failed. "
<< "Unexpected exception was thrown" << std::endl;
} else {
errmsg << "Assertion failed in " << filename << " at line " << linenr << std::endl
<< "Unexpected exception was thrown" << std::endl << "_____" << std::endl;
}
}
void TestFixture::complainMissingLib(const char* libname) const void TestFixture::complainMissingLib(const char* libname) const
{ {
missingLibs.insert(libname); missingLibs.insert(libname);

View File

@ -61,6 +61,7 @@ protected:
long long current, long long actual) const; long long current, long long actual) const;
void assertThrow(const char *filename, unsigned int linenr) const; void assertThrow(const char *filename, unsigned int linenr) const;
void assertThrowFail(const char *filename, unsigned int linenr) const; void assertThrowFail(const char *filename, unsigned int linenr) const;
void assertNoThrowFail(const char *filename, unsigned int linenr) const;
void complainMissingLib(const char* libname) const; void complainMissingLib(const char* libname) const;
void processOptions(const options& args); void processOptions(const options& args);
@ -85,6 +86,7 @@ extern std::ostringstream warnings;
#define ASSERT_EQUALS_DOUBLE( EXPECTED , ACTUAL ) assertEqualsDouble(__FILE__, __LINE__, EXPECTED, ACTUAL) #define ASSERT_EQUALS_DOUBLE( EXPECTED , ACTUAL ) assertEqualsDouble(__FILE__, __LINE__, EXPECTED, ACTUAL)
#define ASSERT_EQUALS_MSG( EXPECTED , ACTUAL, MSG ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL, MSG) #define ASSERT_EQUALS_MSG( EXPECTED , ACTUAL, MSG ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL, MSG)
#define ASSERT_THROW( CMD, EXCEPTION ) try { CMD ; assertThrowFail(__FILE__, __LINE__); } catch (const EXCEPTION&) { } catch (...) { assertThrowFail(__FILE__, __LINE__); } #define ASSERT_THROW( CMD, EXCEPTION ) try { CMD ; assertThrowFail(__FILE__, __LINE__); } catch (const EXCEPTION&) { } catch (...) { assertThrowFail(__FILE__, __LINE__); }
#define ASSERT_NO_THROW( CMD ) try { CMD ; } catch (...) { assertNoThrowFail(__FILE__, __LINE__); }
#define TODO_ASSERT_THROW( CMD, EXCEPTION ) try { CMD ; } catch (const EXCEPTION&) { } catch (...) { assertThrow(__FILE__, __LINE__); } #define TODO_ASSERT_THROW( CMD, EXCEPTION ) try { CMD ; } catch (const EXCEPTION&) { } catch (...) { assertThrow(__FILE__, __LINE__); }
#define TODO_ASSERT( CONDITION ) { bool condition=CONDITION; todoAssertEquals(__FILE__, __LINE__, true, false, condition); } #define TODO_ASSERT( CONDITION ) { bool condition=CONDITION; todoAssertEquals(__FILE__, __LINE__, true, false, condition); }
#define TODO_ASSERT_EQUALS( WANTED , CURRENT , ACTUAL ) todoAssertEquals(__FILE__, __LINE__, WANTED, CURRENT, ACTUAL) #define TODO_ASSERT_EQUALS( WANTED , CURRENT , ACTUAL ) todoAssertEquals(__FILE__, __LINE__, WANTED, CURRENT, ACTUAL)

View File

@ -456,6 +456,10 @@ private:
TEST_CASE(removeMacroInClassDef); // #6058 TEST_CASE(removeMacroInClassDef); // #6058
TEST_CASE(sizeofAddParentheses); TEST_CASE(sizeofAddParentheses);
// Make sure the Tokenizer::findGarbageCode() does not have false positives
// The TestGarbage ensures that there are true positives
TEST_CASE(findGarbageCode);
} }
std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) { std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) {
@ -8379,6 +8383,17 @@ private:
ASSERT_EQUALS("sizeof ( a [ 2 ] . b ) + 3 ;", tokenizeAndStringify("sizeof a[2].b+3;")); ASSERT_EQUALS("sizeof ( a [ 2 ] . b ) + 3 ;", tokenizeAndStringify("sizeof a[2].b+3;"));
ASSERT_EQUALS("f ( 0 , sizeof ( ptr . bar ) ) ;", tokenizeAndStringify("f(0, sizeof ptr->bar );")); ASSERT_EQUALS("f ( 0 , sizeof ( ptr . bar ) ) ;", tokenizeAndStringify("f(0, sizeof ptr->bar );"));
} }
void findGarbageCode() { // Make sure the Tokenizer::findGarbageCode() does not have FPs
// before if|for|while|switch
ASSERT_NO_THROW(tokenizeAndStringify("void f() { do switch (a) {} while (1); }"))
ASSERT_NO_THROW(tokenizeAndStringify("void f() { label: switch (a) {} }"));
// TODO ASSERT_NO_THROW(tokenizeAndStringify("void f() { MACRO(switch); }"));
// TODO ASSERT_NO_THROW(tokenizeAndStringify("void f() { MACRO(x,switch); }"));
ASSERT_NO_THROW(tokenizeAndStringify("void f() { switch (a) int b; }"));
}
}; };
REGISTER_TEST(TestTokenizer) REGISTER_TEST(TestTokenizer)