views:

126

answers:

1

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
+2  A: 

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.

Jens Gustedt
Does the job, thanks :) I must say, I came up with the most obvious and the most creative bloody memory leaks I could dream up, and it let all of them pass. Clearly it knows enough to know I was testing it.
detly
@detly: has been fun, learned clang by it :) for my curiosity what are leaks in a context of static analysis?
Jens Gustedt
Well I'm not 100% sure, but I was under the impression that many static analysis tools, including clang, can detect potential runtime memory problems (such as `p = malloc(...); p = q;`). I could be wrong about that.
detly
Hm, it could, if they somehow hardcode that `malloc` does an allocation. Shouldn't this be documented somewhere? At least it should give you an "initialization not used" warning in this trivial case :) But for dynamic memory problems there is `valgrind` which does an excellent job, so perhaps the concentrate their efforts to other potential bugs.
Jens Gustedt
That seems reasonable. Usually I don't use dynamic memory, so it's not an issue, I was just curious whether it would pick it up. Also, I can't use valgrind anyway, since it's code for the PIC32MX (ie. embedded).
detly