Error analysis

January 14th, 2009

I also have something interesting to mention: I’ve been working with Taras and Dave‘s static analysis system, writing an error-code checking analysis.

The notion of my particular analysis is that you should be able to tell the compiler that some function like:

  bool tryToDoSomethingScary();

is the sort of function that uses its return value as a possible error code, where for example the return value of false should mean an error occurred, and someone ought to handle the error. If you do so — via a gcc attribute annotation like __attribute__((user("SETS_ERR"))), you can then run my analysis script on code that calls the error-code signaling function, and gcc will enforce a bunch of subtle-but-important rules:

  1. If you call the the function you can’t ignore its return value. Someone has to check it.
  2. If you call the function, and check the return code (as you must), all subsequent possible code paths after the call must satisfy a bunch of checks:
    1. On a path corresponding to a false return — indicating an error being signaled — you must either call a matching function annotated as “handling” the error in question or you must annotate the calling function to return the same type of error itself, and you must return false on the error path.
    2. On a path corresponding to a true return — indicating a lack of error — you must not call to clean up the error, since no error is pending.

This results in something similar to the model of checked exceptions in Java — the compiler won’t let you get away with ignoring, mis-handling or mis-propagating an error code — only using explicit error codes rather than try/throw/catch and exception specifiers.

I’m impressed that this flow sensitive feature can be implemented in 300 lines of javascript and bolted into a production C++ compiler with a week’s work (and a lot of hand-holding from the pros). Everyone who writes C++ should try.

Comments are closed.