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
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
.