Example code to trigger Clang's static analyse

2019-02-06 12:26发布

问题:

I would like to see a small but complete snippet of code that will cause Clang's static analyser to complain. My motivation is mostly that I'm trying to get it to work on my PIC32 code, and I need a way to distinguish between "all the code is fine" and "it's not actually doing anything". It's also partly curiosity, since I can't seem to come up with a simple example myself.

C89/ANSI or C99 is fine, and ideally I'd like to see it pick up a simple memory leak. My usage is

clang --analyze test.c

回答1:

I found a "bug" in my code (the only one ;-) that triggers by that, and that is not detected by -Wall. I cooked it down to the following

struct elem {
  struct elem *prev;
  struct elem *next;
};

#define ELEM_INITIALIZER(NAME) { .prev = &(NAME), .next = &(NAME), }

struct head {
  struct elem header;
};

#define HEAD_INITIALIZER(NAME) { .header = ELEM_INITIALIZER(NAME.header) }

int main(int argc, char ** argv) {
  struct head myhead = HEAD_INITIALIZER(myhead);
}

This is a relatively straight forward implementation of a linked list, but this is not important here. The variable myhead is unused in a common sense application of the term, but for the compiler it is used since inside the initializer the address of a field is taken.

clang correctly analyzes this as

/tmp 11:58 <722>% clang --analyze test-clang.c
test-clang.c:25:15: warning: Value stored to 'myhead' during its initialization is never read
  struct head myhead = HEAD_INITIALIZER(myhead);
              ^        ~~~~~~~~~~~~~~~~~~~~~~~~
1 diagnostic generated.

Edit: I found another one that also detects stack memory proliferation

char const* myBuggyFunction(void) {
  return (char[len + 1]){ 0 };
}

This is not detected by gcc, open64 or clang with -Wall, but by clang with --analyze.