From 74fa69fe5eaf04bbec145f204c402a1964aaba65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 20 Nov 2016 17:59:50 +0100 Subject: [PATCH] Fixed #7821 (syntax error, first token is &) --- lib/tokenize.cpp | 4 ++++ test/testgarbage.cpp | 44 +++++++++++++---------------------- test/testleakautovar.cpp | 4 ++-- test/testsimplifytemplate.cpp | 34 +++++++++++++-------------- test/testsymboldatabase.cpp | 4 ++-- test/testtoken.cpp | 40 +++++++++++++++---------------- test/testtokenize.cpp | 8 +++---- test/testvalueflow.cpp | 12 +++++----- 8 files changed, 71 insertions(+), 79 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index f38e9d0d6..263168a33 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8028,6 +8028,10 @@ const Token * Tokenizer::findGarbageCode() const } } + // Code must not start with an arithmetical operand + if (Token::Match(list.front(), "%cop%")) + return list.front(); + // Code must end with } ; ) NAME if (!Token::Match(list.back(), "%name%|;|}|)")) return list.back(); diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 15b102db3..0141b3637 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -152,7 +152,6 @@ private: TEST_CASE(garbageCode110); TEST_CASE(garbageCode111); TEST_CASE(garbageCode112); - TEST_CASE(garbageCode113); TEST_CASE(garbageCode114); TEST_CASE(garbageCode115); // #5506 TEST_CASE(garbageCode116); // #5356 @@ -188,11 +187,10 @@ private: TEST_CASE(garbageCode148); // #7090 TEST_CASE(garbageCode149); // #7085 TEST_CASE(garbageCode150); // #7089 - TEST_CASE(garbageCode151); // #4175 + TEST_CASE(garbageCode151); // #4911 TEST_CASE(garbageCode152); // travis after 9c7271a5 TEST_CASE(garbageCode153); TEST_CASE(garbageCode154); // #7112 - TEST_CASE(garbageCode155); // #7118 TEST_CASE(garbageCode156); // #7120 TEST_CASE(garbageCode157); // #7131 TEST_CASE(garbageCode158); // #3238 @@ -214,7 +212,6 @@ private: TEST_CASE(garbageCode175); TEST_CASE(garbageCode176); // #7527 TEST_CASE(garbageCode177); // #7321 - TEST_CASE(garbageCode179); // #3533 TEST_CASE(garbageCode180); TEST_CASE(garbageCode181); TEST_CASE(garbageCode182); // #4195 @@ -224,7 +221,8 @@ private: TEST_CASE(garbageSymbolDatabase); TEST_CASE(garbageAST); TEST_CASE(templateSimplifierCrashes); - TEST_CASE(garbageLastToken); // Make sure syntax errors are detected and reported + TEST_CASE(syntaxErrorFirstToken); // Make sure syntax errors are detected and reported + TEST_CASE(syntaxErrorLastToken); // Make sure syntax errors are detected and reported } std::string checkCode(const char code[], bool cpp = true) { @@ -869,10 +867,6 @@ private: TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ) } {{ }}>> enum { FOO< = ( ) } { { } } ;"), InternalError); } - void garbageCode113() { // #6858 - checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"); - } - void garbageCode114() { // #2118 ASSERT_THROW(checkCode("Q_GLOBAL_STATIC_WITH_INITIALIZER(Qt4NodeStaticData, qt4NodeStaticData, {\n" " for (unsigned i = 0 ; i < count; i++) {\n" @@ -1166,9 +1160,8 @@ private: "}\n"), InternalError); } - void garbageCode151() { // #4175 - checkCode(">{ x while (y) z int = }"); - checkCode("void f() {\n" // #4911 - bad simplification => don't crash + void garbageCode151() { // #4911 - bad simplification => don't crash + checkCode("void f() {\n" " int a;\n" " do { a=do_something() } while (a);\n" "}"); @@ -1189,10 +1182,6 @@ private: checkCode("\"abc\"[];"); } - void garbageCode155() { // #7118 - checkCode("&p(!{}e x){({(0?:?){({})}()})}"); - } - void garbageCode156() { // #7120 checkCode("struct {}a; d f() { c ? : } {}a.p"); } @@ -1298,8 +1287,6 @@ private: "}\n" ); - checkCode(" > template < . > struct Y < T > { = } ;\n"); // #6108 - checkCode( // #6117 "template struct something_like_tuple\n" "{};\n" @@ -1420,15 +1407,6 @@ private: checkCode("{(){(())}}r&const"); } - void garbageCode179() { // #3533 - checkCode("\n" - "{\n" - " struct {\n" - " typename D4:typename Base\n" - " };\n" - "};"); - } - void garbageCode180() { checkCode("int"); } @@ -1453,7 +1431,17 @@ private: "}"); } - void garbageLastToken() { + void syntaxErrorFirstToken() { + ASSERT_THROW(checkCode("&operator(){[]};"), InternalError); // #7818 + ASSERT_THROW(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"), InternalError); // #6858 + ASSERT_THROW(checkCode(">{ x while (y) z int = }"), InternalError); // #4175 + ASSERT_THROW(checkCode("&p(!{}e x){({(0?:?){({})}()})}"), InternalError); // #7118 + ASSERT_THROW(checkCode(" { struct { typename D4:typename Base }; };"), InternalError); // #3533 + ASSERT_THROW(checkCode(" > template < . > struct Y < T > { = } ;\n"), InternalError); // #6108 + + } + + void syntaxErrorLastToken() { ASSERT_THROW(checkCode("int *"), InternalError); // #7821 ASSERT_THROW(checkCode("x[y]"), InternalError); // #2986 ASSERT_THROW(checkCode("( ) &"), InternalError); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index c1da4118c..86f922d05 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -576,10 +576,10 @@ private: ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str()); check( - "~LineMarker() {\n" + "LineMarker::~LineMarker() {\n" " delete pxpm;\n" "}\n" - "LineMarker &operator=(const LineMarker &) {\n" + "LineMarker &LineMarker::operator=(const LineMarker &) {\n" " delete pxpm;\n" " pxpm = NULL;\n" " return *this;\n" diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 5ef237f11..fbb8e5588 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -1292,27 +1292,27 @@ private: std::istringstream istr(code); tokenizer.tokenize(istr, "test.cpp", ""); - return TemplateSimplifier::templateParameters(tokenizer.tokens()); + return TemplateSimplifier::templateParameters(tokenizer.tokens()->next()); } void templateParameters() { // Test that the function TemplateSimplifier::templateParameters works - ASSERT_EQUALS(1U, templateParameters(" x;")); - ASSERT_EQUALS(1U, templateParameters(" x;")); - ASSERT_EQUALS(1U, templateParameters(" x;")); - ASSERT_EQUALS(1U, templateParameters(" x;")); - ASSERT_EQUALS(1U, templateParameters(" x;")); - ASSERT_EQUALS(0U, templateParameters(">x;")); - ASSERT_EQUALS(1U, templateParameters(" x;")); - ASSERT_EQUALS(0U, templateParameters("<...> x;")); - ASSERT_EQUALS(0U, templateParameters(" x;")); // Invalid syntax - ASSERT_EQUALS(1U, templateParameters(" x;")); - ASSERT_EQUALS(0U, templateParameters(" x;")); // Invalid syntax - ASSERT_EQUALS(2U, templateParameters(" x;")); - ASSERT_EQUALS(2U, templateParameters(" x;")); - ASSERT_EQUALS(3U, templateParameters(" x;")); - TODO_ASSERT_EQUALS(1U, 0U, templateParameters(" x;")); // Mishandled valid syntax - TODO_ASSERT_EQUALS(2U, 0U, templateParameters(" x;")); // Mishandled valid syntax + ASSERT_EQUALS(1U, templateParameters("X x;")); + ASSERT_EQUALS(1U, templateParameters("X x;")); + ASSERT_EQUALS(1U, templateParameters("X x;")); + ASSERT_EQUALS(1U, templateParameters("X x;")); + ASSERT_EQUALS(1U, templateParameters("X x;")); + ASSERT_EQUALS(0U, templateParameters("X>x;")); + ASSERT_EQUALS(1U, templateParameters("X x;")); + ASSERT_EQUALS(0U, templateParameters("X<...> x;")); + ASSERT_EQUALS(0U, templateParameters("X x;")); // Invalid syntax + ASSERT_EQUALS(1U, templateParameters("X x;")); + ASSERT_EQUALS(0U, templateParameters("X x;")); // Invalid syntax + ASSERT_EQUALS(2U, templateParameters("X x;")); + ASSERT_EQUALS(2U, templateParameters("X x;")); + ASSERT_EQUALS(3U, templateParameters("X x;")); + TODO_ASSERT_EQUALS(1U, 0U, templateParameters("X x;")); // Mishandled valid syntax + TODO_ASSERT_EQUALS(2U, 0U, templateParameters("X x;")); // Mishandled valid syntax } // Helper function to unit test TemplateSimplifier::getTemplateNamePosition diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index b137143e1..e1effcc74 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3940,7 +3940,7 @@ private: // char * ASSERT_EQUALS("const char *", typeOf("\"hello\" + 1;", "+")); ASSERT_EQUALS("const char", typeOf("\"hello\"[1];", "[")); - ASSERT_EQUALS("const char", typeOf("*\"hello\";", "*")); + ASSERT_EQUALS("const char", typeOf(";*\"hello\";", "*")); ASSERT_EQUALS("const short *", typeOf("L\"hello\" + 1;", "+")); // Variable calculations @@ -3983,7 +3983,7 @@ private: // Boolean operators ASSERT_EQUALS("bool", typeOf("a > b;", ">")); - ASSERT_EQUALS("bool", typeOf("!b;", "!")); + ASSERT_EQUALS("bool", typeOf(";!b;", "!")); ASSERT_EQUALS("bool", typeOf("c = a && b;", "&&")); // shift => result has same type as lhs diff --git a/test/testtoken.cpp b/test/testtoken.cpp index e67771363..34ae0f9c6 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -118,11 +118,11 @@ private: bool Match(const std::string &code, const std::string &pattern, unsigned int varid=0) { static const Settings settings; Tokenizer tokenizer(&settings, this); - std::istringstream istr(code + ";"); + std::istringstream istr(";" + code + ";"); try { tokenizer.tokenize(istr, "test.cpp"); } catch (...) {} - return Token::Match(tokenizer.tokens(), pattern.c_str(), varid); + return Token::Match(tokenizer.tokens()->next(), pattern.c_str(), varid); } void multiCompare() const { @@ -512,27 +512,27 @@ private: } void matchOr() const { - givenACodeSampleToTokenize bitwiseOr("|;", true); - ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "%or%")); - ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "%op%")); - ASSERT_EQUALS(false, Token::Match(bitwiseOr.tokens(), "%oror%")); + givenACodeSampleToTokenize bitwiseOr(";|;", true); + ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "; %or%")); + ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "; %op%")); + ASSERT_EQUALS(false, Token::Match(bitwiseOr.tokens(), "; %oror%")); - givenACodeSampleToTokenize bitwiseOrAssignment("|=;"); - ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "%or%")); - ASSERT_EQUALS(true, Token::Match(bitwiseOrAssignment.tokens(), "%op%")); - ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "%oror%")); + givenACodeSampleToTokenize bitwiseOrAssignment(";|=;"); + ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "; %or%")); + ASSERT_EQUALS(true, Token::Match(bitwiseOrAssignment.tokens(), "; %op%")); + ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "; %oror%")); - givenACodeSampleToTokenize logicalOr("||;", true); - ASSERT_EQUALS(false, Token::Match(logicalOr.tokens(), "%or%")); - ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "%op%")); - ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "%oror%")); - ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "&&|%oror%")); - ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "%oror%|&&")); + givenACodeSampleToTokenize logicalOr(";||;", true); + ASSERT_EQUALS(false, Token::Match(logicalOr.tokens(), "; %or%")); + ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "; %op%")); + ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "; %oror%")); + ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "; &&|%oror%")); + ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "; %oror%|&&")); - givenACodeSampleToTokenize logicalAnd("&&;", true); - ASSERT_EQUALS(true, Token::simpleMatch(logicalAnd.tokens(), "&&")); - ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "&&|%oror%")); - ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "%oror%|&&")); + givenACodeSampleToTokenize logicalAnd(";&&;", true); + ASSERT_EQUALS(true, Token::simpleMatch(logicalAnd.tokens(), "; &&")); + ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "; &&|%oror%")); + ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "; %oror%|&&")); } static void append_vector(std::vector &dest, const std::vector &src) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index e41a31afb..3d555bdd0 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -3191,8 +3191,8 @@ private: void removeParentheses16() { // *(x.y)= // #4423 - ASSERT_EQUALS("* x = 0 ;", tokenizeAndStringify("*(x)=0;", false)); - ASSERT_EQUALS("* x . y = 0 ;", tokenizeAndStringify("*(x.y)=0;", false)); + ASSERT_EQUALS("; * x = 0 ;", tokenizeAndStringify(";*(x)=0;", false)); + ASSERT_EQUALS("; * x . y = 0 ;", tokenizeAndStringify(";*(x.y)=0;", false)); } void removeParentheses17() { // a ? b : (c > 0 ? d : e) @@ -3232,8 +3232,8 @@ private: void removeParentheses23() { // Ticket #6103 // Reported case { - static char code[] = "* * p f ( ) int = { new int ( * [ 2 ] ) ; void }"; - static char exp[] = "* * p f ( ) int = { new int ( * [ 2 ] ) ; void }"; + static char code[] = "; * * p f ( ) int = { new int ( * [ 2 ] ) ; void }"; + static char exp[] = "; * * p f ( ) int = { new int ( * [ 2 ] ) ; void }"; ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } // Various valid cases diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index e57de0212..df5ee8bff 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -372,12 +372,12 @@ private: ASSERT_EQUALS(0, valueOfTok("3 <= (a ? b : 2);", "<=").intvalue); // Don't calculate if there is UB - ASSERT(tokenValues("-1<<10;","<<").empty()); - ASSERT(tokenValues("10<<-1;","<<").empty()); - ASSERT(tokenValues("10<<64;","<<").empty()); - ASSERT(tokenValues("-1>>10;",">>").empty()); - ASSERT(tokenValues("10>>-1;",">>").empty()); - ASSERT(tokenValues("10>>64;",">>").empty()); + ASSERT(tokenValues(";-1<<10;","<<").empty()); + ASSERT(tokenValues(";10<<-1;","<<").empty()); + ASSERT(tokenValues(";10<<64;","<<").empty()); + ASSERT(tokenValues(";-1>>10;",">>").empty()); + ASSERT(tokenValues(";10>>-1;",">>").empty()); + ASSERT(tokenValues(";10>>64;",">>").empty()); // calculation using 1,2 variables/values code = "void f(int x) {\n"