32bitmicro

World is programmable!

RaspberryPico link

Projects

Pico-SDK Static Code Analysis

This project demonstrates static code analysis of Rasberry Pico SDK.

Github project link

Static analysis with GCC compiler requires using -fanalyzer option see this page

Running GCC static analysis on pico-sdk code reveals a single issue use of using uninitialized value in pico_divider_test.c file.

/home/pawel/src/MCU/RasperryPico/pico-sdk/test/pico_divider_test/pico_divider_test.c:270:16: warning: use of uninitialized value 'time_32(rnd32(), rnd32() / (2147483648 >> bit), &compiler_div_s32)' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]

/home/pawel/src/MCU/RasperryPico/pico-sdk/test/pico_divider_test/pico_divider_test.c:305:20: warning: use of uninitialized value 'time_64(rnd64() >> extra, (long long unsigned int)b, & pico_div_s64)' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]

/home/pawel/src/MCU/RasperryPico/pico-sdk/test/pico_divider_test/pico_divider_test.c:320:20: warning: use of uninitialized value 'time_64(a,  b, & compiler_div_u64)' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]

/home/pawel/src/MCU/RasperryPico/pico-sdk/test/pico_divider_test/pico_divider_test.c:321:20: warning: use of uninitialized value 'time_64(a,  b, & pico_div_u64)' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]

GCC provides detailed analysis of the issue. Here is a an example of the output for the first warning:

[ 14%] Building C object pico-sdk/test/pico_divider_test/CMakeFiles/pico_divider_test.dir/pico_divider_test.c.obj
/home/pawel/src/MCU/RasperryPico/pico-sdk/test/pico_divider_test/pico_divider_test.c: In function 'perf_test':
/home/pawel/src/MCU/RasperryPico/pico-sdk/test/pico_divider_test/pico_divider_test.c:270:16: warning: use of uninitialized value 'time_32(rnd32(), rnd32() / (2147483648 >> bit), &compiler_div_s32)' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
  270 |             tc += time_32(a, b, compiler_div_s32);
      |                ^~
  'main': events 1-2
    |
    |  328 | int main() {
    |      |     ^~~~
    |      |     |
    |      |     (1) entry to 'main'
    |......
    |  346 |   perf_test();
    |      |   ~~~~~~~~~~~
    |      |   |
    |      |   (2) calling 'perf_test' from 'main'
    |
    +--> 'perf_test': events 3-8
           |
           |  257 | void perf_test() {
           |      |      ^~~~~~~~~
           |      |      |
           |      |      (3) entry to 'perf_test'
           |......
           |  260 |     for(int bit = 30; bit>=0; bit--) {
           |      |                       ~~~~~~
           |      |                          |
           |      |                          (4) following 'true' branch (when 'bit >= 0')...
           |  261 |         int div = 1u << (31-bit);
           |      |         ~~~
           |      |         |
           |      |         (5) ...to here
           |......
           |  264 |         for (int i = 0; i < N; i++) {
           |      |                         ~~~~~
           |      |                           |
           |      |                           (6) following 'true' branch (when 'i <= 999')...
           |  265 |             int a = rnd32();
           |      |             ~~~
           |      |             |
           |      |             (7) ...to here
           |......
           |  270 |             tc += time_32(a, b, compiler_div_s32);
           |      |                ~~
           |      |                |
           |      |                (8) use of uninitialized value 'time_32(rnd32(), rnd32() / (2147483648 >> bit), &compiler_div_s32)' here
           |

GCC full log of static analysis