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

Reply via email to