These reports with regard to DEBUGASSERT have been reported before.

DEBUGASSERT is defined in a ccouple of ways.  Here is one way:

   do                                      \
        {                                     \
          if (predict_false(!(f)))            \
            __assert(__ASSERT_FILE__,         \
                     __ASSERT_LINE__, 0);     \
        }                                     \
      while (0)
   #endif

   #ifdef CONFIG_DEBUG_ASSERTIONS
   #  define DEBUGPANIC()   PANIC()
   #  define DEBUGASSERT(f) ASSERT(f)
   #  define DEBUGVERIFY(f) VERIFY(f)
   #else
   #  define DEBUGPANIC()
   #  define DEBUGASSERT(f) ((void)(1 || (f)))
   #  define DEBUGVERIFY(f) ((void)(f))
   #endif

if CONFIG_DEBUG_ASSERTIONS  is not defined, then there is no test for NULL pointers, so this is not the case the tool is complaining about.

if CONFIG_DEBUG_ASSERTIONS then __assert() is called.  __assert() is a no-return function.  In that case, it is impossible to reach the code that uses the pointer.

So the tool is wrong.  I suspect that it is wrong because it does not understand no-return functions.  At any rate, no code change is appropriate.

On 10/10/2023 12:33 PM, Daniel Appiagyei wrote:
Hey,
I was running the [cppcheck](https://cppcheck.sourceforge.io/) static
analysis tool, found a few potential bugs, and wrote the following to share
how tools like this can help us ensure the integrity of our code. The
following are some bugs found. If anyone is interested in running cppcheck
on their project, scroll to the bottom for a HOW-TO. Is using a static
analysis tool like this something we'd be interested in adding to ci/cd?

*The following were found in NuttX 12.2.1*
## Null pointer dereference
#### 1: sched/signal/sig_dispatch.c:325
```
src/deps/nuttx/sched/signal/sig_dispatch.c:325:26: warning: Either the
condition 'info!=NULL' is redundant or there is possible null pointer
dereference: info. [nullPointerRedundantCheck]
         stcb, stcb->pid, info->si_signo, info->si_code,


                          ^


src/deps/nuttx/sched/signal/sig_dispatch.c:329:36: note: Assuming that
condition 'info!=NULL' is not redundant

   DEBUGASSERT(stcb != NULL && info != NULL);


                                    ^


src/deps/nuttx/sched/signal/sig_dispatch.c:325:26: note: Null pointer
dereference

         stcb, stcb->pid, info->si_signo, info->si_code,


                          ^


```

####  2: sched/signal/sig_dispatch.c:326
```
src/deps/nuttx/sched/signal/sig_dispatch.c:326:9: warning: Either the
condition 'info!=NULL' is redundant or there is possible null pointer
dereference: info. [nullPointerRedundantCheck]
         info->si_value.sival_int,


         ^
src/deps/nuttx/sched/signal/sig_dispatch.c:329:36: note: Assuming that
condition 'info!=NULL' is not redundant
   DEBUGASSERT(stcb != NULL && info != NULL);
                                    ^
src/deps/nuttx/sched/signal/sig_dispatch.c:326:9: note: Null pointer
dereference
         info->si_value.sival_int,
         ^
```

#### 3: sched/signal/sig_dispatch.c:327
```
src/deps/nuttx/sched/signal/sig_dispatch.c:327:41: warning: Either the
condition 'info!=NULL' is redundant or there is possible null pointer
dereference: info. [nullPointerRedundantCheck]
         sigismember(&stcb->sigprocmask, info->si_signo) == 1 ? "YES" :
"NO");
                                         ^
src/deps/nuttx/sched/signal/sig_dispatch.c:329:36: note: Assuming that
condition 'info!=NULL' is not redundant
   DEBUGASSERT(stcb != NULL && info != NULL);
                                    ^
src/deps/nuttx/sched/signal/sig_dispatch.c:327:41: note: Null pointer
dereference
         sigismember(&stcb->sigprocmask, info->si_signo) == 1 ? "YES" :
"NO");
                                         ^
```

#### 4: src/deps/nuttx/libs/libc/stdlib/lib_mbstowcs.c:42
```
src/deps/nuttx/libs/libc/stdlib/lib_mbstowcs.c:42:36: error: Null pointer
dereference [nullPointer]

   return mbsrtowcs(dst, &src, len, NULL);


                                    ^
```

#### 5: nuttx/libs/libc/stdlib/lib_wcstombs.c:38
```
src/deps/nuttx/libs/libc/stdlib/lib_wcstombs.c:38:36: error: Null pointer
dereference [nullPointer]
   return wcsrtombs(dst, &src, len, NULL);
```

#### 6: drivers/net/netdev_upperhalf.c:168
```
src/deps/nuttx/drivers/net/netdev_upperhalf.c:168:42: warning: Either the
condition 'dev' is redundant or there is possible null pointer dereference:
dev. [nullPointerRedundantCheck]
   FAR struct netdev_upperhalf_s *upper = dev->d_private;
                                          ^
src/deps/nuttx/drivers/net/netdev_upperhalf.c:170:15: note: Assuming that
condition 'dev' is not redundant
   DEBUGASSERT(dev && pkt);
               ^
src/deps/nuttx/drivers/net/netdev_upperhalf.c:168:42: note: Null pointer
dereference
   FAR struct netdev_upperhalf_s *upper = dev->d_private;
                                          ^
```

#### 7: sched/task/task_init.c:90
```
src/deps/nuttx/sched/task/task_init.c:90:19: warning: Either the condition
'tcb' is redundant or there is possible null pointer dereference: tcb.
[nullPointerRedundantCheck]
   uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK;
                   ^
src/deps/nuttx/sched/task/task_init.c:96:15: note: Assuming that condition
'tcb' is not redundant
   DEBUGASSERT(tcb && ttype != TCB_FLAG_TTYPE_PTHREAD);
               ^
```

## Signed integer overflow
The [C standard](
https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Integer-Overflow-Basics.html)
treats _signed_ integer overflow as undefined behavior.
#### 8: arch/arm/src/armv7-m/arm_fpuconfig.c:75
```
src/deps/nuttx/arch/arm/src/armv7-m/arm_fpuconfig.c:75:15: error: Signed
integer overflow for expression '1<<31'. [integerOverflow]

   regval &= ~(NVIC_FPCCR_ASPEN | NVIC_FPCCR_LSPEN);
```

#### 9: arch/arm/src/armv7-m/arm_hardfault.c:169
```
src/deps/nuttx/arch/arm/src/armv7-m/arm_hardfault.c:169:19: error: Signed
integer overflow for expression '1<<31'. [integerOverflow]
   else if (hfsr & NVIC_HFAULTS_DEBUGEVT)
```

## Buffer Overflow
#### 10: nuttx/tools/mkdeps.c:795
```
src/deps/nuttx/tools/mkdeps.c:795:12: warning: Either the condition
'cmdlen>=10240' is redundant or the array 'g_command[10240]' is accessed at
index 10240, which is out of bounds. [arrayIndexOutOfBoundsCond]
   g_command[cmdlen] = '\0';
            ^
src/deps/nuttx/tools/mkdeps.c:781:18: note: Assuming that condition
'cmdlen>=10240' is not redundant
       if (cmdlen >= MAX_BUFFER)
                  ^
src/deps/nuttx/tools/mkdeps.c:794:3: note: cmdlen is incremented', new
value is 10240
   cmdlen++;
   ^
src/deps/nuttx/tools/mkdeps.c:795:12: note: Array index out of bounds
   g_command[cmdlen] = '\0';
            ^
```

## Uninitialized Variable
#### 11: src/deps/nuttx/tools/mkdeps.c:138
```
src/deps/nuttx/tools/mkdeps.c:138:23: warning: Uninitialized variable:
*saveptr [uninitvar]
   else if (saveptr && *saveptr)
                       ^
src/deps/nuttx/tools/mkdeps.c:962:39: note: Calling function 'my_strtok_r',
3rd argument '&lasts' value is <Uninit>
   while ((file = strtok_r(files, " ", &lasts)) != NULL)
                                       ^
src/deps/nuttx/tools/mkdeps.c:138:23: note: Uninitialized variable: *saveptr
   else if (saveptr && *saveptr)
                       ^
```

## Background
I needed a way to create a [compile_commands.json](
https://cmake.org/cmake/help/latest/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html)
from `make`, so I installed [bear](https://github.com/rizsotto/Bear) from
my ubuntu package manager. I cloned `cppcheck` from its [github repo](
https://github.com/danmar/cppcheck) and built it by following the [cmake
instructions](https://github.com/danmar/cppcheck#cmake).

Next, I ran `make clean` followed by `bear make` on my project, which
generated the `compile_commands.json`.
Then, I ran:
```
/path/to/build/bin/cppcheck --version
Cppcheck 2.13 dev

/path/to/build/bin/cppcheck --project=/path/to/compile_commands.json
-j8 --std=c++11 --std=c89 --quiet  --enable=warning
```

Reply via email to