Refactorization: Reduced code duplication in test suite

This commit is contained in:
PKEuS 2015-10-08 11:35:51 +02:00
parent ab89e85ce5
commit 0a34b206e8
7 changed files with 571 additions and 743 deletions

View File

@ -3428,78 +3428,63 @@ private:
"void d() { struct b *f; f = malloc(108); }");
}
void epcheck(const char code[], const char filename[] = "test.cpp") {
// Clear the error buffer..
errout.str("");
// Tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, filename);
tokenizer.simplifyTokenList2();
// Check for buffer overruns..
CheckBufferOverrun checkBufferOverrun(&tokenizer, &settings0, this);
checkBufferOverrun.bufferOverrun();
}
void executionPaths1() {
epcheck("void f(int a)\n"
"{\n"
" int buf[10];\n"
" int i = 5;\n"
" if (a == 1)\n"
" i = 1000;\n"
" buf[i] = 0;\n"
"}");
check("void f(int a)\n"
"{\n"
" int buf[10];\n"
" int i = 5;\n"
" if (a == 1)\n"
" i = 1000;\n"
" buf[i] = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Array 'buf[10]' accessed at index 1000, which is out of bounds.\n", errout.str());
epcheck("void f(int a)\n"
"{\n"
" int buf[10][5];\n"
" int i = 5;\n"
" if (a == 1)\n"
" i = 1000;\n"
" buf[i][0] = 0;\n"
"}");
check("void f(int a)\n"
"{\n"
" int buf[10][5];\n"
" int i = 5;\n"
" if (a == 1)\n"
" i = 1000;\n"
" buf[i][0] = 0;\n"
"}");
ASSERT_EQUALS("[test.cpp:7]: (error) Array 'buf[10][5]' index buf[1000][0] out of bounds.\n", errout.str());
}
void executionPaths2() {
epcheck("void foo()\n"
"{\n"
" char a[64];\n"
" int sz = sizeof(a);\n"
" bar(&sz);\n"
" a[sz] = 0;\n"
"}");
check("void foo()\n"
"{\n"
" char a[64];\n"
" int sz = sizeof(a);\n"
" bar(&sz);\n"
" a[sz] = 0;\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void executionPaths3() {
epcheck("void f(char *VLtext)\n"
"{\n"
" if ( x ) {\n"
" return VLtext[0];\n"
" } else {\n"
" int wordlen = ab();\n"
" VLtext[wordlen] = 0;\n"
" }\n"
"}");
check("void f(char *VLtext)\n"
"{\n"
" if ( x ) {\n"
" return VLtext[0];\n"
" } else {\n"
" int wordlen = ab();\n"
" VLtext[wordlen] = 0;\n"
" }\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void executionPaths5() {
// No false positive
epcheck("class A {\n"
" void foo() {\n"
" int j = g();\n"
" arr[j]=0;\n"
" }\n"
"\n"
" int arr[2*BSize + 2];\n"
"};");
check("class A {\n"
" void foo() {\n"
" int j = g();\n"
" arr[j]=0;\n"
" }\n"
"\n"
" int arr[2*BSize + 2];\n"
"};");
ASSERT_EQUALS("", errout.str());
}
@ -3510,7 +3495,7 @@ private:
" if (x) { i = 1000; }\n"
" a[i] = 0;\n"
"}";
epcheck(code);
check(code);
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'a[10]' accessed at index 1000, which is out of bounds.\n", errout.str());
}

View File

@ -375,6 +375,7 @@ private:
tokenizer.simplifyTokenList2();
checkCondition.runSimplifiedChecks(&tokenizer, &settings1, this);
}
void duplicateIf() {
check("void f(int a, int &b) {\n"
" if (a) { b = 1; }\n"

View File

@ -184,6 +184,7 @@ private:
TEST_CASE(garbageCode132); // #7022
TEST_CASE(garbageCode133);
TEST_CASE(garbageCode134);
TEST_CASE(garbageCode135); // #4994
TEST_CASE(garbageValueFlow);
TEST_CASE(garbageSymbolDatabase);
@ -1064,6 +1065,14 @@ private:
"void f() { A<int>::i = 0; }");
}
void garbageCode135() { // #4994
checkCode("long f () {\n"
" return a >> extern\n"
"}\n"
"long a = 1 ;\n"
"long b = 2 ;");
}
void garbageValueFlow() {
// #6089

File diff suppressed because it is too large Load Diff

View File

@ -782,21 +782,12 @@ private:
}
}
std::string elseif(const char code[]) {
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.elseif();
return tokenizer.tokens()->stringifyList(false);
}
void elseif1() {
const char code[] = "else if(ab) { cd } else { ef }gh";
ASSERT_EQUALS("\n\n##file 0\n1: else { if ( ab ) { cd } else { ef } } gh\n", elseif(code));
ASSERT_EQUALS("\n\n##file 0\n1: else { if ( ab ) { cd } else { ef } } gh\n", tokenizeDebugListing(code));
// syntax error: assert there is no segmentation fault
ASSERT_EQUALS("\n\n##file 0\n1: else if ( x ) { }\n", elseif("else if (x) { }"));
ASSERT_EQUALS("\n\n##file 0\n1: else if ( x ) { }\n", tokenizeDebugListing("else if (x) { }"));
{
const char src[] = "void f(int g,int f) {\n"
@ -832,25 +823,24 @@ private:
{
const char src[] = "( []{if (ab) {cd}else if(ef) { gh } else { ij }kl}() )";
const char expected[] = "\n\n##file 0\n1: ( [ ] { if ( ab ) { cd } else { if ( ef ) { gh } else { ij } } kl } ( ) )\n";
ASSERT_EQUALS(expected, elseif(src));
ASSERT_EQUALS(expected, tokenizeDebugListing(src));
}
{
const char src[] = "[ []{if (ab) {cd}else if(ef) { gh } else { ij }kl}() ]";
const char expected[] = "\n\n##file 0\n1: [ [ ] { if ( ab ) { cd } else { if ( ef ) { gh } else { ij } } kl } ( ) ]\n";
ASSERT_EQUALS(expected, elseif(src));
ASSERT_EQUALS(expected, tokenizeDebugListing(src));
}
{
const char src[] = "= { []{if (ab) {cd}else if(ef) { gh } else { ij }kl}() }";
const char expected[] = "\n\n##file 0\n1: = { [ ] { if ( ab ) { cd } else { if ( ef ) { gh } else { ij } } kl } ( ) }\n";
ASSERT_EQUALS(expected, elseif(src));
ASSERT_EQUALS(expected, tokenizeDebugListing(src));
}
}
unsigned int sizeofFromTokenizer(const char type[]) {
Tokenizer tokenizer(&settings0, this);
std::istringstream istr("");
tokenizer.tokenize(istr, "test.cpp");
tokenizer.fillTypeSizes();
Token tok1(0);
tok1.str(type);
return tokenizer.sizeOfType(&tok1);

View File

@ -541,17 +541,7 @@ private:
void simplifyTypedef18() {
const char code[] = "typedef vector<int[4]> a;\n"
"a b;";
// Clear the error buffer..
errout.str("");
Tokenizer tokenizer(&settings1, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList2();
tokenizer.validate();
ASSERT_EQUALS("vector < int [ 4 ] > b ;", tok(code));
}
void simplifyTypedef19() {
@ -603,17 +593,7 @@ private:
void simplifyTypedef20() {
// ticket #1284
const char code[] = "typedef jobject invoke_t (jobject, Proxy *, Method *, JArray< jobject > *);";
// Clear the error buffer..
errout.str("");
Tokenizer tokenizer(&settings1, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList2();
tokenizer.validate();
ASSERT_EQUALS(";", tok(code));
}
void simplifyTypedef21() {

View File

@ -880,16 +880,7 @@ private:
void longtok() {
const std::string filedata(10000, 'a');
errout.str("");
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(filedata);
tokenizer.tokenize(istr, "test.cpp");
// Expected result..
ASSERT_EQUALS(filedata, tokenizer.tokens()->str());
ASSERT_EQUALS(filedata, tokenizeAndStringify(filedata.c_str(), true));
}
@ -897,33 +888,13 @@ private:
// Dont remove "(int *)"..
void removeCast1() {
const char code[] = "int *f(int *);";
errout.str("");
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyCasts();
ASSERT_EQUALS("int * f ( int * ) ;", tokenizer.tokens()->stringifyList(0, false));
ASSERT_EQUALS("int * f ( int * ) ;", tokenizeAndStringify(code, true));
}
// remove static_cast..
void removeCast2() {
const char code[] = "t = (static_cast<std::vector<int> *>(&p));\n";
errout.str("");
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyCasts();
ASSERT_EQUALS("t = ( & p ) ;", tokenizer.tokens()->stringifyList(0, false));
ASSERT_EQUALS("t = & p ;", tokenizeAndStringify(code, true));
}
void removeCast3() {
@ -3609,21 +3580,13 @@ private:
void vardecl_par() {
// ticket #2743 - set links if variable type contains parentheses
const char code[] = "Fred<int(*)()> fred1=a, fred2=b;";
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.validate();
ASSERT_EQUALS("Fred < int ( * ) ( ) > fred1 ; fred1 = a ; Fred < int ( * ) ( ) > fred2 ; fred2 = b ;", tokenizeAndStringify(code));
}
void vardecl_par2() {
// ticket #3912 - set correct links
const char code[] = "function<void (shared_ptr<MyClass>)> v;";
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.validate();
ASSERT_EQUALS("function < void ( shared_ptr < MyClass > ) > v ;", tokenizeAndStringify(code));
}
void vardecl_par3() {
@ -4819,64 +4782,41 @@ private:
"decltype(auto) forward(T& t) { return 0; }");
}
std::string arraySize_(const std::string &code) {
errout.str("");
// tokenize..
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
std::ostringstream ostr;
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->isName() && tok->previous())
ostr << " ";
ostr << tok->str();
}
return ostr.str();
}
void arraySize() {
ASSERT_EQUALS("; int a[3]={1,2,3};", arraySize_(";int a[]={1,2,3};"));
ASSERT_EQUALS("; int a[3]={1,2,3};", arraySize_(";int a[]={1,2,3,};"));
ASSERT_EQUALS("; foo a[3]={{1,2},{3,4},{5,6}};", arraySize_(";foo a[]={{1,2},{3,4},{5,6}};"));
TODO_ASSERT_EQUALS("; int a[1]={ foo< bar1, bar2>(123,4)};", "; int a[]={ foo< bar1, bar2>(123,4)};", arraySize_(";int a[]={foo<bar1,bar2>(123,4)};"));
ASSERT_EQUALS("; int a[2]={ b> c?1:2,3};", arraySize_(";int a[]={ b>c?1:2,3};"));
TODO_ASSERT_EQUALS("int main(){ int a[2]={ b< c?1:2,3}}", "int main(){ int a[]={ b< c?1:2,3}}", arraySize_("int main(){int a[]={b<c?1:2,3}}"));
ASSERT_EQUALS("; int a[3]={ ABC,2,3};", arraySize_(";int a[]={ABC,2,3};"));
ASSERT_EQUALS("; int a[3]={[2]=5};", arraySize_(";int a[]={ [2] = 5 };"));
ASSERT_EQUALS("; int a[5]={1,2,[2]=5,3,4};", arraySize_(";int a[]={ 1, 2, [2] = 5, 3, 4 };"));
ASSERT_EQUALS("; int a[]={1,2,[ x]=5,3,4};", arraySize_(";int a[]={ 1, 2, [x] = 5, 3, 4 };"));
}
std::string labels_(const std::string &code) {
// the arraySize_ does what we want currently..
return arraySize_(code);
ASSERT_EQUALS("; int a [ 3 ] = { 1 , 2 , 3 } ;", tokenizeAndStringify(";int a[]={1,2,3};"));
ASSERT_EQUALS("; int a [ 3 ] = { 1 , 2 , 3 } ;", tokenizeAndStringify(";int a[]={1,2,3,};"));
ASSERT_EQUALS("; foo a [ 3 ] = { { 1 , 2 } , { 3 , 4 } , { 5 , 6 } } ;", tokenizeAndStringify(";foo a[]={{1,2},{3,4},{5,6}};"));
TODO_ASSERT_EQUALS("; int a [ 1 ] = { foo < bar1 , bar2 > ( 123 , 4 ) } ;", "; int a [ ] = { foo < bar1 , bar2 > ( 123 , 4 ) } ;", tokenizeAndStringify(";int a[]={foo<bar1,bar2>(123,4)};"));
ASSERT_EQUALS("; int a [ 2 ] = { b > c ? 1 : 2 , 3 } ;", tokenizeAndStringify(";int a[]={ b>c?1:2,3};"));
TODO_ASSERT_EQUALS("int main ( ) { int a [ 2 ] = { b < c ? 1 : 2 , 3 } }", "int main ( ) { int a [ ] = { b < c ? 1 : 2 , 3 } }", tokenizeAndStringify("int main(){int a[]={b<c?1:2,3}}"));
ASSERT_EQUALS("; int a [ 3 ] = { ABC , 2 , 3 } ;", tokenizeAndStringify(";int a[]={ABC,2,3};"));
ASSERT_EQUALS("; int a [ 3 ] = { [ 2 ] = 5 } ;", tokenizeAndStringify(";int a[]={ [2] = 5 };"));
ASSERT_EQUALS("; int a [ 5 ] = { 1 , 2 , [ 2 ] = 5 , 3 , 4 } ;", tokenizeAndStringify(";int a[]={ 1, 2, [2] = 5, 3, 4 };"));
ASSERT_EQUALS("; int a [ ] = { 1 , 2 , [ x ] = 5 , 3 , 4 } ;", tokenizeAndStringify(";int a[]={ 1, 2, [x] = 5, 3, 4 };"));
}
void labels() {
ASSERT_EQUALS("void f(){ ab:; a=0;}", labels_("void f() { ab: a=0; }"));
ASSERT_EQUALS("void f ( ) { ab : ; a = 0 ; }", tokenizeAndStringify("void f() { ab: a=0; }"));
//ticket #3176
ASSERT_EQUALS("void f(){ ab:;(* func)();}", labels_("void f() { ab: (*func)(); }"));
ASSERT_EQUALS("void f ( ) { ab : ; ( * func ) ( ) ; }", tokenizeAndStringify("void f() { ab: (*func)(); }"));
//with '*' operator
ASSERT_EQUALS("void f(){ ab:;* b=0;}", labels_("void f() { ab: *b=0; }"));
ASSERT_EQUALS("void f(){ ab:;** b=0;}", labels_("void f() { ab: **b=0; }"));
ASSERT_EQUALS("void f ( ) { ab : ; * b = 0 ; }", tokenizeAndStringify("void f() { ab: *b=0; }"));
ASSERT_EQUALS("void f ( ) { ab : ; * * b = 0 ; }", tokenizeAndStringify("void f() { ab: **b=0; }"));
//with '&' operator
ASSERT_EQUALS("void f(){ ab:;& b=0;}", labels_("void f() { ab: &b=0; }"));
ASSERT_EQUALS("void f(){ ab:;&( b. x)=0;}", labels_("void f() { ab: &(b->x)=0; }"));
ASSERT_EQUALS("void f ( ) { ab : ; & b = 0 ; }", tokenizeAndStringify("void f() { ab: &b=0; }"));
ASSERT_EQUALS("void f ( ) { ab : ; & ( b . x ) = 0 ; }", tokenizeAndStringify("void f() { ab: &(b->x)=0; }"));
//with '(' parentheses
ASSERT_EQUALS("void f(){ ab:;*(* b). x=0;}", labels_("void f() { ab: *(* b)->x=0; }"));
ASSERT_EQUALS("void f(){ ab:;(** b). x=0;}", labels_("void f() { ab: (** b).x=0; }"));
ASSERT_EQUALS("void f(){ ab:;&(* b. x)=0;}", labels_("void f() { ab: &(*b.x)=0; }"));
ASSERT_EQUALS("void f ( ) { ab : ; * ( * b ) . x = 0 ; }", tokenizeAndStringify("void f() { ab: *(* b)->x=0; }"));
ASSERT_EQUALS("void f ( ) { ab : ; ( * * b ) . x = 0 ; }", tokenizeAndStringify("void f() { ab: (** b).x=0; }"));
ASSERT_EQUALS("void f ( ) { ab : ; & ( * b . x ) = 0 ; }", tokenizeAndStringify("void f() { ab: &(*b.x)=0; }"));
//with '{' parentheses
ASSERT_EQUALS("void f(){ ab:;{ b=0;}}", labels_("void f() { ab: {b=0;} }"));
ASSERT_EQUALS("void f(){ ab:;{* b=0;}}", labels_("void f() { ab: { *b=0;} }"));
ASSERT_EQUALS("void f(){ ab:;{& b=0;}}", labels_("void f() { ab: { &b=0;} }"));
ASSERT_EQUALS("void f(){ ab:;{&(* b. x)=0;}}", labels_("void f() { ab: {&(*b.x)=0;} }"));
ASSERT_EQUALS("void f ( ) { ab : ; { b = 0 ; } }", tokenizeAndStringify("void f() { ab: {b=0;} }"));
ASSERT_EQUALS("void f ( ) { ab : ; { * b = 0 ; } }", tokenizeAndStringify("void f() { ab: { *b=0;} }"));
ASSERT_EQUALS("void f ( ) { ab : ; { & b = 0 ; } }", tokenizeAndStringify("void f() { ab: { &b=0;} }"));
ASSERT_EQUALS("void f ( ) { ab : ; { & ( * b . x ) = 0 ; } }", tokenizeAndStringify("void f() { ab: {&(*b.x)=0;} }"));
//with unhandled MACRO() code
ASSERT_EQUALS("void f(){ MACRO( ab: b=0;, foo)}", labels_("void f() { MACRO(ab: b=0;, foo)}"));
ASSERT_EQUALS("void f(){ MACRO( bar, ab:{&(* b. x)=0;})}", labels_("void f() { MACRO(bar, ab: {&(*b.x)=0;})}"));
ASSERT_EQUALS("void f ( ) { MACRO ( ab : b = 0 ; , foo ) }", tokenizeAndStringify("void f() { MACRO(ab: b=0;, foo)}"));
ASSERT_EQUALS("void f ( ) { MACRO ( bar , ab : { & ( * b . x ) = 0 ; } ) }", tokenizeAndStringify("void f() { MACRO(bar, ab: {&(*b.x)=0;})}"));
}
void simplifyInitVar() {