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 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() { void executionPaths1() {
epcheck("void f(int a)\n" check("void f(int a)\n"
"{\n" "{\n"
" int buf[10];\n" " int buf[10];\n"
" int i = 5;\n" " int i = 5;\n"
" if (a == 1)\n" " if (a == 1)\n"
" i = 1000;\n" " i = 1000;\n"
" buf[i] = 0;\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()); 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" check("void f(int a)\n"
"{\n" "{\n"
" int buf[10][5];\n" " int buf[10][5];\n"
" int i = 5;\n" " int i = 5;\n"
" if (a == 1)\n" " if (a == 1)\n"
" i = 1000;\n" " i = 1000;\n"
" buf[i][0] = 0;\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()); ASSERT_EQUALS("[test.cpp:7]: (error) Array 'buf[10][5]' index buf[1000][0] out of bounds.\n", errout.str());
} }
void executionPaths2() { void executionPaths2() {
epcheck("void foo()\n" check("void foo()\n"
"{\n" "{\n"
" char a[64];\n" " char a[64];\n"
" int sz = sizeof(a);\n" " int sz = sizeof(a);\n"
" bar(&sz);\n" " bar(&sz);\n"
" a[sz] = 0;\n" " a[sz] = 0;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void executionPaths3() { void executionPaths3() {
epcheck("void f(char *VLtext)\n" check("void f(char *VLtext)\n"
"{\n" "{\n"
" if ( x ) {\n" " if ( x ) {\n"
" return VLtext[0];\n" " return VLtext[0];\n"
" } else {\n" " } else {\n"
" int wordlen = ab();\n" " int wordlen = ab();\n"
" VLtext[wordlen] = 0;\n" " VLtext[wordlen] = 0;\n"
" }\n" " }\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void executionPaths5() { void executionPaths5() {
// No false positive // No false positive
epcheck("class A {\n" check("class A {\n"
" void foo() {\n" " void foo() {\n"
" int j = g();\n" " int j = g();\n"
" arr[j]=0;\n" " arr[j]=0;\n"
" }\n" " }\n"
"\n" "\n"
" int arr[2*BSize + 2];\n" " int arr[2*BSize + 2];\n"
"};"); "};");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -3510,7 +3495,7 @@ private:
" if (x) { i = 1000; }\n" " if (x) { i = 1000; }\n"
" a[i] = 0;\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()); 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(); tokenizer.simplifyTokenList2();
checkCondition.runSimplifiedChecks(&tokenizer, &settings1, this); checkCondition.runSimplifiedChecks(&tokenizer, &settings1, this);
} }
void duplicateIf() { void duplicateIf() {
check("void f(int a, int &b) {\n" check("void f(int a, int &b) {\n"
" if (a) { b = 1; }\n" " if (a) { b = 1; }\n"

View File

@ -184,6 +184,7 @@ private:
TEST_CASE(garbageCode132); // #7022 TEST_CASE(garbageCode132); // #7022
TEST_CASE(garbageCode133); TEST_CASE(garbageCode133);
TEST_CASE(garbageCode134); TEST_CASE(garbageCode134);
TEST_CASE(garbageCode135); // #4994
TEST_CASE(garbageValueFlow); TEST_CASE(garbageValueFlow);
TEST_CASE(garbageSymbolDatabase); TEST_CASE(garbageSymbolDatabase);
@ -1064,6 +1065,14 @@ private:
"void f() { A<int>::i = 0; }"); "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() { void garbageValueFlow() {
// #6089 // #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() { void elseif1() {
const char code[] = "else if(ab) { cd } else { ef }gh"; 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 // 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" 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 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"; 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 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"; 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 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"; 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[]) { unsigned int sizeofFromTokenizer(const char type[]) {
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
std::istringstream istr(""); tokenizer.fillTypeSizes();
tokenizer.tokenize(istr, "test.cpp");
Token tok1(0); Token tok1(0);
tok1.str(type); tok1.str(type);
return tokenizer.sizeOfType(&tok1); return tokenizer.sizeOfType(&tok1);

View File

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

View File

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