Moved a few tests out of testtokenize.cpp; refactorized them
This commit is contained in:
parent
be72b7413a
commit
4ac6623875
|
@ -182,6 +182,8 @@ private:
|
|||
TEST_CASE(garbageCode130); // #7021
|
||||
TEST_CASE(garbageCode131); // #7023
|
||||
TEST_CASE(garbageCode132); // #7022
|
||||
TEST_CASE(garbageCode133);
|
||||
TEST_CASE(garbageCode134);
|
||||
|
||||
TEST_CASE(garbageValueFlow);
|
||||
TEST_CASE(garbageSymbolDatabase);
|
||||
|
@ -991,6 +993,77 @@ private:
|
|||
checkCode("() () { } { () () ({}) i() } void i(void(*ptr) ()) { ptr(!) () }");
|
||||
}
|
||||
|
||||
void garbageCode133() {
|
||||
ASSERT_THROW(checkCode("void f() {{}"), InternalError);
|
||||
|
||||
ASSERT_THROW(checkCode("void f()) {}"), InternalError);
|
||||
|
||||
ASSERT_THROW(checkCode("void f()\n"
|
||||
"{\n"
|
||||
" foo(;\n"
|
||||
"}\n"), InternalError);
|
||||
|
||||
ASSERT_THROW(checkCode("void f()\n"
|
||||
"{\n"
|
||||
" for(;;){ foo();\n"
|
||||
"}\n"), InternalError);
|
||||
|
||||
ASSERT_THROW(checkCode("void f()\n"
|
||||
"{\n"
|
||||
" a[10;\n"
|
||||
"}\n"), InternalError);
|
||||
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "{\n"
|
||||
" a(\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
" b());\n"
|
||||
"}\n";
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
try {
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
assertThrowFail(__FILE__, __LINE__);
|
||||
} catch (InternalError& e) {
|
||||
ASSERT_EQUALS("Invalid number of character '(' when these macros are defined: ''.", e.errorMessage);
|
||||
ASSERT_EQUALS("syntaxError", e.id);
|
||||
ASSERT_EQUALS(2, e.token->linenr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void garbageCode134() {
|
||||
// Ticket #5605, #5759, #5762, #5774, #5823, #6059
|
||||
checkCode("template<>\n");
|
||||
checkCode("foo() template<typename T1 = T2 = typename = unused, T5 = = unused> struct tuple Args> tuple<Args...> { } main() { foo<int,int,int,int,int,int>(); }");
|
||||
checkCode("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }");
|
||||
checkCode("() template < T = typename = x > struct a {} { f <int> () }");
|
||||
checkCode("template < T = typename = > struct a { f <int> }");
|
||||
checkCode("struct S { int i, j; }; "
|
||||
"template<int S::*p, typename U> struct X {}; "
|
||||
"X<&S::i, int> x = X<&S::i, int>(); "
|
||||
"X<&S::j, int> y = X<&S::j, int>(); ");
|
||||
checkCode("template <typename T> struct A {}; "
|
||||
"template <> struct A<void> {}; "
|
||||
"void foo(const void* f = 0) {}");
|
||||
checkCode("template<typename... T> struct A { "
|
||||
" static const int s = 0; "
|
||||
"}; "
|
||||
"A<int> a;");
|
||||
checkCode("template<class T, class U> class A {}; "
|
||||
"template<class T = A<int, int> > class B {}; "
|
||||
"template<class T = B<int> > class C { "
|
||||
" C() : _a(0), _b(0) {} "
|
||||
" int _a, _b; "
|
||||
"};");
|
||||
checkCode("template<class... T> struct A { "
|
||||
" static int i; "
|
||||
"}; "
|
||||
"void f() { A<int>::i = 0; }");
|
||||
}
|
||||
|
||||
|
||||
void garbageValueFlow() {
|
||||
// #6089
|
||||
|
|
|
@ -94,6 +94,8 @@ private:
|
|||
TEST_CASE(template_default_type);
|
||||
TEST_CASE(template_typename);
|
||||
TEST_CASE(template_constructor); // #3152 - template constructor is removed
|
||||
TEST_CASE(syntax_error_templates_1);
|
||||
TEST_CASE(template_member_ptr); // Ticket #5786 - crash upon valid code
|
||||
|
||||
// Test TemplateSimplifier::templateParameters
|
||||
TEST_CASE(templateParameters);
|
||||
|
@ -1177,6 +1179,81 @@ private:
|
|||
ASSERT_EQUALS("class Fred { template < class T > Fred ( T t ) { } }", tok(code2));
|
||||
}
|
||||
|
||||
void syntax_error_templates_1() {
|
||||
// ok code.. using ">" for a comparison
|
||||
tok("x<y>z> xyz;\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// ok code
|
||||
tok("template<class T> operator<(T a, T b) { }\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// ok code (ticket #1984)
|
||||
tok("void f(a) int a;\n"
|
||||
"{ ;x<y; }");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// ok code (ticket #1985)
|
||||
tok("void f()\n"
|
||||
"try { ;x<y; }");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// ok code (ticket #3183)
|
||||
tok("MACRO(({ i < x }))");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// bad code.. missing ">"
|
||||
ASSERT_THROW(tok("x<y<int> xyz;\n"), InternalError);
|
||||
|
||||
// bad code
|
||||
ASSERT_THROW(tok("typedef\n"
|
||||
" typename boost::mpl::if_c<\n"
|
||||
" _visitableIndex < boost::mpl::size< typename _Visitables::ConcreteVisitables >::value\n"
|
||||
" , ConcreteVisitable\n"
|
||||
" , Dummy< _visitableIndex >\n"
|
||||
" >::type ConcreteVisitableOrDummy;\n"), InternalError);
|
||||
|
||||
// code is ok, don't show syntax error
|
||||
tok("struct A {int a;int b};\n"
|
||||
"class Fred {"
|
||||
"public:\n"
|
||||
" Fred() : a({1,2}) {\n"
|
||||
" for (int i=0;i<6;i++);\n" // <- no syntax error
|
||||
" }\n"
|
||||
"private:\n"
|
||||
" A a;\n"
|
||||
"};\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void template_member_ptr() { // Ticket #5786
|
||||
tok("struct A {}; "
|
||||
"struct B { "
|
||||
"template <void (A::*)() const> struct BB {}; "
|
||||
"template <bool BT> static bool foo(int) { return true; } "
|
||||
"void bar() { bool b = foo<true>(0); }"
|
||||
"};");
|
||||
tok("struct A {}; "
|
||||
"struct B { "
|
||||
"template <void (A::*)() volatile> struct BB {}; "
|
||||
"template <bool BT> static bool foo(int) { return true; } "
|
||||
"void bar() { bool b = foo<true>(0); }"
|
||||
"};");
|
||||
tok("struct A {}; "
|
||||
"struct B { "
|
||||
"template <void (A::*)() const volatile> struct BB {}; "
|
||||
"template <bool BT> static bool foo(int) { return true; } "
|
||||
"void bar() { bool b = foo<true>(0); }"
|
||||
"};");
|
||||
tok("struct A {}; "
|
||||
"struct B { "
|
||||
"template <void (A::*)() volatile const> struct BB {}; "
|
||||
"template <bool BT> static bool foo(int) { return true; } "
|
||||
"void bar() { bool b = foo<true>(0); }"
|
||||
"};");
|
||||
}
|
||||
|
||||
|
||||
unsigned int templateParameters(const char code[]) {
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
|
||||
|
|
|
@ -287,11 +287,6 @@ private:
|
|||
TEST_CASE(vardecl_par2); // #3912 - set correct links
|
||||
TEST_CASE(vardecl_par3); // #6556 - Fred x1(a), x2(b);
|
||||
TEST_CASE(volatile_variables);
|
||||
TEST_CASE(syntax_error);
|
||||
TEST_CASE(syntax_error_templates_1);
|
||||
TEST_CASE(syntax_error_templates_2);
|
||||
TEST_CASE(syntax_error_templates_3); // Ticket #5605, #5759, #5762, #5774
|
||||
TEST_CASE(template_member_ptr); // Ticket #5786 - crash upon valid code
|
||||
|
||||
// unsigned i; => unsigned int i;
|
||||
TEST_CASE(unsigned1);
|
||||
|
@ -3996,244 +3991,6 @@ private:
|
|||
ASSERT_EQUALS("int a ; a = 0 ;\nint b ; b = 0 ;\nint c ; c = 0 ;", actual);
|
||||
}
|
||||
|
||||
void syntax_error() {
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "void f() {}";
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_EQUALS(true, tokenizer.tokenize(istr, "test.cpp"));
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "void f() {{}";
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_THROW(tokenizer.tokenize(istr, "test.cpp"), InternalError);
|
||||
}
|
||||
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "void f()) {}";
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_THROW(tokenizer.tokenize(istr, "test.cpp"), InternalError);
|
||||
}
|
||||
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "namespace extract{\nB(weighted_moment)\n}\nusing extract::weighted_moment;\n";
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_EQUALS(true, tokenizer.tokenize(istr, "test.cpp"));
|
||||
tokenizer.simplifyTokenList2();
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "void f()\n"
|
||||
"{\n"
|
||||
" foo(;\n"
|
||||
"}\n";
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_THROW(tokenizer.tokenize(istr, "test.cpp", "ABC"), InternalError);
|
||||
}
|
||||
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "void f()\n"
|
||||
"{\n"
|
||||
" for(;;){ foo();\n"
|
||||
"}\n";
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_THROW(tokenizer.tokenize(istr, "test.cpp"), InternalError);
|
||||
}
|
||||
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "void f()\n"
|
||||
"{\n"
|
||||
" a[10;\n"
|
||||
"}\n";
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
std::istringstream istr(code);
|
||||
ASSERT_THROW(tokenizer.tokenize(istr, "test.cpp"), InternalError);
|
||||
}
|
||||
|
||||
{
|
||||
errout.str("");
|
||||
const char code[] = "{\n"
|
||||
" a(\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
" b());\n"
|
||||
"}\n";
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
std::istringstream istr(code);
|
||||
try {
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
assertThrowFail(__FILE__, __LINE__);
|
||||
} catch (InternalError& e) {
|
||||
ASSERT_EQUALS("Invalid number of character '(' when these macros are defined: ''.", e.errorMessage);
|
||||
ASSERT_EQUALS("syntaxError", e.id);
|
||||
ASSERT_EQUALS(2, e.token->linenr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void syntax_error_templates_1() {
|
||||
// ok code.. using ">" for a comparison
|
||||
{
|
||||
errout.str("");
|
||||
std::istringstream istr("x<y>z> xyz;\n");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
// ok code..
|
||||
{
|
||||
errout.str("");
|
||||
std::istringstream istr("template<class T> operator<(T a, T b) { }\n");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
// ok code (ticket #1984)..
|
||||
{
|
||||
errout.str("");
|
||||
std::istringstream istr("void f(a) int a;\n"
|
||||
"{ ;x<y; }");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
// ok code (ticket #1985)..
|
||||
{
|
||||
errout.str("");
|
||||
std::istringstream istr("void f()\n"
|
||||
"try { ;x<y; }");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
// ok code (ticket #3183)
|
||||
{
|
||||
errout.str();
|
||||
std::istringstream istr("MACRO(({ i < x }))");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
// bad code.. missing ">"
|
||||
{
|
||||
errout.str("");
|
||||
std::istringstream istr("x<y<int> xyz;\n");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
ASSERT_THROW(tokenizer.tokenize(istr, "test.cpp"), InternalError);
|
||||
}
|
||||
|
||||
// bad code
|
||||
{
|
||||
errout.str("");
|
||||
std::istringstream istr("typedef\n"
|
||||
" typename boost::mpl::if_c<\n"
|
||||
" _visitableIndex < boost::mpl::size< typename _Visitables::ConcreteVisitables >::value\n"
|
||||
" , ConcreteVisitable\n"
|
||||
" , Dummy< _visitableIndex >\n"
|
||||
" >::type ConcreteVisitableOrDummy;\n");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
ASSERT_THROW(tokenizer.tokenize(istr, "test.cpp"), InternalError);
|
||||
}
|
||||
|
||||
// code is ok, don't show syntax error
|
||||
{
|
||||
errout.str("");
|
||||
std::istringstream istr("struct A {int a;int b};\n"
|
||||
"class Fred {"
|
||||
"public:\n"
|
||||
" Fred() : a({1,2}) {\n"
|
||||
" for (int i=0;i<6;i++);\n" // <- no syntax error
|
||||
" }\n"
|
||||
"private:\n"
|
||||
" A a;\n"
|
||||
"};\n");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
void syntax_error_templates_2() {
|
||||
std::istringstream istr("template<>\n");
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
tokenizer.tokenize(istr, "test.cpp"); // shouldn't segfault
|
||||
}
|
||||
|
||||
void syntax_error_templates_3() { // Ticket #5605, #5759, #5762, #5774, #5823, #6059
|
||||
tokenizeAndStringify("foo() template<typename T1 = T2 = typename = unused, T5 = = unused> struct tuple Args> tuple<Args...> { } main() { foo<int,int,int,int,int,int>(); }");
|
||||
tokenizeAndStringify("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }");
|
||||
tokenizeAndStringify("() template < T = typename = x > struct a {} { f <int> () }");
|
||||
tokenizeAndStringify("template < T = typename = > struct a { f <int> }");
|
||||
tokenizeAndStringify("struct S { int i, j; }; "
|
||||
"template<int S::*p, typename U> struct X {}; "
|
||||
"X<&S::i, int> x = X<&S::i, int>(); "
|
||||
"X<&S::j, int> y = X<&S::j, int>(); ");
|
||||
tokenizeAndStringify("template <typename T> struct A {}; "
|
||||
"template <> struct A<void> {}; "
|
||||
"void foo(const void* f = 0) {}");
|
||||
tokenizeAndStringify("template<typename... T> struct A { "
|
||||
" static const int s = 0; "
|
||||
"}; "
|
||||
"A<int> a;");
|
||||
tokenizeAndStringify("template<class T, class U> class A {}; "
|
||||
"template<class T = A<int, int> > class B {}; "
|
||||
"template<class T = B<int> > class C { "
|
||||
" C() : _a(0), _b(0) {} "
|
||||
" int _a, _b; "
|
||||
"};");
|
||||
tokenizeAndStringify("template<class... T> struct A { "
|
||||
" static int i; "
|
||||
"}; "
|
||||
"void f() { A<int>::i = 0; }");
|
||||
}
|
||||
|
||||
void template_member_ptr() { // Ticket #5786
|
||||
tokenizeAndStringify("struct A {}; "
|
||||
"struct B { "
|
||||
"template <void (A::*)() const> struct BB {}; "
|
||||
"template <bool BT> static bool foo(int) { return true; } "
|
||||
"void bar() { bool b = foo<true>(0); }"
|
||||
"};");
|
||||
tokenizeAndStringify("struct A {}; "
|
||||
"struct B { "
|
||||
"template <void (A::*)() volatile> struct BB {}; "
|
||||
"template <bool BT> static bool foo(int) { return true; } "
|
||||
"void bar() { bool b = foo<true>(0); }"
|
||||
"};");
|
||||
tokenizeAndStringify("struct A {}; "
|
||||
"struct B { "
|
||||
"template <void (A::*)() const volatile> struct BB {}; "
|
||||
"template <bool BT> static bool foo(int) { return true; } "
|
||||
"void bar() { bool b = foo<true>(0); }"
|
||||
"};");
|
||||
tokenizeAndStringify("struct A {}; "
|
||||
"struct B { "
|
||||
"template <void (A::*)() volatile const> struct BB {}; "
|
||||
"template <bool BT> static bool foo(int) { return true; } "
|
||||
"void bar() { bool b = foo<true>(0); }"
|
||||
"};");
|
||||
}
|
||||
|
||||
void simplifyKeyword() {
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue