diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index bd18f6b98..e4f373d3b 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -268,9 +268,9 @@ void CheckFunctions::checkIgnoredReturnValue() if ((!tok->function() || !Token::Match(tok->function()->retDef, "void %name%")) && !WRONG_DATA(!tok->next()->astOperand1(), tok)) { const Library::UseRetValType retvalTy = mSettings->library.getUseRetValType(tok); - if (mSettings->severity.isEnabled(Severity::warning) && - ((retvalTy == Library::UseRetValType::DEFAULT) || - (tok->function() && tok->function()->isAttributeNodiscard()))) + const bool warn = (tok->function() && tok->function()->isAttributeNodiscard()) || // avoid duplicate warnings for resource-allocating functions + (retvalTy == Library::UseRetValType::DEFAULT && mSettings->library.getAllocFuncInfo(tok) == nullptr); + if (mSettings->severity.isEnabled(Severity::warning) && warn) ignoredReturnValueError(tok, tok->next()->astOperand1()->expressionString()); else if (mSettings->severity.isEnabled(Severity::style) && retvalTy == Library::UseRetValType::ERROR_CODE) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index be1c508e2..402c7c252 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -274,6 +274,16 @@ bool CheckMemoryLeak::isReopenStandardStream(const Token *tok) const return false; } +bool CheckMemoryLeak::isOpenDevNull(const Token *tok) const +{ + if (mSettings_->posix() && tok->str() == "open" && numberOfArguments(tok) == 2) { + const Token* arg = getArguments(tok).at(0); + if (Token::simpleMatch(arg, "\"/dev/null\"")) + return true; + } + return false; +} + //-------------------------------------------------------------------------- @@ -1053,10 +1063,12 @@ void CheckMemoryLeakNoVar::checkForUnusedReturnValue(const Scope *scope) if (isReopenStandardStream(tok)) continue; + if (isOpenDevNull(tok)) + continue; // get ast parent, skip casts const Token *parent = isNew ? tok->astParent() : tok->next()->astParent(); - while (parent && parent->str() == "(" && !parent->astOperand2()) + while (parent && parent->isCast()) parent = parent->astParent(); bool warn = true; diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 3edfb4a39..5eae5509d 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -118,6 +118,11 @@ public: * @param tok token to check */ bool isReopenStandardStream(const Token *tok) const; + /** + * Check if token opens /dev/null + * @param tok token to check + */ + bool isOpenDevNull(const Token *tok) const; /** * Report that there is a memory leak (new/malloc/etc) * @param tok token where memory is leaked diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c index 0ca810479..47624972b 100644 --- a/test/cfg/gtk.c +++ b/test/cfg/gtk.c @@ -73,7 +73,6 @@ void validCode(int argInt, GHashTableIter * hash_table_iter, GHashTable * hash_t void g_malloc_test() { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_malloc(8); @@ -86,7 +85,6 @@ void g_malloc_test() void g_malloc0_test() { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_malloc0(8); @@ -99,7 +97,6 @@ void g_malloc0_test() void g_malloc_n_test() { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_malloc_n(8, 1); @@ -112,7 +109,6 @@ void g_malloc_n_test() void g_malloc0_n_test() { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_malloc0_n(8, 1); @@ -125,7 +121,6 @@ void g_malloc0_n_test() void g_try_malloc_test() { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_try_malloc(8); @@ -138,7 +133,6 @@ void g_try_malloc_test() void g_try_malloc0_test() { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_try_malloc0(8); @@ -151,7 +145,6 @@ void g_try_malloc0_test() void g_try_malloc_n_test() { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_try_malloc_n(8, 1); @@ -164,7 +157,6 @@ void g_try_malloc_n_test() void g_try_malloc0_n_test() { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_try_malloc0_n(8, 1); @@ -374,7 +366,6 @@ void g_error_new_test() printf("%p", pNew1); g_error_free(pNew1); - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed g_error_new(1, -2, "a %d", 1); diff --git a/test/cfg/posix.c b/test/cfg/posix.c index 195f86f85..4c368931e 100644 --- a/test/cfg/posix.c +++ b/test/cfg/posix.c @@ -838,7 +838,6 @@ void nullPointer(char *p, int fd, pthread_mutex_t mutex) // cppcheck-suppress unreadVariable // cppcheck-suppress nullPointer int ret = access(NULL, 0); - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed // cppcheck-suppress nullPointer fdopen(fd, NULL); @@ -978,7 +977,6 @@ void noleak(int x, int y, int z) void ignoredReturnValue(void *addr, int fd) { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed mmap(addr, 255, PROT_NONE, MAP_PRIVATE, fd, 0); // cppcheck-suppress ignoredReturnValue @@ -1065,7 +1063,6 @@ void uninitvar(int fd) // cppcheck-suppress uninitvar int access_ret = access("file", x3); - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed // cppcheck-suppress uninitvar fdopen(x4, "rw"); diff --git a/test/cfg/std.c b/test/cfg/std.c index e60e90637..cd4bfc977 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -287,7 +287,6 @@ void pointerLessThanZero_aligned_alloc(void) void unusedRetVal_aligned_alloc(void) { - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed aligned_alloc(8, 16); } diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp index 9c6978747..ae52271c9 100644 --- a/test/cfg/windows.cpp +++ b/test/cfg/windows.cpp @@ -681,7 +681,6 @@ void ignoredReturnValue() // cppcheck-suppress leakReturnValNotUsed CreateEventEx(NULL, L"test", CREATE_EVENT_INITIAL_SET, EVENT_MODIFY_STATE); - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed _malloca(10); // cppcheck-suppress ignoredReturnValue @@ -693,10 +692,8 @@ void ignoredReturnValue() // cppcheck-suppress ignoredReturnValue GetProcessHeap(); - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed HeapAlloc(GetProcessHeap(), 0, 10); - // cppcheck-suppress ignoredReturnValue // cppcheck-suppress leakReturnValNotUsed HeapReAlloc(GetProcessHeap(), 0, 1, 0); diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 676a77955..b7f9a5280 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2311,6 +2311,7 @@ private: TEST_CASE(getAllocationType); TEST_CASE(crash1); // #10729 + TEST_CASE(openDevNull); // #9653 } void functionParameter() { @@ -2852,6 +2853,14 @@ private: "}"); ASSERT_EQUALS("", errout.str()); } + + void openDevNull() { + check("void f() {\n" // #9653 + " (void)open(\"/dev/null\", O_RDONLY);\n" + " open(\"/dev/null\", O_WRONLY);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } }; REGISTER_TEST(TestMemleakNoVar)