Fixed #7821 (syntax error, first token is &)

This commit is contained in:
Daniel Marjamäki 2016-11-20 17:59:50 +01:00
parent 4388435ce1
commit 74fa69fe5e
8 changed files with 71 additions and 79 deletions

View File

@ -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 // Code must end with } ; ) NAME
if (!Token::Match(list.back(), "%name%|;|}|)")) if (!Token::Match(list.back(), "%name%|;|}|)"))
return list.back(); return list.back();

View File

@ -152,7 +152,6 @@ private:
TEST_CASE(garbageCode110); TEST_CASE(garbageCode110);
TEST_CASE(garbageCode111); TEST_CASE(garbageCode111);
TEST_CASE(garbageCode112); TEST_CASE(garbageCode112);
TEST_CASE(garbageCode113);
TEST_CASE(garbageCode114); TEST_CASE(garbageCode114);
TEST_CASE(garbageCode115); // #5506 TEST_CASE(garbageCode115); // #5506
TEST_CASE(garbageCode116); // #5356 TEST_CASE(garbageCode116); // #5356
@ -188,11 +187,10 @@ private:
TEST_CASE(garbageCode148); // #7090 TEST_CASE(garbageCode148); // #7090
TEST_CASE(garbageCode149); // #7085 TEST_CASE(garbageCode149); // #7085
TEST_CASE(garbageCode150); // #7089 TEST_CASE(garbageCode150); // #7089
TEST_CASE(garbageCode151); // #4175 TEST_CASE(garbageCode151); // #4911
TEST_CASE(garbageCode152); // travis after 9c7271a5 TEST_CASE(garbageCode152); // travis after 9c7271a5
TEST_CASE(garbageCode153); TEST_CASE(garbageCode153);
TEST_CASE(garbageCode154); // #7112 TEST_CASE(garbageCode154); // #7112
TEST_CASE(garbageCode155); // #7118
TEST_CASE(garbageCode156); // #7120 TEST_CASE(garbageCode156); // #7120
TEST_CASE(garbageCode157); // #7131 TEST_CASE(garbageCode157); // #7131
TEST_CASE(garbageCode158); // #3238 TEST_CASE(garbageCode158); // #3238
@ -214,7 +212,6 @@ private:
TEST_CASE(garbageCode175); TEST_CASE(garbageCode175);
TEST_CASE(garbageCode176); // #7527 TEST_CASE(garbageCode176); // #7527
TEST_CASE(garbageCode177); // #7321 TEST_CASE(garbageCode177); // #7321
TEST_CASE(garbageCode179); // #3533
TEST_CASE(garbageCode180); TEST_CASE(garbageCode180);
TEST_CASE(garbageCode181); TEST_CASE(garbageCode181);
TEST_CASE(garbageCode182); // #4195 TEST_CASE(garbageCode182); // #4195
@ -224,7 +221,8 @@ private:
TEST_CASE(garbageSymbolDatabase); TEST_CASE(garbageSymbolDatabase);
TEST_CASE(garbageAST); TEST_CASE(garbageAST);
TEST_CASE(templateSimplifierCrashes); 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) { std::string checkCode(const char code[], bool cpp = true) {
@ -869,10 +867,6 @@ private:
TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ) } {{ }}>> enum { FOO< = ( ) } { { } } ;"), InternalError); TODO_ASSERT_THROW(checkCode("enum { FOO = ( , ) } {{ }}>> enum { FOO< = ( ) } { { } } ;"), InternalError);
} }
void garbageCode113() { // #6858
checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }");
}
void garbageCode114() { // #2118 void garbageCode114() { // #2118
ASSERT_THROW(checkCode("Q_GLOBAL_STATIC_WITH_INITIALIZER(Qt4NodeStaticData, qt4NodeStaticData, {\n" ASSERT_THROW(checkCode("Q_GLOBAL_STATIC_WITH_INITIALIZER(Qt4NodeStaticData, qt4NodeStaticData, {\n"
" for (unsigned i = 0 ; i < count; i++) {\n" " for (unsigned i = 0 ; i < count; i++) {\n"
@ -1166,9 +1160,8 @@ private:
"}\n"), InternalError); "}\n"), InternalError);
} }
void garbageCode151() { // #4175 void garbageCode151() { // #4911 - bad simplification => don't crash
checkCode(">{ x while (y) z int = }"); checkCode("void f() {\n"
checkCode("void f() {\n" // #4911 - bad simplification => don't crash
" int a;\n" " int a;\n"
" do { a=do_something() } while (a);\n" " do { a=do_something() } while (a);\n"
"}"); "}");
@ -1189,10 +1182,6 @@ private:
checkCode("\"abc\"[];"); checkCode("\"abc\"[];");
} }
void garbageCode155() { // #7118
checkCode("&p(!{}e x){({(0?:?){({})}()})}");
}
void garbageCode156() { // #7120 void garbageCode156() { // #7120
checkCode("struct {}a; d f() { c ? : } {}a.p"); checkCode("struct {}a; d f() { c ? : } {}a.p");
} }
@ -1298,8 +1287,6 @@ private:
"}\n" "}\n"
); );
checkCode(" > template < . > struct Y < T > { = } ;\n"); // #6108
checkCode( // #6117 checkCode( // #6117
"template <typename ...> struct something_like_tuple\n" "template <typename ...> struct something_like_tuple\n"
"{};\n" "{};\n"
@ -1420,15 +1407,6 @@ private:
checkCode("{(){(())}}r&const"); checkCode("{(){(())}}r&const");
} }
void garbageCode179() { // #3533
checkCode("<class T>\n"
"{\n"
" struct {\n"
" typename D4:typename Base<T*>\n"
" };\n"
"};");
}
void garbageCode180() { void garbageCode180() {
checkCode("int"); 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("<class T> { struct { typename D4:typename Base<T*> }; };"), InternalError); // #3533
ASSERT_THROW(checkCode(" > template < . > struct Y < T > { = } ;\n"), InternalError); // #6108
}
void syntaxErrorLastToken() {
ASSERT_THROW(checkCode("int *"), InternalError); // #7821 ASSERT_THROW(checkCode("int *"), InternalError); // #7821
ASSERT_THROW(checkCode("x[y]"), InternalError); // #2986 ASSERT_THROW(checkCode("x[y]"), InternalError); // #2986
ASSERT_THROW(checkCode("( ) &"), InternalError); ASSERT_THROW(checkCode("( ) &"), InternalError);

View File

@ -576,10 +576,10 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory pointed to by 'p' is freed twice.\n", errout.str());
check( check(
"~LineMarker() {\n" "LineMarker::~LineMarker() {\n"
" delete pxpm;\n" " delete pxpm;\n"
"}\n" "}\n"
"LineMarker &operator=(const LineMarker &) {\n" "LineMarker &LineMarker::operator=(const LineMarker &) {\n"
" delete pxpm;\n" " delete pxpm;\n"
" pxpm = NULL;\n" " pxpm = NULL;\n"
" return *this;\n" " return *this;\n"

View File

@ -1292,27 +1292,27 @@ private:
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp", ""); tokenizer.tokenize(istr, "test.cpp", "");
return TemplateSimplifier::templateParameters(tokenizer.tokens()); return TemplateSimplifier::templateParameters(tokenizer.tokens()->next());
} }
void templateParameters() { void templateParameters() {
// Test that the function TemplateSimplifier::templateParameters works // Test that the function TemplateSimplifier::templateParameters works
ASSERT_EQUALS(1U, templateParameters("<struct C> x;")); ASSERT_EQUALS(1U, templateParameters("X<struct C> x;"));
ASSERT_EQUALS(1U, templateParameters("<union C> x;")); ASSERT_EQUALS(1U, templateParameters("X<union C> x;"));
ASSERT_EQUALS(1U, templateParameters("<const int> x;")); ASSERT_EQUALS(1U, templateParameters("X<const int> x;"));
ASSERT_EQUALS(1U, templateParameters("<int const *> x;")); ASSERT_EQUALS(1U, templateParameters("X<int const *> x;"));
ASSERT_EQUALS(1U, templateParameters("<const struct C> x;")); ASSERT_EQUALS(1U, templateParameters("X<const struct C> x;"));
ASSERT_EQUALS(0U, templateParameters("<len>>x;")); ASSERT_EQUALS(0U, templateParameters("X<len>>x;"));
ASSERT_EQUALS(1U, templateParameters("<typename> x;")); ASSERT_EQUALS(1U, templateParameters("X<typename> x;"));
ASSERT_EQUALS(0U, templateParameters("<...> x;")); ASSERT_EQUALS(0U, templateParameters("X<...> x;"));
ASSERT_EQUALS(0U, templateParameters("<class T...> x;")); // Invalid syntax ASSERT_EQUALS(0U, templateParameters("X<class T...> x;")); // Invalid syntax
ASSERT_EQUALS(1U, templateParameters("<class... T> x;")); ASSERT_EQUALS(1U, templateParameters("X<class... T> x;"));
ASSERT_EQUALS(0U, templateParameters("<class, typename T...> x;")); // Invalid syntax ASSERT_EQUALS(0U, templateParameters("X<class, typename T...> x;")); // Invalid syntax
ASSERT_EQUALS(2U, templateParameters("<class, typename... T> x;")); ASSERT_EQUALS(2U, templateParameters("X<class, typename... T> x;"));
ASSERT_EQUALS(2U, templateParameters("<int(&)(), class> x;")); ASSERT_EQUALS(2U, templateParameters("X<int(&)(), class> x;"));
ASSERT_EQUALS(3U, templateParameters("<char, int(*)(), bool> x;")); ASSERT_EQUALS(3U, templateParameters("X<char, int(*)(), bool> x;"));
TODO_ASSERT_EQUALS(1U, 0U, templateParameters("<int...> x;")); // Mishandled valid syntax TODO_ASSERT_EQUALS(1U, 0U, templateParameters("X<int...> x;")); // Mishandled valid syntax
TODO_ASSERT_EQUALS(2U, 0U, templateParameters("<class, typename...> x;")); // Mishandled valid syntax TODO_ASSERT_EQUALS(2U, 0U, templateParameters("X<class, typename...> x;")); // Mishandled valid syntax
} }
// Helper function to unit test TemplateSimplifier::getTemplateNamePosition // Helper function to unit test TemplateSimplifier::getTemplateNamePosition

View File

@ -3940,7 +3940,7 @@ private:
// char * // char *
ASSERT_EQUALS("const char *", typeOf("\"hello\" + 1;", "+")); ASSERT_EQUALS("const char *", typeOf("\"hello\" + 1;", "+"));
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;", "+")); ASSERT_EQUALS("const short *", typeOf("L\"hello\" + 1;", "+"));
// Variable calculations // Variable calculations
@ -3983,7 +3983,7 @@ private:
// Boolean operators // Boolean operators
ASSERT_EQUALS("bool", typeOf("a > b;", ">")); ASSERT_EQUALS("bool", typeOf("a > b;", ">"));
ASSERT_EQUALS("bool", typeOf("!b;", "!")); ASSERT_EQUALS("bool", typeOf(";!b;", "!"));
ASSERT_EQUALS("bool", typeOf("c = a && b;", "&&")); ASSERT_EQUALS("bool", typeOf("c = a && b;", "&&"));
// shift => result has same type as lhs // shift => result has same type as lhs

View File

@ -118,11 +118,11 @@ private:
bool Match(const std::string &code, const std::string &pattern, unsigned int varid=0) { bool Match(const std::string &code, const std::string &pattern, unsigned int varid=0) {
static const Settings settings; static const Settings settings;
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code + ";"); std::istringstream istr(";" + code + ";");
try { try {
tokenizer.tokenize(istr, "test.cpp"); tokenizer.tokenize(istr, "test.cpp");
} catch (...) {} } catch (...) {}
return Token::Match(tokenizer.tokens(), pattern.c_str(), varid); return Token::Match(tokenizer.tokens()->next(), pattern.c_str(), varid);
} }
void multiCompare() const { void multiCompare() const {
@ -512,27 +512,27 @@ private:
} }
void matchOr() const { void matchOr() const {
givenACodeSampleToTokenize bitwiseOr("|;", true); givenACodeSampleToTokenize bitwiseOr(";|;", true);
ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "%or%")); ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "; %or%"));
ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "%op%")); ASSERT_EQUALS(true, Token::Match(bitwiseOr.tokens(), "; %op%"));
ASSERT_EQUALS(false, Token::Match(bitwiseOr.tokens(), "%oror%")); ASSERT_EQUALS(false, Token::Match(bitwiseOr.tokens(), "; %oror%"));
givenACodeSampleToTokenize bitwiseOrAssignment("|=;"); givenACodeSampleToTokenize bitwiseOrAssignment(";|=;");
ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "%or%")); ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "; %or%"));
ASSERT_EQUALS(true, Token::Match(bitwiseOrAssignment.tokens(), "%op%")); ASSERT_EQUALS(true, Token::Match(bitwiseOrAssignment.tokens(), "; %op%"));
ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "%oror%")); ASSERT_EQUALS(false, Token::Match(bitwiseOrAssignment.tokens(), "; %oror%"));
givenACodeSampleToTokenize logicalOr("||;", true); givenACodeSampleToTokenize logicalOr(";||;", true);
ASSERT_EQUALS(false, Token::Match(logicalOr.tokens(), "%or%")); ASSERT_EQUALS(false, Token::Match(logicalOr.tokens(), "; %or%"));
ASSERT_EQUALS(true, Token::Match(logicalOr.tokens(), "%op%")); 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%")); 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); givenACodeSampleToTokenize logicalAnd(";&&;", true);
ASSERT_EQUALS(true, Token::simpleMatch(logicalAnd.tokens(), "&&")); ASSERT_EQUALS(true, Token::simpleMatch(logicalAnd.tokens(), "; &&"));
ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "&&|%oror%")); ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "; &&|%oror%"));
ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "%oror%|&&")); ASSERT_EQUALS(true, Token::Match(logicalAnd.tokens(), "; %oror%|&&"));
} }
static void append_vector(std::vector<std::string> &dest, const std::vector<std::string> &src) { static void append_vector(std::vector<std::string> &dest, const std::vector<std::string> &src) {

View File

@ -3191,8 +3191,8 @@ private:
void removeParentheses16() { // *(x.y)= void removeParentheses16() { // *(x.y)=
// #4423 // #4423
ASSERT_EQUALS("* x = 0 ;", tokenizeAndStringify("*(x)=0;", false)); ASSERT_EQUALS("; * x = 0 ;", tokenizeAndStringify(";*(x)=0;", false));
ASSERT_EQUALS("* x . y = 0 ;", tokenizeAndStringify("*(x.y)=0;", false)); ASSERT_EQUALS("; * x . y = 0 ;", tokenizeAndStringify(";*(x.y)=0;", false));
} }
void removeParentheses17() { // a ? b : (c > 0 ? d : e) void removeParentheses17() { // a ? b : (c > 0 ? d : e)
@ -3232,8 +3232,8 @@ private:
void removeParentheses23() { // Ticket #6103 void removeParentheses23() { // Ticket #6103
// Reported case // Reported case
{ {
static char code[] = "* * 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 }"; static char exp[] = "; * * p f ( ) int = { new int ( * [ 2 ] ) ; void }";
ASSERT_EQUALS(exp, tokenizeAndStringify(code)); ASSERT_EQUALS(exp, tokenizeAndStringify(code));
} }
// Various valid cases // Various valid cases

View File

@ -372,12 +372,12 @@ private:
ASSERT_EQUALS(0, valueOfTok("3 <= (a ? b : 2);", "<=").intvalue); ASSERT_EQUALS(0, valueOfTok("3 <= (a ? b : 2);", "<=").intvalue);
// Don't calculate if there is UB // Don't calculate if there is UB
ASSERT(tokenValues("-1<<10;","<<").empty()); ASSERT(tokenValues(";-1<<10;","<<").empty());
ASSERT(tokenValues("10<<-1;","<<").empty()); ASSERT(tokenValues(";10<<-1;","<<").empty());
ASSERT(tokenValues("10<<64;","<<").empty()); ASSERT(tokenValues(";10<<64;","<<").empty());
ASSERT(tokenValues("-1>>10;",">>").empty()); ASSERT(tokenValues(";-1>>10;",">>").empty());
ASSERT(tokenValues("10>>-1;",">>").empty()); ASSERT(tokenValues(";10>>-1;",">>").empty());
ASSERT(tokenValues("10>>64;",">>").empty()); ASSERT(tokenValues(";10>>64;",">>").empty());
// calculation using 1,2 variables/values // calculation using 1,2 variables/values
code = "void f(int x) {\n" code = "void f(int x) {\n"