Moved a few tests out of testtokenize.cpp; refactorized them

This commit is contained in:
Philipp Kloke 2015-10-07 22:45:38 +02:00
parent be72b7413a
commit 4ac6623875
3 changed files with 150 additions and 243 deletions

View File

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

View File

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

View File

@ -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() {
{