Extended std.cfg

This commit is contained in:
Martin Ettl 2014-03-19 21:08:48 +01:00 committed by Daniel Marjamäki
parent 5c88934431
commit fe1b46c174
4 changed files with 219 additions and 23 deletions

View File

@ -15,10 +15,20 @@
<alloc init="true">fopen</alloc> <alloc init="true">fopen</alloc>
</resource> </resource>
<function name="fopen"> <noreturn>false</noreturn> </function> <function name="fopen"> <noreturn>false</noreturn> <arg nr="1"><not-null/><not-uninit/></arg><arg nr="2"><not-null/><not-uninit/></arg></function>
<function name="fclose"> <noreturn>false</noreturn> </function> <function name="fclose"> <noreturn>false</noreturn> <arg nr="1"><not-null/><not-uninit/></arg></function>
<function name="fflush"> <noreturn>false</noreturn> <leak-ignore/> </function> <function name="fflush"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><not-uninit/></arg></function>
<function name="fgetc"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg></function>
<function name="fgetpos"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg><arg nr="2"><not-null/><not-uninit/></arg></function>
<function name="fgets">
<noreturn>false</noreturn>
<leak-ignore/>
<arg nr="1"><not-null/></arg>
<arg nr="2"><not-uninit/><not-bool/><valid>0-</valid></arg>
<arg nr="3"><not-null/><not-uninit/></arg>
</function>
<function name="fsetpos"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg><arg nr="2"><not-null/><not-uninit/></arg></function>
<function name="isalnum"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><valid>0-255</valid></arg> </function> <function name="isalnum"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><valid>0-255</valid></arg> </function>
<function name="isalpha"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><valid>0-255</valid></arg> </function> <function name="isalpha"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><valid>0-255</valid></arg> </function>
<function name="isblank"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><valid>0-255</valid></arg> </function> <function name="isblank"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><valid>0-255</valid></arg> </function>
@ -54,7 +64,7 @@
<function name="strerror"> <noreturn>false</noreturn> <leak-ignore/></function> <function name="strerror"> <noreturn>false</noreturn> <leak-ignore/></function>
<function name="strcspn"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="2"><not-null/><not-uninit/></arg> </function> <function name="strcspn"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="2"><not-null/><not-uninit/></arg> </function>
<function name="strcoll"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="2"><not-null/><not-uninit/></arg> </function> <function name="strcoll"> <noreturn>false</noreturn> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="2"><not-null/><not-uninit/></arg> </function>
<function name="strtol"> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="3"><valid>0,2-36</valid></arg> </function> <function name="strtol"> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="3"><valid>0,2-36</valid></arg> </function>
<function name="strtoll"> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="3"><valid>0,2-36</valid></arg> </function> <function name="strtoll"> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="3"><valid>0,2-36</valid></arg> </function>
<function name="strtoul"> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="3"><valid>0,2-36</valid></arg> </function> <function name="strtoul"> <leak-ignore/> <arg nr="1"><not-null/><not-uninit/></arg> <arg nr="3"><valid>0,2-36</valid></arg> </function>
@ -64,6 +74,10 @@
<function name="wcstoul"> <leak-ignore/> <arg nr="3"><valid>0,2-36</valid></arg> </function> <function name="wcstoul"> <leak-ignore/> <arg nr="3"><valid>0,2-36</valid></arg> </function>
<function name="wcstoull"> <leak-ignore/> <arg nr="3"><valid>0,2-36</valid></arg> </function> <function name="wcstoull"> <leak-ignore/> <arg nr="3"><valid>0,2-36</valid></arg> </function>
<function name="clearerr"> <noreturn>false</noreturn> <arg nr="1"><not-null/><not-uninit/></arg></function>
<function name="feof"> <noreturn>false</noreturn> <arg nr="1"><not-null/><not-uninit/></arg></function>
<function name="ferror"> <noreturn>false</noreturn> <arg nr="1"><not-null/><not-uninit/></arg></function>
<function name="printf"> <noreturn>false</noreturn> <formatstr/> <arg nr="1"><formatstr/></arg> <arg nr="any"><not-uninit/></arg> </function> <function name="printf"> <noreturn>false</noreturn> <formatstr/> <arg nr="1"><formatstr/></arg> <arg nr="any"><not-uninit/></arg> </function>
<function name="wprintf"> <noreturn>false</noreturn> <formatstr/> <arg nr="1"><formatstr/></arg> </function> <function name="wprintf"> <noreturn>false</noreturn> <formatstr/> <arg nr="1"><formatstr/></arg> </function>
<function name="sprintf"> <noreturn>false</noreturn> <formatstr/> <arg nr="2"><formatstr/></arg> </function> <function name="sprintf"> <noreturn>false</noreturn> <formatstr/> <arg nr="2"><formatstr/></arg> </function>

View File

@ -201,7 +201,7 @@ static const Signaltype listofsignals[] = {
}; };
/** /**
* Simple helper function: * Simple helper function:
* \return size of array * \return size of array
* */ * */
template<typename T, int size> template<typename T, int size>

View File

@ -2396,54 +2396,77 @@ private:
const char errpq[] = "[test.cpp:1] -> [test.cpp:1]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n" const char errpq[] = "[test.cpp:1] -> [test.cpp:1]: (warning) Possible null pointer dereference: p - otherwise it is redundant to check it against null.\n"
"[test.cpp:1] -> [test.cpp:1]: (warning) Possible null pointer dereference: q - otherwise it is redundant to check it against null.\n"; "[test.cpp:1] -> [test.cpp:1]: (warning) Possible null pointer dereference: q - otherwise it is redundant to check it against null.\n";
// str.. check("void f(FILE *p){ clearerr (p);if(!p){}}");
check("void f(char*p){ strchr (p,c);if(!p){}}");
ASSERT_EQUALS(errp,errout.str()); ASSERT_EQUALS(errp,errout.str());
check("void f(char*p){ strdup (p);if(!p){}}"); check("void f(FILE *p){ feof (p);if(!p){}}");
ASSERT_EQUALS(errp,errout.str()); ASSERT_EQUALS(errp,errout.str());
check("void f(char*p){ strlen (p);if(!p){}}"); check("void f(FILE *p){ fgetc (p);if(!p){}}");
ASSERT_EQUALS(errp,errout.str()); ASSERT_EQUALS(errp,errout.str());
check("void f(char*p,char*q){ strcpy (p,q);if(!p||!q){}}"); check("void f(FILE *p){ fclose (p);if(!p){}}");
ASSERT_EQUALS(errp,errout.str());
check("void f(FILE *p){ ferror (p);if(!p){}}");
ASSERT_EQUALS(errp,errout.str());
check("void f(char * p,char * q){ fopen (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strspn (p,q);if(!p||!q){}}"); check("void f(FILE * p,fpos_t * q){ fgetpos (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strcspn (p,q);if(!p||!q){}}"); check("void f(FILE * p,fpos_t * q){ fsetpos (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strcoll (p,q);if(!p||!q){}}"); check("void f(char * p){ strchr (p,c);if(!p){}}");
ASSERT_EQUALS(errp,errout.str());
check("void f(char * p){ strdup (p);if(!p){}}");
ASSERT_EQUALS(errp,errout.str());
check("void f(char * p){ strlen (p);if(!p){}}");
ASSERT_EQUALS(errp,errout.str());
check("void f(char * p,char * q){ strcpy (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strcat (p,q);if(!p||!q){}}"); check("void f(char * p,char * q){ strspn (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strcmp (p,q);if(!p||!q){}}"); check("void f(char * p,char * q){ strcspn (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strncpy (p,q,1);if(!p||!q){}}"); check("void f(char * p,char * q){ strcoll (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strncat (p,q,1);if(!p||!q){}}"); check("void f(char * p,char * q){ strcat (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strncmp (p,q,1);if(!p||!q){}}"); check("void f(char * p,char * q){ strcmp (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
check("void f(char*p,char*q){ strstr (p,q);if(!p||!q){}}"); check("void f(char * p,char * q){ strncpy (p,q,1);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str());
check("void f(char * p,char * q){ strncat (p,q,1);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str());
check("void f(char * p,char * q){ strncmp (p,q,1);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str());
check("void f(char * p,char * q){ strstr (p,q);if(!p||!q){}}");
ASSERT_EQUALS(errpq,errout.str()); ASSERT_EQUALS(errpq,errout.str());
// strtol etc // strtol etc
check("void f(char*p,char*q){ strtoul (p,q,0);if(!p){}}"); check("void f(char * p,char * q){ strtoul (p,q,0);if(!p){}}");
ASSERT_EQUALS(errp,errout.str()); ASSERT_EQUALS(errp,errout.str());
check("void f(char*p,char*q){ strtoull (p,q,0);if(!p){}}"); check("void f(char * p,char * q){ strtoull (p,q,0);if(!p){}}");
ASSERT_EQUALS(errp,errout.str()); ASSERT_EQUALS(errp,errout.str());
check("void f(char*p,char*q){ strtol (p,q,0);if(!p){}}"); check("void f(char * p,char * q){ strtol (p,q,0);if(!p){}}");
ASSERT_EQUALS(errp,errout.str()); ASSERT_EQUALS(errp,errout.str());
} }
}; };

View File

@ -67,6 +67,9 @@ private:
TEST_CASE(uninitvar2_malloc); // malloc returns uninitialized data TEST_CASE(uninitvar2_malloc); // malloc returns uninitialized data
TEST_CASE(syntax_error); // Ticket #5073 TEST_CASE(syntax_error); // Ticket #5073
// Test that std.cfg is configured correctly
TEST_CASE(stdcfg);
} }
void checkUninitVar(const char code[], const char filename[] = "test.cpp") { void checkUninitVar(const char code[], const char filename[] = "test.cpp") {
@ -3423,6 +3426,162 @@ private:
"}", "test.cpp", /*verify=*/true, /*debugwarnings=*/true); "}", "test.cpp", /*verify=*/true, /*debugwarnings=*/true);
ASSERT_EQUALS("[test.cpp:6]: (debug) assertion failed '} while ('\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (debug) assertion failed '} while ('\n", errout.str());
} }
// Test that std.cfg is configured correctly
void stdcfg() {
// clearerr
checkUninitVar("void f() {\n"
" FILE * pFile;\n"
" clearerr (pFile);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: pFile\n", errout.str());
checkUninitVar("void f(FILE * pFile) {\n"
" clearerr (pFile);\n"
"}");
ASSERT_EQUALS("", errout.str());
// fclose
checkUninitVar("void f() {\n"
" FILE * pFile;\n"
" fclose (pFile);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: pFile\n", errout.str());
checkUninitVar("void f(FILE * pFile) {\n"
" fclose (pFile);\n"
"}");
ASSERT_EQUALS("", errout.str());
// fopen
checkUninitVar("void f() {\n"
" char * filename;\n"
" fopen (filename, \"w\");\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: filename\n", errout.str());
checkUninitVar("void f() {\n"
" char * filename;\n"
" char * mode;\n"
" fopen (filename, mode);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: filename\n"
"[test.cpp:4]: (error) Uninitialized variable: mode\n", errout.str());
checkUninitVar("void f(FILE * name, char *mode) {\n"
" fopen (name, mode);\n"
"}");
ASSERT_EQUALS("", errout.str());
// feof
checkUninitVar("void f() {\n"
" FILE * pFile;\n"
" feof (pFile);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: pFile\n", errout.str());
checkUninitVar("void f(FILE * pFile) {\n"
" feof (pFile);\n"
"}");
ASSERT_EQUALS("", errout.str());
// ferror
checkUninitVar("void f() {\n"
" FILE * pFile;\n"
" ferror (pFile);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: pFile\n", errout.str());
checkUninitVar("void f(FILE * pFile) {\n"
" ferror (pFile);\n"
"}");
ASSERT_EQUALS("", errout.str());
// fflush
checkUninitVar("void f() {\n"
" FILE * pFile;\n"
" fflush (pFile);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: pFile\n", errout.str());
checkUninitVar("void f(FILE * pFile) {\n"
" fflush (pFile);\n"
"}");
ASSERT_EQUALS("", errout.str());
// fgetc
checkUninitVar("void f() {\n"
" FILE * pFile;\n"
" fgetc (pFile);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: pFile\n", errout.str());
checkUninitVar("void f(FILE * pFile) {\n"
" fgetc (pFile);\n"
"}");
ASSERT_EQUALS("", errout.str());
// fgetpos
checkUninitVar("void f() {\n"
" FILE * f;\n"
" fpos_t * p;\n"
" fgetpos (f, p);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: f\n"
"[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
checkUninitVar("void f(FILE * f) {\n"
" fpos_t p;"
" fgetpos (f, &p);\n"
"}");
ASSERT_EQUALS("", errout.str());
checkUninitVar("void f(FILE * f, fpos_t *p) {\n"
" fgetpos (f, p);\n"
"}");
ASSERT_EQUALS("", errout.str());
// fsetpos
checkUninitVar("void f() {\n"
" FILE * f;\n"
" fpos_t * p;\n"
" fsetpos (f, p);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: f\n"
"[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
checkUninitVar("void f(FILE * f) {\n"
" fpos_t *p;"
" fsetpos (f, p);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: p\n", errout.str());
checkUninitVar("void f(FILE * f, fpos_t *p) {\n"
" fsetpos (f, p);\n"
"}");
ASSERT_EQUALS("", errout.str());
// fgets
checkUninitVar("void f(FILE *f) {\n"
" char *s;\n"
" int n;\n"
" fgets (s, n, f);\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: n\n"
"[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
checkUninitVar("void f(char * s, int n) {\n"
" FILE *f;\n"
" fgets (s, n, f);\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: f\n","", errout.str());
checkUninitVar("void f(char * s, int n, FILE *f) {\n"
" fgets (s, n, f);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
}; };
REGISTER_TEST(TestUninitVar) REGISTER_TEST(TestUninitVar)