CheckMemoryLeak: Cleanup the old memory leaks check
This commit is contained in:
parent
f118c22bb6
commit
3b328f9187
File diff suppressed because it is too large
Load Diff
|
@ -187,95 +187,16 @@ public:
|
|||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) override {
|
||||
CheckMemoryLeakInFunction checkMemoryLeak(tokenizer, settings, errorLogger);
|
||||
checkMemoryLeak.checkReallocUsage();
|
||||
// Commented out so we can evaluate if this checking can be removed.
|
||||
//checkMemoryLeak.check();
|
||||
}
|
||||
|
||||
/** @brief Unit testing : testing the white list */
|
||||
static bool test_white_list(const std::string &funcname, const Settings *settings, bool cpp);
|
||||
|
||||
/** @brief Perform checking */
|
||||
void check();
|
||||
|
||||
/**
|
||||
* Checking for a memory leak caused by improper realloc usage.
|
||||
*/
|
||||
void checkReallocUsage();
|
||||
|
||||
/**
|
||||
* Inspect a function call. the call_func and getcode are recursive
|
||||
* @param tok token where the function call occurs
|
||||
* @param callstack callstack
|
||||
* @param varid variable id to check
|
||||
* @param alloctype if memory is allocated, this indicates the type of allocation
|
||||
* @param dealloctype if memory is deallocated, this indicates the type of deallocation
|
||||
* @param allocpar if function allocates varid parameter
|
||||
* @param sz not used by call_func - see getcode
|
||||
* @return These are the possible return values:
|
||||
* - NULL : no significant code
|
||||
* - "recursive" : recursive function
|
||||
* - "alloc" : the function returns allocated memory
|
||||
* - "dealloc" : the function deallocates the variable
|
||||
* - "dealloc_"
|
||||
* - "use" : the variable is used (unknown usage of the variable => the checking bails out)
|
||||
* - "callfunc" : a function call with unknown side effects
|
||||
* - "&use"
|
||||
*/
|
||||
const char * call_func(const Token *tok, std::list<const Token *> callstack, const unsigned int varid, AllocType &alloctype, AllocType &dealloctype, bool &allocpar, unsigned int sz);
|
||||
|
||||
/**
|
||||
* Extract a new tokens list that is easier to parse than the "mTokenizer->tokens()", the
|
||||
* extracted tokens list describes how the given variable is used.
|
||||
* The getcode and call_func are recursive
|
||||
* @param tok start parse token
|
||||
* @param callstack callstack
|
||||
* @param varid variable id
|
||||
* @param alloctype keep track of what type of allocation is used
|
||||
* @param dealloctype keeps track of what type of deallocation is used
|
||||
* @param classmember should be set if the inspected function is a class member
|
||||
* @param sz size of type, used to check for mismatching size of allocation. for example "int *a;" => the sz is "sizeof(int)"
|
||||
* @return Newly allocated token array. Caller needs to release reserved
|
||||
* memory by calling TokenList::deleteTokens(returnValue);
|
||||
* Returned tokens:
|
||||
* - "alloc" : the variable is allocated
|
||||
* - "assign" : the variable is assigned a new value
|
||||
* - "break" : corresponds to "break"
|
||||
* - "callfunc" : a function call with unknown side effects
|
||||
* - "continue" : corresponds to "continue"
|
||||
* - "dealloc" : the variable is deallocated
|
||||
* - "goto" : corresponds to a "goto"
|
||||
* - "if" : there is an "if"
|
||||
* - "if(var)" : corresponds with "if ( var != 0 )"
|
||||
* - "if(!var)" : corresponds with "if ( var == 0 )"
|
||||
* - "ifv" : the variable is used in some way in a "if"
|
||||
* - "loop" : corresponds to either a "for" or a "while"
|
||||
* - "realloc" : the variable is reallocated
|
||||
* - "return" : corresponds to a "return"
|
||||
* - "use" : unknown usage -> bail out checking of this execution path
|
||||
* - "&use" : the address of the variable is taken
|
||||
* - "::use" : calling member function of class
|
||||
* - "use_" : content of variable is accessed (used to warn access after dealloc)
|
||||
*/
|
||||
Token *getcode(const Token *tok, std::list<const Token *> callstack, const unsigned int varid, AllocType &alloctype, AllocType &dealloctype, bool classmember, unsigned int sz);
|
||||
|
||||
/**
|
||||
* Simplify code e.g. by replacing empty "{ }" with ";"
|
||||
* @param tok first token. The tokens list can be modified.
|
||||
*/
|
||||
void simplifycode(Token *tok) const;
|
||||
|
||||
static const Token *findleak(const Token *tokens);
|
||||
|
||||
/**
|
||||
* Checking the variable varname
|
||||
* @param startTok start token
|
||||
* @param varname name of variable (for error messages)
|
||||
* @param varid variable id
|
||||
* @param classmember is the scope inside a class member function
|
||||
* @param sz size of type.. if the variable is a "int *" then sz should be "sizeof(int)"
|
||||
*/
|
||||
void checkScope(const Token *startTok, const std::string &varname, unsigned int varid, bool classmember, unsigned int sz);
|
||||
|
||||
private:
|
||||
/** Report all possible errors (for the --errorlist) */
|
||||
void getErrorMessages(ErrorLogger *e, const Settings *settings) const override {
|
||||
|
|
|
@ -149,7 +149,6 @@ private:
|
|||
// Check for memory leaks..
|
||||
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, settings, this);
|
||||
checkMemoryLeak.checkReallocUsage();
|
||||
checkMemoryLeak.check();
|
||||
}
|
||||
|
||||
|
||||
|
@ -158,18 +157,7 @@ private:
|
|||
LOAD_LIB_2(settings1.library, "posix.cfg");
|
||||
LOAD_LIB_2(settings2.library, "std.cfg");
|
||||
|
||||
// Check that getcode works correctly..
|
||||
TEST_CASE(testgetcode);
|
||||
|
||||
// check that call_func works correctly..
|
||||
TEST_CASE(call_func);
|
||||
|
||||
// Check that simplifycode works correctly..
|
||||
TEST_CASE(simplifycode);
|
||||
|
||||
// Check that errors are found..
|
||||
TEST_CASE(findleak);
|
||||
|
||||
/*
|
||||
TEST_CASE(simple5);
|
||||
TEST_CASE(simple7);
|
||||
TEST_CASE(simple9); // Bug 2435468 - member function "free"
|
||||
|
@ -277,7 +265,6 @@ private:
|
|||
TEST_CASE(realloc3);
|
||||
TEST_CASE(realloc4);
|
||||
TEST_CASE(realloc5);
|
||||
TEST_CASE(realloc6);
|
||||
TEST_CASE(realloc7);
|
||||
TEST_CASE(realloc8);
|
||||
TEST_CASE(realloc9);
|
||||
|
@ -382,551 +369,7 @@ private:
|
|||
TEST_CASE(crash);
|
||||
TEST_CASE(trac7680);
|
||||
TEST_CASE(trac7440);
|
||||
}
|
||||
|
||||
std::string getcode(const char code[], const char varname[], bool classfunc=false) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
settings2.standards.posix = true;
|
||||
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings2, this);
|
||||
std::istringstream istr(code);
|
||||
if (!tokenizer.tokenize(istr, "test.cpp"))
|
||||
return "";
|
||||
tokenizer.simplifyTokenList2();
|
||||
const Token * start = tokenizer.tokens();
|
||||
const SymbolDatabase * db = tokenizer.getSymbolDatabase();
|
||||
if (db && db->functionScopes.size())
|
||||
start = db->functionScopes[0]->bodyStart->next();
|
||||
|
||||
const unsigned int varId(Token::findmatch(start, varname)->varId());
|
||||
|
||||
// getcode..
|
||||
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings2, nullptr);
|
||||
std::list<const Token *> callstack(1, nullptr);
|
||||
CheckMemoryLeak::AllocType allocType, deallocType;
|
||||
allocType = deallocType = CheckMemoryLeak::No;
|
||||
Token *tokens = checkMemoryLeak.getcode(start, callstack, varId, allocType, deallocType, classfunc, 1);
|
||||
|
||||
// stringify..
|
||||
std::ostringstream ret;
|
||||
for (const Token *tok = tokens; tok; tok = tok->next())
|
||||
ret << tok->str();
|
||||
|
||||
TokenList::deleteTokens(tokens);
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void testgetcode() {
|
||||
// alloc;
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int *a = malloc(100);", "a"));
|
||||
TODO_ASSERT_EQUALS(";;alloc;", ";;alloccallfunc;", getcode("int *a = ::malloc(100);", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int *a = new int;", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int *a = new int[10];", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int **a = new int*[10];", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int * const a = new int[10];", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("const int * const a = new int[10];", "a"));
|
||||
ASSERT_EQUALS(";;assign;", getcode("A * a = new (X) A;", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int i = open(a,b);", "i"));
|
||||
ASSERT_EQUALS(";;assign;", getcode("int i = open();", "i"));
|
||||
ASSERT_EQUALS(";;alloc;use;", getcode("int *p; dostuff(p = new int);", "p"));
|
||||
ASSERT_EQUALS(";;alloc;use;", getcode("int *p; dostuff(p = new int());", "p"));
|
||||
ASSERT_EQUALS(";;alloc;use;", getcode("int *p; fred.dostuff(p = new int);", "p"));
|
||||
ASSERT_EQUALS(";;alloc;use;", getcode("int *p; fred.dostuff(p = new int());", "p"));
|
||||
|
||||
// alloc; return use;
|
||||
ASSERT_EQUALS(";;alloc;returnuse;", getcode("int *a = new int[10]; return a;", "a"));
|
||||
ASSERT_EQUALS(";;alloc;returnuse;", getcode("char *a = new char[100]; return (char *)a;", "a"));
|
||||
|
||||
// alloc; return;
|
||||
ASSERT_EQUALS(";;alloc;return;", getcode("char *s = new char[100]; return 0;", "s"));
|
||||
ASSERT_EQUALS(";;alloc;return;", getcode("char *s = new char[100]; return s[0];", "s"));
|
||||
ASSERT_EQUALS(";;alloc;return;", getcode("char *s = new char[100]; return strcmp(s,x);", "s"));
|
||||
|
||||
// lock/unlock..
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int a; __cppcheck_lock();", ""));
|
||||
ASSERT_EQUALS(";;callfunc;", getcode("int a; __cppcheck_lock();", "a"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("int a; __cppcheck_unlock();", ""));
|
||||
ASSERT_EQUALS(";;callfunc;", getcode("int a; __cppcheck_unlock();", "a"));
|
||||
|
||||
// dealloc;
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; free(s);", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; free((void *)s);", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; free((void *)(s));", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; free(reinterpret_cast<void *>(s));", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; ::free(s);", "s")); // #2802
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete s;", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete (s);", "s"));
|
||||
TODO_ASSERT_EQUALS(";;dealloc;",
|
||||
";;;", getcode("char *s; delete (void *)(s);", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete [] s;", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; delete [] (s);", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("void *p; foo(fclose(p));", "p"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("void *p; foo(close(p));", "p"));
|
||||
ASSERT_EQUALS(";;;;", getcode("FILE *f1; FILE *f2; fclose(f1);", "f2"));
|
||||
ASSERT_EQUALS(";;returnuse;", getcode("FILE *f; return fclose(f) == EOF ? 1 : 2;", "f"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("char *s; s ? free(s) : 0;", "s"));
|
||||
|
||||
// if..
|
||||
ASSERT_EQUALS(";;if{}", getcode("char *s; if (a) { }", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;ifv{}", getcode("FILE *f; if (fclose(f)) { }", "f"));
|
||||
ASSERT_EQUALS(";;if(!var){}else{}", getcode("char *s; if (!s) { } else { }", "s"));
|
||||
TODO_ASSERT_EQUALS(";;ifv{}",";;if{}", getcode("char *s; if (a && s) { }", "s"));
|
||||
ASSERT_EQUALS(";;ifv{}", getcode("char *s; if (s && a) { }", "s"));
|
||||
ASSERT_EQUALS(";;;ifv{}", getcode("char *s; int a; if (a && s) { }", "s"));
|
||||
ASSERT_EQUALS(";;;ifv{}", getcode("char *s; int a; if (s && a) { }", "s"));
|
||||
ASSERT_EQUALS(";;ifv{}", getcode("char *s; if (a || s) { }", "s"));
|
||||
ASSERT_EQUALS(";;ifv{}", getcode("char *s; if (s || a) { }", "s"));
|
||||
ASSERT_EQUALS(";;if(!var){}", getcode("char *s; if (a && !s) { }", "s"));
|
||||
ASSERT_EQUALS(";;ifv{}", getcode("char *s; if (foo(!s)) { }", "s"));
|
||||
ASSERT_EQUALS(";;;if{dealloc;};if{dealloc;return;}assign;returnuse;", getcode("char *buf, *tmp; tmp = realloc(buf, 40); if (!(tmp)) { free(buf); return; } buf = tmp; return buf;", "buf"));
|
||||
ASSERT_EQUALS(";;if{}", getcode("FILE *f; if (fgets(buf,100,f)){}", "f"));
|
||||
ASSERT_EQUALS(";;alloc;if(var){dealloc;}", getcode("int fd = open(a,b); if (0 < fd) { close(fd); }", "fd"));
|
||||
ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (x(s)) { }", "s"));
|
||||
ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (x(&s)) { }", "s"));
|
||||
ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (!s || x(&s)) { }", "s"));
|
||||
ASSERT_EQUALS(";;ifv{}", getcode("int ffd; if (ffd<0 && (ffd=a)<0){}", "ffd"));
|
||||
|
||||
// if (ticket #2442)
|
||||
ASSERT_EQUALS(";;;;if(!var){;}ifv{}", getcode("char *s; int x = 0; if (!s) { x = 2; } if (x) { }", "s"));
|
||||
ASSERT_EQUALS(";;;;if(!var){;}if{}", getcode("char *s; int x = 0; if (!s) { x = 2; } if (y) { }", "s"));
|
||||
|
||||
// switch..
|
||||
ASSERT_EQUALS(";;switch{case;;break;};", getcode("char *s; switch(a){case 1: break;};", "s"));
|
||||
|
||||
// loop..
|
||||
ASSERT_EQUALS(";;loop{}", getcode("char *s; while (a) { }", "s"));
|
||||
ASSERT_EQUALS(";;loopcallfunc{}", getcode("char *s; while (a()) { }", "s"));
|
||||
ASSERT_EQUALS(";;loop{}", getcode("char *s; for (a;b;c) { }", "s"));
|
||||
ASSERT_EQUALS(";;loop{alloc;}", getcode("char *s; for (a;b;c) { s=malloc(10); }", "s"));
|
||||
ASSERT_EQUALS(";;do{}loop;", getcode("char *s; do { } while (a);", "s"));
|
||||
ASSERT_EQUALS(";;while1{}", getcode("char *s; while(true) { }", "s"));
|
||||
ASSERT_EQUALS(";;while1{}", getcode("char *s; for(;;) { }", "s"));
|
||||
ASSERT_EQUALS(";;while(var){}", getcode("char *s; while (s) { }", "s"));
|
||||
ASSERT_EQUALS(";;while(!var){}", getcode("char *s; while (!s) { }", "s"));
|
||||
ASSERT_EQUALS(";;alloc;while(var){}", getcode("int fd = open(a,b); while (fd >= 0) { }", "fd"));
|
||||
ASSERT_EQUALS(";;alloc;while(!var){}", getcode("int fd = open(a,b); while (fd < 0) { }", "fd"));
|
||||
|
||||
// asprintf..
|
||||
ASSERT_EQUALS(";;alloc;", getcode("char *s; asprintf(&s, \"xyz\");", "s"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("char *s; asprintf(&s, \"s: %s\", s);", "s"));
|
||||
ASSERT_EQUALS(";;;", getcode("char *s; asprintf(&p, \"s: %s\", s);", "s"));
|
||||
|
||||
// Since we don't check how the return value is used we must bail out
|
||||
ASSERT_EQUALS("", getcode("char *s; int ret = asprintf(&s, \"xyz\");", "s"));
|
||||
TODO_ASSERT_EQUALS(";;alloc;",
|
||||
"", getcode("char *s; int ret; ret=asprintf(&s, \"xyz\"); if (ret==-1) return;", "s"));
|
||||
|
||||
// use..
|
||||
ASSERT_EQUALS(";;use;", getcode("char *s; a(s);", "s"));
|
||||
ASSERT_EQUALS(";;use;", getcode("char *s; (*a)(s);", "s"));
|
||||
ASSERT_EQUALS(";;use;", getcode("char *s; abc.a(s);", "s"));
|
||||
ASSERT_EQUALS(";;use;", getcode("char *s; s2 = s;", "s"));
|
||||
ASSERT_EQUALS(";;use;", getcode("char *s; s2 = s + 10;", "s"));
|
||||
ASSERT_EQUALS(";;use;", getcode("char *s; s2 = x + s;", "s"));
|
||||
ASSERT_EQUALS(";;use;if{;}", getcode("char *s; if (foo(s)) ;", "s"));
|
||||
ASSERT_EQUALS(";;use;", getcode("char *s; map1[s] = 0;", "s"));
|
||||
ASSERT_EQUALS(";;;use;", getcode("char *p; const char *q; q = p;", "p"));
|
||||
ASSERT_EQUALS(";;use;;", getcode("char *s; x = {1,s};", "s"));
|
||||
ASSERT_EQUALS(";{};;alloc;;use;", getcode("struct Foo { }; Foo *p; p = malloc(10); const Foo *q; q = p;", "p"));
|
||||
ASSERT_EQUALS(";;useuse_;", getcode("struct AB *ab; f(ab->a);", "ab"));
|
||||
ASSERT_EQUALS(";;use;", getcode("struct AB *ab; ab = pop(ab);", "ab"));
|
||||
|
||||
// non-use..
|
||||
ASSERT_EQUALS(";;use_;", getcode("char *s; c = x + s[0];","s"));
|
||||
ASSERT_EQUALS(";;use_;", getcode("char *s; c = s[0] + x;","s"));
|
||||
ASSERT_EQUALS(";;use_;", getcode("type *c; y = x + c->y;","c"));
|
||||
ASSERT_EQUALS(";;use_;", getcode("type *c; y = c->y + x;","c"));
|
||||
ASSERT_EQUALS(";;use_;", getcode("char *s; s = s + 1;", "s"));
|
||||
ASSERT_EQUALS(";;dealloc;;", getcode("struct foo *s; free(s); printf(a,sizeof(*s));", "s"));
|
||||
ASSERT_EQUALS(";;do{dealloc;;}while(var);", getcode("struct foo *s; do{free(s); printf(a,sizeof(*s));}while(s);", "s"));
|
||||
|
||||
// use reference
|
||||
ASSERT_EQUALS(";;callfunc&use;", getcode("struct AB *ab; f(&ab);", "ab"));
|
||||
|
||||
// return..
|
||||
ASSERT_EQUALS(";;return;", getcode("char *s; return;", "s"));
|
||||
ASSERT_EQUALS(";;returnuse;", getcode("char *s; return s;", "s"));
|
||||
ASSERT_EQUALS(";;return;", getcode("char *s; return 5 + s[0];", "s"));
|
||||
|
||||
// assign..
|
||||
ASSERT_EQUALS(";;assign;", getcode("char *s; s = 0;", "s"));
|
||||
ASSERT_EQUALS(";;;", getcode("char *s; s = strcpy(s, p);", "s"));
|
||||
|
||||
// callfunc..
|
||||
ASSERT_EQUALS(";;assign;", getcode("char *s; s = a();", "s"));
|
||||
ASSERT_EQUALS(";;callfunc;", getcode("char *s; a();", "s"));
|
||||
ASSERT_EQUALS(";;callfunc;", getcode("char *s; abc.a();", "s"));
|
||||
ASSERT_EQUALS(";;;", getcode("char *s; x = a();", "s")); // the function call is irrelevant
|
||||
|
||||
// exit..
|
||||
ASSERT_EQUALS(";;exit;", getcode("char *s; exit(0);", "s"));
|
||||
ASSERT_EQUALS(";;callfunc;", getcode("char *s; _exit(0);", "s")); // not in std.cfg
|
||||
ASSERT_EQUALS(";;exit;", getcode("char *s; abort();", "s"));
|
||||
ASSERT_EQUALS(";;callfunc;", getcode("char *s; err(0);", "s")); // not in std.cfg
|
||||
ASSERT_EQUALS(";;if{exit;}", getcode("char *s; if (a) { exit(0); }", "s"));
|
||||
ASSERT_EQUALS(";;if{exit;}", getcode("char *s; if (a) { ::exit(0); }", "s"));
|
||||
ASSERT_EQUALS(";;if{exit;}", getcode("char *s; if (a) { std::exit(0); }", "s"));
|
||||
|
||||
// list_for_each
|
||||
ASSERT_EQUALS(";;exit;{}}", getcode("void f() { char *s; list_for_each(x,y,s) { } }", "s"));
|
||||
|
||||
// open/close
|
||||
ASSERT_EQUALS(";;alloc;if(var){dealloc;}", getcode("int f; f=open(a,b); if(f>=0)close(f);", "f"));
|
||||
ASSERT_EQUALS(";;alloc;if(var){dealloc;}", getcode("int f; f=open(a,b); if(f>-1)close(f);", "f"));
|
||||
ASSERT_EQUALS(";;alloc;ifv{;}", getcode("int f; f=open(a,b); if(f!=-1 || x);", "f"));
|
||||
ASSERT_EQUALS(";;;dealloc;loop{}", getcode(";int f; while (close(f) == -1) { }", "f"));
|
||||
ASSERT_EQUALS(";;;dealloc;assign;;", getcode(";int res; res = close(res);", "res"));
|
||||
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("int f; e |= fclose(f);", "f"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("int f; e += fclose(f);", "f"));
|
||||
ASSERT_EQUALS(";;dealloc;", getcode("int f; foo(fclose(f));", "f"));
|
||||
|
||||
// fcloseall..
|
||||
ASSERT_EQUALS(";;alloc;;", getcode("char *s; s = malloc(10); fcloseall();", "s"));
|
||||
ASSERT_EQUALS(";;alloc;dealloc;", getcode("FILE *f; f = fopen(a,b); fcloseall();", "f"));
|
||||
|
||||
// call memcpy in class function..
|
||||
ASSERT_EQUALS(";;alloc;;", getcode("char *s; s = new char[10]; memcpy(s,a);", "s", true));
|
||||
|
||||
// #2112 - Segmentation fault in the getcode function
|
||||
ASSERT_THROW(getcode("page *one = foo();\n"
|
||||
"ASSERT(one, return 0)\n"
|
||||
"const int two = rand();\n"
|
||||
"return 0;\n"
|
||||
"}", "one"), InternalError);
|
||||
|
||||
// ticket #2336: calling member function with same name as a white_list function
|
||||
ASSERT_EQUALS(";;use;", getcode("char *s; foo.write(s);", "s"));
|
||||
|
||||
// #2473 - inner struct
|
||||
ASSERT_EQUALS(";;alloc;{;;};dealloc;",
|
||||
getcode("char *s = new char[10];\n"
|
||||
"struct ab { int a, b; };\n"
|
||||
"delete [] s;\n", "s"));
|
||||
|
||||
// #4405 - catch
|
||||
ASSERT_EQUALS(";;catch{}", getcode("char *s; catch(err) { }", "s"));
|
||||
}
|
||||
|
||||
bool test_white_list(const std::string& str, bool cpp = true) const {
|
||||
return CheckMemoryLeakInFunction::test_white_list(str, &settings1, cpp);
|
||||
}
|
||||
|
||||
void call_func() const {
|
||||
// whitelist..
|
||||
ASSERT_EQUALS(true, test_white_list("qsort"));
|
||||
ASSERT_EQUALS(true, test_white_list("scanf"));
|
||||
ASSERT_EQUALS(true, test_white_list("sscanf"));
|
||||
|
||||
// #1293
|
||||
ASSERT_EQUALS(true, test_white_list("time"));
|
||||
ASSERT_EQUALS(true, test_white_list("asctime"));
|
||||
ASSERT_EQUALS(true, test_white_list("asctime_r"));
|
||||
ASSERT_EQUALS(true, test_white_list("ctime"));
|
||||
ASSERT_EQUALS(true, test_white_list("ctime_r"));
|
||||
ASSERT_EQUALS(true, test_white_list("gmtime"));
|
||||
ASSERT_EQUALS(true, test_white_list("gmtime_r"));
|
||||
ASSERT_EQUALS(true, test_white_list("localtime"));
|
||||
ASSERT_EQUALS(true, test_white_list("localtime_r"));
|
||||
ASSERT_EQUALS(true, test_white_list("memcmp"));
|
||||
ASSERT_EQUALS(true, test_white_list("gets"));
|
||||
ASSERT_EQUALS(true, test_white_list("vprintf"));
|
||||
ASSERT_EQUALS(true, test_white_list("vfprintf"));
|
||||
ASSERT_EQUALS(true, test_white_list("vsprintf"));
|
||||
ASSERT_EQUALS(true, test_white_list("snprintf"));
|
||||
ASSERT_EQUALS(true, test_white_list("vsnprintf"));
|
||||
|
||||
ASSERT_EQUALS(true, test_white_list("delete", true));
|
||||
ASSERT_EQUALS(false, test_white_list("delete", false));
|
||||
|
||||
static const char * const call_func_white_list[] = {
|
||||
"access", "asprintf", "atof", "atoi", "atol", "chdir", "chmod", "clearerr", "chown"
|
||||
, "fchmod", "fcntl", "fdatasync", "feof", "ferror", "fflush", "fgetc", "fgetpos", "fgets"
|
||||
, "flock", "for", "fprintf", "fputc", "fputs", "fread", "free", "freopen", "fscanf", "fseek"
|
||||
, "fseeko", "fsetpos", "fstat", "fsync", "ftell", "ftello", "ftruncate"
|
||||
, "fwrite", "getc", "if", "ioctl", "lockf", "lseek", "open", "memchr", "memcpy"
|
||||
, "memmove", "memset", "mkstemp", "perror", "posix_fadvise", "posix_fallocate", "pread"
|
||||
, "printf", "puts", "pwrite", "read", "readahead", "readdir", "readdir_r", "readv"
|
||||
, "realloc", "return", "rewind", "rewinddir", "scandir", "seekdir"
|
||||
, "setbuf", "setbuffer", "setlinebuf", "setvbuf", "snprintf", "sprintf", "stpcpy", "strcasecmp"
|
||||
, "strcat", "strchr", "strcmp", "strcpy", "stricmp", "strlen", "strncat", "strncmp"
|
||||
, "strncpy", "strrchr", "strspn","strstr", "strtod", "strtol", "strtoul", "switch"
|
||||
, "sync_file_range", "telldir", "typeid", "while", "write", "writev", "lstat", "stat"
|
||||
, "_open", "_wopen", "vscanf", "vsscanf", "vfscanf", "vasprintf", "utime", "utimes", "unlink"
|
||||
, "tempnam", "system", "symlink", "strpbrk", "strncasecmp", "strdup", "strcspn", "strcoll"
|
||||
, "setlocale", "sethostname", "rmdir", "rindex", "rename", "remove", "adjtime", "creat", "execle"
|
||||
, "execl", "execlp", "execve", "execv", "fmemopen", "fnmatch", "fopencookie", "fopen"
|
||||
, "getgrnam", "gethostbyaddr", "getnetbyname", "getopt", "getopt_long", "getprotobyname", "getpwnam"
|
||||
, "getservbyname", "getservbyport", "glob", "index", "inet_addr", "inet_aton", "inet_network"
|
||||
, "initgroups", "link", "mblen", "mbstowcs", "mbtowc", "mkdir", "mkfifo", "mknod", "obstack_printf"
|
||||
, "obstack_vprintf", "opendir", "parse_printf_format", "pathconf", "popen", "psignal"
|
||||
, "readlink", "regcomp", "strxfrm", "wordexp", "sizeof", "strtok"
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < (sizeof(call_func_white_list) / sizeof(char *)); ++i) {
|
||||
bool ret = test_white_list(call_func_white_list[i]);
|
||||
ASSERT_EQUALS("", ret ? "" : call_func_white_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string simplifycode(const char code[]) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
// Tokenize..
|
||||
std::istringstream istr(code);
|
||||
Tokenizer tokenizer(&settings0, this);
|
||||
tokenizer.list.createTokens(istr, "test.cpp");
|
||||
|
||||
// replace "if ( ! var )" => "if(!var)"
|
||||
for (Token *tok = tokenizer.list.front(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "if|while ( var )")) {
|
||||
Token::eraseTokens(tok, tok->tokAt(4));
|
||||
tok->str(tok->str() + "(var)");
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, "if|while ( ! var )")) {
|
||||
Token::eraseTokens(tok, tok->tokAt(5));
|
||||
tok->str(tok->str() + "(!var)");
|
||||
}
|
||||
}
|
||||
|
||||
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings0, this);
|
||||
checkMemoryLeak.simplifycode(tokenizer.list.front());
|
||||
|
||||
return tokenizer.tokens()->stringifyList(0, false);
|
||||
}
|
||||
|
||||
|
||||
// Test that the CheckMemoryLeaksInFunction::simplifycode works
|
||||
void simplifycode() {
|
||||
ASSERT_EQUALS(";", simplifycode("; ; ; ;"));
|
||||
ASSERT_EQUALS(";", simplifycode("; if ;"));
|
||||
ASSERT_EQUALS("alloc ;", simplifycode("alloc ; if ; if(var) ; ifv ; if(!var) ;"));
|
||||
ASSERT_EQUALS("alloc ;", simplifycode("alloc ; if ; else ;"));
|
||||
|
||||
// use..
|
||||
ASSERT_EQUALS("; use ; }", simplifycode("; use use ; }"));
|
||||
ASSERT_EQUALS("; use ; }", simplifycode("; use use_ ; }"));
|
||||
ASSERT_EQUALS("; use ; }", simplifycode("; use_ use ; }"));
|
||||
ASSERT_EQUALS("; use ; }", simplifycode("; &use use ; }"));
|
||||
ASSERT_EQUALS("; use ; }", simplifycode("; use &use ; }"));
|
||||
ASSERT_EQUALS("; alloc ; dealloc ; }", simplifycode("; alloc ; use ; use ; if use ; dealloc ; }"));
|
||||
|
||||
// if, else..
|
||||
ASSERT_EQUALS("; alloc ; if break ; dealloc ;", simplifycode("; alloc ; if { break; } dealloc ;"));
|
||||
ASSERT_EQUALS("; alloc ; if continue ; dealloc ;", simplifycode("; alloc ; if { continue; } dealloc ;"));
|
||||
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc; if { return use; }"));
|
||||
ASSERT_EQUALS("; alloc ; dealloc ;", simplifycode("; alloc; if(!var) { return; } dealloc;"));
|
||||
ASSERT_EQUALS("; alloc ;", simplifycode("; if { alloc; } else { return; }"));
|
||||
ASSERT_EQUALS("; alloc ; dealloc ;", simplifycode("; alloc ; if(!var) { alloc ; } dealloc ;"));
|
||||
ASSERT_EQUALS("; use ;", simplifycode("; if(var) use ;"));
|
||||
ASSERT_EQUALS("; break ;", simplifycode("; if break ; else break ;"));
|
||||
ASSERT_EQUALS("; alloc ; if return ;", simplifycode("; alloc ; loop { if return ; if continue ; }"));
|
||||
ASSERT_EQUALS("; alloc ; if return ;", simplifycode("; alloc ; loop { if continue ; else return ; }"));
|
||||
|
||||
ASSERT_EQUALS("; alloc ; if dealloc ;", simplifycode("; alloc ; if(!var) { return ; } if { dealloc ; }"));
|
||||
ASSERT_EQUALS("; if alloc ; else assign ; return use ;", simplifycode("; callfunc ; if callfunc { alloc ; } else { assign ; } return use ;"));
|
||||
|
||||
ASSERT_EQUALS("; dealloc ; return ;", simplifycode("; while1 { if callfunc { dealloc ; return ; } else { continue ; } }"));
|
||||
|
||||
// remove outer if (#2733)
|
||||
ASSERT_EQUALS("alloc ; return ; }", simplifycode("alloc ; if { if return use ; } return ; }"));
|
||||
ASSERT_EQUALS("alloc ; return ; }", simplifycode("alloc ; if { if(var) return use ; } return ; }"));
|
||||
ASSERT_EQUALS("alloc ; return ; }", simplifycode("alloc ; if(var) { if return use ; } return ; }"));
|
||||
|
||||
// "if ; .."
|
||||
ASSERT_EQUALS("; if xxx ;", simplifycode("; if ; else xxx ;"));
|
||||
ASSERT_EQUALS("; if(var) xxx ;", simplifycode("; if(!var) ; else xxx ;"));
|
||||
ASSERT_EQUALS("; if(!var) xxx ;", simplifycode("; if(var) ; else xxx ;"));
|
||||
ASSERT_EQUALS("; ifv xxx ;", simplifycode("; ifv ; else xxx ;"));
|
||||
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc; if { dealloc; return; }"));
|
||||
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc; if { return use; }"));
|
||||
ASSERT_EQUALS("; alloc ; return ;", simplifycode(";alloc;if{return;}return;"));
|
||||
ASSERT_EQUALS("; alloc ; if assign ; dealloc ;", simplifycode(";alloc;if{assign;}dealloc;"));
|
||||
|
||||
// if(var)
|
||||
ASSERT_EQUALS("; alloc ; return use ;", simplifycode("; alloc ; return use ;"));
|
||||
ASSERT_EQUALS("; alloc ; return use ;", simplifycode("; alloc ; ifv return ; return use ;"));
|
||||
|
||||
// switch..
|
||||
ASSERT_EQUALS("; alloc ; dealloc ;", simplifycode(";alloc;switch{case;break;};dealloc;"));
|
||||
ASSERT_EQUALS(";", simplifycode("; switch { case ; return ; default ; break ; }"));
|
||||
ASSERT_EQUALS(";", simplifycode("; switch { case ; if { return ; } break ; default ; break ; }"));
|
||||
ASSERT_EQUALS("; use ;", simplifycode("; switch { case ; return ; default ; use ; break ; }"));
|
||||
ASSERT_EQUALS("; use ;", simplifycode("; while1 { loop { ; } switch { case ; dealloc ; return ; default ; break ; } }"));
|
||||
ASSERT_EQUALS("; { dealloc ; return ; } }", simplifycode("switch { case ; case ; dealloc ; return ; default ; dealloc ; return ; } }"));
|
||||
|
||||
// loops..
|
||||
ASSERT_EQUALS(";", simplifycode("; loop { ; }"));
|
||||
ASSERT_EQUALS(";", simplifycode("; loop { break; }"));
|
||||
ASSERT_EQUALS(";", simplifycode("; loop { if { break; } }"));
|
||||
ASSERT_EQUALS("; loop alloc ;", simplifycode("; loop { alloc ; }"));
|
||||
ASSERT_EQUALS("; alloc ; alloc ;", simplifycode("; alloc ; do { alloc ; } loop ;"));
|
||||
ASSERT_EQUALS("; exit ;", simplifycode("; alloc ; do { } loop ; exit ;"));
|
||||
ASSERT_EQUALS("; loop use ;", simplifycode("; loop { loop loop use ; } ;"));
|
||||
ASSERT_EQUALS("; }", simplifycode("; loop { if break ; break ; } ; }"));
|
||||
ASSERT_EQUALS("; }", simplifycode("; loop { if continue ; if continue ; } ; }"));
|
||||
{
|
||||
// ticket #3267
|
||||
const char expected[] = "; loop if alloc ; if { dealloc ; return ; } }";
|
||||
ASSERT_EQUALS(expected, simplifycode("; loop { if alloc ; } if { dealloc ; return ; } }"));
|
||||
ASSERT_EQUALS(expected, simplifycode("; loop { if { alloc ; if(!var) { return ; } } } if { dealloc ; return ; } }"));
|
||||
}
|
||||
|
||||
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; while(!var) alloc ;"));
|
||||
|
||||
ASSERT_EQUALS("; alloc ; dealloc ; return ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } }"));
|
||||
ASSERT_EQUALS("; alloc ; dealloc ; return ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } if { continue ; } }"));
|
||||
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; while1 { if { dealloc ; return ; } if { break ; } }"));
|
||||
ASSERT_EQUALS("; alloc ; use ; }", simplifycode("; alloc ; while1 { if { dealloc ; return ; } continue ; } ; }"));
|
||||
|
||||
ASSERT_EQUALS(";", simplifycode("; do { dealloc ; alloc ; } while(var) ;"));
|
||||
ASSERT_EQUALS("dealloc ; alloc ;", simplifycode("loop { dealloc ; alloc ; }"));
|
||||
ASSERT_EQUALS("dealloc ; alloc ;", simplifycode("while1 { dealloc ; alloc ; }"));
|
||||
ASSERT_EQUALS("use ; }", simplifycode("loop { use ; callfunc ; } }"));
|
||||
|
||||
ASSERT_EQUALS(";", simplifycode("; loop { if { continue ; } else { if continue ; } }"));
|
||||
ASSERT_EQUALS(";", simplifycode("; loop { { if continue ; if continue ; } }"));
|
||||
|
||||
ASSERT_EQUALS("; use ;", simplifycode("; while1 { if { dealloc ; return ; } if { if { continue ; } } }"));
|
||||
|
||||
// scope..
|
||||
TODO_ASSERT_EQUALS("; assign ; if alloc ; }",
|
||||
"; assign ; dealloc ; if alloc ; }", simplifycode("; assign ; { dealloc ; if alloc ; } }"));
|
||||
|
||||
// callfunc..
|
||||
ASSERT_EQUALS("; callfunc ; }", simplifycode(";callfunc;}"));
|
||||
ASSERT_EQUALS(";", simplifycode(";callfunc;;"));
|
||||
ASSERT_EQUALS("; callfunc ; }", simplifycode(";callfunc callfunc ; }"));
|
||||
ASSERT_EQUALS("dealloc ; alloc ; return ; }", simplifycode("while1 { dealloc ; alloc ; } callfunc ; return ; }"));
|
||||
ASSERT_EQUALS("; }", simplifycode("loop callfunc ; }"));
|
||||
ASSERT_EQUALS("alloc ; dealloc ; }", simplifycode("alloc ; if { dealloc ; callfunc } dealloc ; }")); // #4405
|
||||
|
||||
// #2900 - don't report false positive
|
||||
ASSERT_EQUALS("; alloc ; if { if { dealloc ; callfunc ; } return ; } dealloc ; }",
|
||||
simplifycode("; alloc ; if { if { dealloc ; callfunc ; } return ; } dealloc ; }"));
|
||||
|
||||
// exit..
|
||||
ASSERT_EQUALS("; exit ;", simplifycode("; alloc; exit;"));
|
||||
ASSERT_EQUALS("; exit ;", simplifycode("; alloc; if { loop ; } dealloc; exit;"));
|
||||
ASSERT_EQUALS(";", simplifycode("; if { alloc; exit; }"));
|
||||
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; if { use; exit; }"));
|
||||
ASSERT_EQUALS("; alloc ;", simplifycode("; alloc ; if(!var) { exit; }"));
|
||||
TODO_ASSERT_EQUALS(";",
|
||||
"; if(var) exit ;", simplifycode("; alloc ; if(var) { exit; }"));
|
||||
TODO_ASSERT_EQUALS(";\n; alloc ;",
|
||||
"; alloc ; ifv exit ;", simplifycode("; alloc ; ifv { exit; }"));
|
||||
|
||||
// try-catch
|
||||
ASSERT_EQUALS("; }", simplifycode("; try ; catch exit ; }"));
|
||||
|
||||
// dealloc; dealloc;
|
||||
ASSERT_EQUALS("; alloc ; if dealloc ; dealloc ;", simplifycode("; alloc ; if { dealloc ; } dealloc ;"));
|
||||
|
||||
// use ; dealloc ;
|
||||
ASSERT_EQUALS("; alloc ; use ; if return ; dealloc ;", simplifycode("; alloc ; use ; if { return ; } dealloc ;"));
|
||||
|
||||
// #2635 - false negative
|
||||
ASSERT_EQUALS("; alloc ; return use ; }",
|
||||
simplifycode("; alloc ; if(!var) { loop { ifv { } } alloc ; } return use; }"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// is there a leak in given code? if so, return the linenr
|
||||
unsigned int dofindleak(const char code[]) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
settings0.debugwarnings = true;
|
||||
|
||||
// Tokenize..
|
||||
std::istringstream istr(code);
|
||||
TokenList list(&settings0);
|
||||
list.createTokens(istr,"test.cpp");
|
||||
Token *tokens=list.front();
|
||||
|
||||
// replace "if ( ! var )" => "if(!var)"
|
||||
for (Token *tok = tokens; tok; tok = tok->next()) {
|
||||
if (tok->str() == "if_var") {
|
||||
tok->str("if(var)");
|
||||
}
|
||||
|
||||
else if (Token::simpleMatch(tok, "if ( var )")) {
|
||||
Token::eraseTokens(tok, tok->tokAt(4));
|
||||
tok->str("if(var)");
|
||||
}
|
||||
|
||||
else if (Token::simpleMatch(tok, "if ( ! var )")) {
|
||||
Token::eraseTokens(tok, tok->tokAt(5));
|
||||
tok->str("if(!var)");
|
||||
}
|
||||
}
|
||||
|
||||
const Token *tok = CheckMemoryLeakInFunction::findleak(tokens);
|
||||
|
||||
settings0.debugwarnings = false;
|
||||
|
||||
return (tok ? tok->linenr() : (unsigned int)(-1));
|
||||
}
|
||||
|
||||
void findleak() {
|
||||
static const unsigned int notfound = (unsigned int)(-1);
|
||||
|
||||
ASSERT_EQUALS(1, dofindleak("alloc;"));
|
||||
ASSERT_EQUALS(1, dofindleak("; use; { alloc; }"));
|
||||
ASSERT_EQUALS(2, dofindleak("alloc;\n return;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc; return use;"));
|
||||
ASSERT_EQUALS(2, dofindleak("alloc;\n callfunc;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc; use;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("assign; alloc; dealloc;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("assign; if alloc; dealloc;"));
|
||||
|
||||
// if alloc..
|
||||
ASSERT_EQUALS(2, dofindleak("if alloc;\n return;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("if alloc;\n return use;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("if alloc;\n use;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("if alloc;\n if assign;\n if dealloc; }"));
|
||||
|
||||
// if..
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc; ifv dealloc;"));
|
||||
ASSERT_EQUALS(2, dofindleak("alloc;\n if return;\n dealloc;"));
|
||||
ASSERT_EQUALS(2, dofindleak("alloc;\n if continue;\n dealloc;"));
|
||||
ASSERT_EQUALS(2, dofindleak("alloc;\n if_var return;\n dealloc;"));
|
||||
ASSERT_EQUALS(3, dofindleak("alloc;\n if\n return;\n dealloc;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc; if { dealloc ; return; } dealloc;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc; if { dealloc ; return; } dealloc;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc; if { dealloc ; alloc; } dealloc;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc;\n if(!var)\n { callfunc;\n return;\n }\n use;"));
|
||||
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc; if { return use; } dealloc;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc; if { dealloc; return; } dealloc;"));
|
||||
|
||||
ASSERT_EQUALS(5, dofindleak("{\n;\n alloc;\n if dealloc;\n}"));
|
||||
|
||||
// assign..
|
||||
ASSERT_EQUALS(2, dofindleak("alloc;\n assign;\n dealloc;"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("alloc;\n if(!var) assign;\n dealloc;"));
|
||||
ASSERT_EQUALS(2, dofindleak(";alloc;\n if assign;\n dealloc;"));
|
||||
|
||||
// loop..
|
||||
TODO_ASSERT_EQUALS(1, notfound, dofindleak("; loop { alloc ; if break; dealloc ; }"));
|
||||
TODO_ASSERT_EQUALS(1, notfound, dofindleak("; loop { alloc ; if continue; dealloc ; }"));
|
||||
ASSERT_EQUALS(notfound, dofindleak("; loop { alloc ; if break; } dealloc ;"));
|
||||
ASSERT_EQUALS(1, dofindleak("; loop alloc ;"));
|
||||
ASSERT_EQUALS(1, dofindleak("; loop alloc ; dealloc ;"));
|
||||
|
||||
// callfunc (might be noreturn)
|
||||
ASSERT_EQUALS(notfound, dofindleak("; alloc ; callfunc ; }"));
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -2912,11 +2355,6 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void realloc6() {
|
||||
ASSERT_EQUALS(";;realloc;;", getcode("char *buf; buf=realloc(buf,100);", "buf"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("char *buf; buf=realloc(0,100);", "buf"));
|
||||
}
|
||||
|
||||
void realloc7() {
|
||||
check("bool foo(size_t nLen, char* pData)\n"
|
||||
"{\n"
|
||||
|
@ -6079,7 +5517,6 @@ private:
|
|||
CheckMemoryLeakInClass checkMemoryLeak2(&tokenizer, &settings, this);
|
||||
CheckMemoryLeakStructMember checkMemoryLeak3(&tokenizer, &settings, this);
|
||||
CheckMemoryLeakNoVar checkMemoryLeak4(&tokenizer, &settings, this);
|
||||
checkMemoryLeak1.check();
|
||||
checkMemoryLeak1.checkReallocUsage();
|
||||
checkMemoryLeak2.check();
|
||||
checkMemoryLeak3.check();
|
||||
|
@ -6089,9 +5526,10 @@ private:
|
|||
void run() override {
|
||||
LOAD_LIB_2(settings.library, "gtk.cfg");
|
||||
settings.addEnabled("all");
|
||||
|
||||
/*
|
||||
TEST_CASE(glib1);
|
||||
TEST_CASE(glib2); // #2806 - FP when using redundant assignment
|
||||
*/
|
||||
}
|
||||
|
||||
void glib1() {
|
||||
|
@ -6198,15 +5636,15 @@ private:
|
|||
// Check for memory leaks..
|
||||
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings, this);
|
||||
checkMemoryLeak.checkReallocUsage();
|
||||
checkMemoryLeak.check();
|
||||
}
|
||||
|
||||
void run() override {
|
||||
LOAD_LIB_2(settings.library, "windows.cfg");
|
||||
|
||||
/*
|
||||
TEST_CASE(openfileNoLeak);
|
||||
TEST_CASE(returnValueNotUsed_tfopen_s);
|
||||
TEST_CASE(sendMessage);
|
||||
*/
|
||||
}
|
||||
|
||||
void openfileNoLeak() {
|
||||
|
|
Loading…
Reference in New Issue