diff --git a/cfg/std.cfg b/cfg/std.cfg
index b30583835..c1ba3c546 100644
--- a/cfg/std.cfg
+++ b/cfg/std.cfg
@@ -450,7 +450,6 @@
malloc
calloc
- realloc
diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp
index b87ff5150..ef6fd380d 100644
--- a/lib/checkmemoryleak.cpp
+++ b/lib/checkmemoryleak.cpp
@@ -506,45 +506,6 @@ const char *CheckMemoryLeak::functionArgAlloc(const Function *func, unsigned int
}
-void CheckMemoryLeakInFunction::parse_noreturn()
-{
- if (noreturn.empty()) {
- noreturn.insert("exit");
- noreturn.insert("_exit");
- noreturn.insert("_Exit");
- noreturn.insert("abort");
- noreturn.insert("err");
- noreturn.insert("verr");
- noreturn.insert("errx");
- noreturn.insert("verrx");
- noreturn.insert("ExitProcess");
- noreturn.insert("ExitThread");
- noreturn.insert("pthread_exit");
- }
-
- // only check functions
- const std::size_t functionsCount = symbolDatabase->functionScopes.size();
- for (std::size_t i = 0; i < functionsCount; ++i) {
- const Scope * scope = symbolDatabase->functionScopes[i];
-
- // parse this function to check if it contains an "exit" call..
- bool isNoreturn = false;
- for (const Token *tok2 = scope->classStart->next(); tok2 != scope->classEnd; tok2 = tok2->next()) {
- if (Token::Match(tok2->previous(), "[;{}] exit (")) {
- isNoreturn = true;
- break;
- }
- }
-
- // This function is not a noreturn function
- if (isNoreturn)
- noreturn.insert(scope->className);
- else
- notnoreturn.insert(scope->className);
- }
-}
-
-
bool CheckMemoryLeakInFunction::notvar(const Token *tok, unsigned int varid, bool endpar)
{
const std::string end(endpar ? " &&|)" : " [;)&|]");
@@ -609,7 +570,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::liststr()) != noreturn.end() && tok->strAt(-1) != "=")
+ if (_settings->library.isnoreturn(tok->str()) && tok->strAt(-1) != "=")
return "exit";
if (varid > 0 && (getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No))
@@ -650,7 +611,11 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::listfunction()) {
+ std::string temp;
+ if (!_settings->library.isScopeNoReturn(tok->function()->functionScope->classEnd, &temp) && temp.empty())
+ return nullptr;
+ } else if (_settings->library.isnotnoreturn(funcname))
return nullptr;
return "callfunc";
@@ -1309,7 +1274,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::liststr()) != noreturn.end())
+ if (_settings->library.isnoreturn(tok->str()))
addtoken(&rettail, tok, "exit");
else if (!test_white_list_with_lib(tok->str(), _settings)) {
@@ -2233,9 +2198,6 @@ static bool isInMemberFunc(const Scope* scope)
void CheckMemoryLeakInFunction::check()
{
- // fill the "noreturn"
- parse_noreturn();
-
// Check locking/unlocking of global resources..
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h
index 4de0527f9..bef7bfb4a 100644
--- a/lib/checkmemoryleak.h
+++ b/lib/checkmemoryleak.h
@@ -296,9 +296,6 @@ public:
*/
void checkScope(const Token *Tok1, const std::string &varname, unsigned int varid, bool classmember, unsigned int sz);
- /** parse tokens to see what functions are "noreturn" */
- void parse_noreturn();
-
private:
/** Report all possible errors (for the --errorlist) */
void getErrorMessages(ErrorLogger *e, const Settings *settings) const {
@@ -331,12 +328,6 @@ private:
return "Is there any allocated memory when a function goes out of scope\n";
}
- /** Function names for functions that are "noreturn" */
- std::set noreturn;
-
- /** Function names for functions that are not "noreturn" */
- std::set notnoreturn;
-
const SymbolDatabase *symbolDatabase;
};
diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp
index e492d1fb2..541ce038c 100644
--- a/test/testmemleak.cpp
+++ b/test/testmemleak.cpp
@@ -148,6 +148,7 @@ private:
void run() {
+ LOAD_LIB_2(settings1.library, "std.cfg");
LOAD_LIB_2(settings1.library, "gtk.cfg");
// Check that getcode works correctly..
@@ -366,7 +367,9 @@ private:
TEST_CASE(posixcfg);
}
-
+ void loadlib(Library& library) {
+ LOAD_LIB_2(library, "std.cfg");
+ }
std::string getcode(const char code[], const char varname[], bool classfunc=false) {
// Clear the error buffer..
@@ -374,6 +377,7 @@ private:
Settings settings;
settings.standards.posix = true;
+ loadlib(settings.library);
// Tokenize..
Tokenizer tokenizer(&settings, this);
@@ -386,7 +390,6 @@ private:
// getcode..
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings, nullptr);
- checkMemoryLeak.parse_noreturn();
std::list callstack;
callstack.push_back(0);
CheckMemoryLeak::AllocType allocType, deallocType;
@@ -539,9 +542,9 @@ private:
// exit..
ASSERT_EQUALS(";;exit;", getcode("char *s; exit(0);", "s"));
- ASSERT_EQUALS(";;exit;", getcode("char *s; _exit(0);", "s"));
+ ASSERT_EQUALS(";;callfunc;", getcode("char *s; _exit(0);", "s")); // not in std.cfg nor in gtk.cfg
ASSERT_EQUALS(";;exit;", getcode("char *s; abort();", "s"));
- ASSERT_EQUALS(";;exit;", getcode("char *s; err(0);", "s"));
+ ASSERT_EQUALS(";;callfunc;", getcode("char *s; err(0);", "s")); // not in std.cfg nor in gtk.cfg
ASSERT_EQUALS(";;if{exit;}", getcode("char *s; if (a) { exit(0); }", "s"));
// list_for_each