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(garbageCode130); // #7021
|
||||||
TEST_CASE(garbageCode131); // #7023
|
TEST_CASE(garbageCode131); // #7023
|
||||||
TEST_CASE(garbageCode132); // #7022
|
TEST_CASE(garbageCode132); // #7022
|
||||||
|
TEST_CASE(garbageCode133);
|
||||||
|
TEST_CASE(garbageCode134);
|
||||||
|
|
||||||
TEST_CASE(garbageValueFlow);
|
TEST_CASE(garbageValueFlow);
|
||||||
TEST_CASE(garbageSymbolDatabase);
|
TEST_CASE(garbageSymbolDatabase);
|
||||||
|
@ -991,6 +993,77 @@ private:
|
||||||
checkCode("() () { } { () () ({}) i() } void i(void(*ptr) ()) { ptr(!) () }");
|
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() {
|
void garbageValueFlow() {
|
||||||
// #6089
|
// #6089
|
||||||
|
|
|
@ -94,6 +94,8 @@ private:
|
||||||
TEST_CASE(template_default_type);
|
TEST_CASE(template_default_type);
|
||||||
TEST_CASE(template_typename);
|
TEST_CASE(template_typename);
|
||||||
TEST_CASE(template_constructor); // #3152 - template constructor is removed
|
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 TemplateSimplifier::templateParameters
|
||||||
TEST_CASE(templateParameters);
|
TEST_CASE(templateParameters);
|
||||||
|
@ -1177,6 +1179,81 @@ private:
|
||||||
ASSERT_EQUALS("class Fred { template < class T > Fred ( T t ) { } }", tok(code2));
|
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[]) {
|
unsigned int templateParameters(const char code[]) {
|
||||||
Tokenizer tokenizer(&settings, this);
|
Tokenizer tokenizer(&settings, this);
|
||||||
|
|
||||||
|
|
|
@ -287,11 +287,6 @@ private:
|
||||||
TEST_CASE(vardecl_par2); // #3912 - set correct links
|
TEST_CASE(vardecl_par2); // #3912 - set correct links
|
||||||
TEST_CASE(vardecl_par3); // #6556 - Fred x1(a), x2(b);
|
TEST_CASE(vardecl_par3); // #6556 - Fred x1(a), x2(b);
|
||||||
TEST_CASE(volatile_variables);
|
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;
|
// unsigned i; => unsigned int i;
|
||||||
TEST_CASE(unsigned1);
|
TEST_CASE(unsigned1);
|
||||||
|
@ -3996,244 +3991,6 @@ private:
|
||||||
ASSERT_EQUALS("int a ; a = 0 ;\nint b ; b = 0 ;\nint c ; c = 0 ;", actual);
|
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() {
|
void simplifyKeyword() {
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue