Fixed #7821 (syntax error, first token is &)
This commit is contained in:
parent
4388435ce1
commit
74fa69fe5e
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue