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
if (!Token::Match(list.back(), "%name%|;|}|)"))
return list.back();

View File

@ -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 <typename ...> struct something_like_tuple\n"
"{};\n"
@ -1420,15 +1407,6 @@ private:
checkCode("{(){(())}}r&const");
}
void garbageCode179() { // #3533
checkCode("<class T>\n"
"{\n"
" struct {\n"
" typename D4:typename Base<T*>\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("<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("x[y]"), InternalError); // #2986
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());
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"

View File

@ -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("<struct C> x;"));
ASSERT_EQUALS(1U, templateParameters("<union C> x;"));
ASSERT_EQUALS(1U, templateParameters("<const int> x;"));
ASSERT_EQUALS(1U, templateParameters("<int const *> x;"));
ASSERT_EQUALS(1U, templateParameters("<const struct C> x;"));
ASSERT_EQUALS(0U, templateParameters("<len>>x;"));
ASSERT_EQUALS(1U, templateParameters("<typename> x;"));
ASSERT_EQUALS(0U, templateParameters("<...> x;"));
ASSERT_EQUALS(0U, templateParameters("<class T...> x;")); // Invalid syntax
ASSERT_EQUALS(1U, templateParameters("<class... T> x;"));
ASSERT_EQUALS(0U, templateParameters("<class, typename T...> x;")); // Invalid syntax
ASSERT_EQUALS(2U, templateParameters("<class, typename... T> x;"));
ASSERT_EQUALS(2U, templateParameters("<int(&)(), class> x;"));
ASSERT_EQUALS(3U, templateParameters("<char, int(*)(), bool> x;"));
TODO_ASSERT_EQUALS(1U, 0U, templateParameters("<int...> x;")); // Mishandled valid syntax
TODO_ASSERT_EQUALS(2U, 0U, templateParameters("<class, typename...> x;")); // Mishandled valid syntax
ASSERT_EQUALS(1U, templateParameters("X<struct C> x;"));
ASSERT_EQUALS(1U, templateParameters("X<union C> x;"));
ASSERT_EQUALS(1U, templateParameters("X<const int> x;"));
ASSERT_EQUALS(1U, templateParameters("X<int const *> x;"));
ASSERT_EQUALS(1U, templateParameters("X<const struct C> x;"));
ASSERT_EQUALS(0U, templateParameters("X<len>>x;"));
ASSERT_EQUALS(1U, templateParameters("X<typename> x;"));
ASSERT_EQUALS(0U, templateParameters("X<...> x;"));
ASSERT_EQUALS(0U, templateParameters("X<class T...> x;")); // Invalid syntax
ASSERT_EQUALS(1U, templateParameters("X<class... T> x;"));
ASSERT_EQUALS(0U, templateParameters("X<class, typename T...> x;")); // Invalid syntax
ASSERT_EQUALS(2U, templateParameters("X<class, typename... T> x;"));
ASSERT_EQUALS(2U, templateParameters("X<int(&)(), class> x;"));
ASSERT_EQUALS(3U, templateParameters("X<char, int(*)(), bool> x;"));
TODO_ASSERT_EQUALS(1U, 0U, templateParameters("X<int...> x;")); // Mishandled valid syntax
TODO_ASSERT_EQUALS(2U, 0U, templateParameters("X<class, typename...> x;")); // Mishandled valid syntax
}
// Helper function to unit test TemplateSimplifier::getTemplateNamePosition

View File

@ -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

View File

@ -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<std::string> &dest, const std::vector<std::string> &src) {

View File

@ -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

View File

@ -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"