Package: cppcheck Version: 2.3-1 Severity: normal Thank you for packaging cppcheck 2.3! I'm pleased to confirm that the bugs that I reported in #943463 were indeed fixed in that release.
Unfortunately, it appears to have introduced a few more false positives in this general area. Here is a minimized test case: #include <stdint.h> #include <some-header.h> int test_a(void) { uint32_t pag; struct some_struct foo; pag = (uint32_t) -1; /* The bug disappears if &pag is not cast to void *. */ foo.pag = (void *) &pag; foo.pag_size = sizeof(pag); result = some_call(&foo); if (result == 0) return pag != (uint32_t) -1; } int test_b(void) { char **string = NULL; /* The bug disappears if retval is not included in the check. */ retval = some_other_call(&string); if (retval && string && string[0]) return 0; return -1; } void test_c(void) { some_type *foo = NULL; other_type blah; retval = call_a(&foo); if (retval != 0) goto done; blah.flag = foo->flag; call_b(&blah); done: if (foo != NULL) free_foo(foo); } And here is the output from cppcheck: % cppcheck --enable=warning,style foo.c Checking foo.c ... foo.c:16:20: style: Condition 'pag!=(uint32_t)-1' is always false [knownConditionTrueFalse] return pag != (uint32_t) -1; ^ foo.c:10:11: note: Assignment 'pag=(uint32_t)-1', assigned value is 4294967295 pag = (uint32_t) -1; ^ foo.c:16:20: note: Condition 'pag!=(uint32_t)-1' is always false return pag != (uint32_t) -1; ^ foo.c:22:12: warning: Either the condition 'retval&&string' is redundant or there is possible null pointer dereference: string. [nullPointerRedundantCheck] char **string = NULL; ^ foo.c:26:16: note: Assuming that condition 'retval&&string' is not redundant if (retval && string && string[0]) ^ foo.c:22:12: note: Null pointer dereference char **string = NULL; ^ foo.c:40:17: warning: Either the condition 'foo!=NULL' is redundant or there is possible null pointer dereference: foo. [nullPointerRedundantCheck] blah.flag = foo->flag; ^ foo.c:44:13: note: Assuming that condition 'foo!=NULL' is not redundant if (foo != NULL) ^ foo.c:40:17: note: Null pointer dereference blah.flag = foo->flag; ^ The common theme in all three cases is that a variable is passed by address to another function (via adding its address to a struct or just directly), and cppcheck loses track of the fact that function may have changed its value. In the first case, I think the (void *) cast is the key. If it's removed, cppcheck understands the code correctly. (But this is sometimes required by badly-designed APIs.) In the second case, something about adding retval to the test messes up its understanding of the data flow. The third case seems similar to the previous set of bugs, although note that it only happens with assignment. If that line is instead replaced with something like call_c(foo->flag), there is no error. (Apologies, I haven't reported these upstream since they want bug reporters to catch them on IRC to get a Trac account created.) -- System Information: Debian Release: bullseye/sid APT prefers unstable APT policy: (990, 'unstable'), (500, 'unstable-debug'), (1, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 5.9.0-4-amd64 (SMP w/8 CPU threads) Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages cppcheck depends on: ii libc6 2.31-5 ii libgcc-s1 10.2.1-1 ii libpcre3 2:8.39-13 ii libstdc++6 10.2.1-1 ii libtinyxml2-8 8.0.0+dfsg-2 ii libz3-4 4.8.9-1 ii python3 3.9.0-4 ii python3-pygments 2.7.1+dfsg-1 cppcheck recommends no packages. Versions of packages cppcheck suggests: ii clang 1:11.0-51 pn clang-tidy <none> pn cppcheck-gui <none> -- no debconf information