Hi

I would like to have some advice regarding static code analysis and GCC.
I've just reviewed several tools like Klocwork, Coverity, CodeSonar and 
PolySpace.
These tools offer alot of features and all tools seems to find different types 
of defects.
The tool that found most bugs on our code was Coverity, but it is also the most 
expensive tool.

But basically I would most like just to find very "simple" basic errors like 
NULL-dereferences and buffer overruns.
I attach a small example file with some very obvious errors like 
NULL-dereferences and buffer overruns.

This buggy file compiles fine though without any warnings at all with GCC as 
expected

    gcc -o example example.c -W -Wall -Wextra

I tried to add checking with mudflap:

    gcc -fmudflap -o example example.c -W -Wall -Wextra -lmudflap

Then I found all defects in run-time, but I had to run the program so I could 
not find all potential errors in compile-time.
Also Valgrind could be used to check run-time bugs, but I'm not 100% sure I can 
cover all execution paths in my tests (I also tried gcov).

I tried to analyze my example file with CLANG, then I found "uninitialized" 
issues and NULL-pointers, but not buffer overruns:

    clang --analyze example.c
    example.c:7:3: warning: Dereference of null pointer loaded from variable 'a'
    example.c:41:3: warning: Undefined or garbage value returned to caller  

About NULL-checks and buffer-overruns, is there any possible path to get such 
checkers into a standard GCC, maybe in just some very limited level?
I've checked the "MyGCC" (http://mygcc.free.fr) patch on Graphite, but it has 
been rejected, could it be rewritten somehow as a standard opt_pass to just 
find NULL-derefs?

I've also checked TreeHydra in Mozilla project 
(https://developer.mozilla.org/en/Treehydra) that gives JavaScript interface to 
GIMPEL.
Is the GCC4.5.x plugin API something that is recommended to use to implement 
such features, is performance okey to not have it as a core opt-pass?

I'm willing to put some free time into this matter if it turns out its possible 
to add some tree SSA optimization pass that could find some limited set of 
errors.
Example given if some value is constant NULL and dereferenced, or some element 
if accessed outside a constant length buffer using a constant index.
What is your recommended path to move forward using GCC and basic static code 
analysis?

About un-initialized values I found some additional info, it seems to be hard 
to solve...
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18501
  http://lists.cs.uiuc.edu/pipermail/cfe-dev/2011-February/013170.html

Thanks and Best Regards
/Fredrik

--------------------------------------------------------------
#include <stdio.h>

// Example1: null pointer de-reference
int f1(void)
{
  int* a = NULL;
  *a = 1;
  return *a;
}

// Example2: buffer overrun global variable
char v2[1];
char* f2(void)
{
  v2[-1] = 1;
  v2[0]  = 1;
  v2[1]  = 1;
  return (char*)v2;
}

// Example3: buffer overrun local variable
int f3(void)
{
  char v3[1];
  v3[-1] = 1;
  v3[0]  = 1;
  v3[1]  = 1;
  return v3[-1] + v3[0] + v3[1] + v3[2];
}

// Example4: uninitialized memory access
int f4(void)
{
  char v4[1];
  return v4[0];
}

// Examples NULL dereference and buffer overruns
int main(void)
{
  int t1 = f1();
  printf("test1 %d\n", t1);

  void *t2 = f2();
  printf("test2 %08x\n", (unsigned int)t2);

  int t3 = f3();
  printf("test3 %d\n", t3);

  int t4 = f4();
  printf("test4 %d\n", t4);

  return 0;
}

Reply via email to