[cfe-dev] -fcatch-undefined-behavior testing

Török Edwin edwintorok at gmail.com
Wed Dec 16 13:23:47 PST 2009

On 2009-12-16 22:07, Török Edwin wrote:
> On 2009-12-16 20:12, Mike Stump wrote:
>> On Dec 16, 2009, at 3:39 AM, Daniel Dunbar wrote:
>>> Have you considered running this on an LLVM nightly test run?
>> Love to see the results; my email was to solicit others into trying the feature out on their favorite code.
>> Also, I guess I should say, if people have undefined behavior that they would just love to see runtime checks for, maybe to catch portability problems, or to catch security problems or just random bugs in code, I've love to hear the ideas.
> Well some of the ideas I have would overlap with what SAFEcode already does.
> Ideally it should catch all the undefined behavior that would cause
> different behavior when program is compiled with -O0 vs compiled with
> -O2. Or in other words, any undefined behavior that could break (the
> user's expectations) due to compiler optimizations.
> That "idea" is too vague to be useful, so below are some specific ideas,
> some already crash at runtime but a better error message
> would be very useful.
> A general idea first: please allow for individual tests to be turned
> on/off, for example I may want to test only for
> array overflows, only for shift overflows, etc.
> Or if I compile with -fno-strict-aliasing I wouldn't care about aliasing
> violations, etc.
> 1. support something similar to gcc's "-fmudflapth":
>   It is useful on occasion when valgrind can't find errors (such as
> overrunning a stack allocated buffer). You already do something similar,
> however I'd be interested to catch bugs when the buffer (of constant
> size) is declared in one function, and the buggy store/load is in
> another function.
> 2. alignment testing
>  This is something I haven't found a tool for. Especially important for
> sparc, but thats needs a sparc CPU for testing.
> It'd be nice if we could catch these bugs by running on x86, and
> assuming sparc alignment rules. Even on x86, vectorized variables need
> to be aligned, or it crashes.
> 3. pointer overflows, undefined behavior in userspace
> 4. aliasing rule violations via casts
>  Although LLVM doesn't have TBAA yet, clang could catch some TBAA
> errors, when the dynamic type of a casted value doesn't match
> 5. other aliasing violations
>  - restrict qualifier not obeyed (i.e. a noalias pointer indeed aliases
> something)
>  - two pointers have equal value, yet according to aliasing rules they
> never alias (for example overflowing from one struct field to another)
> 6. pure/const qualifier checks
> 7. calling convention mismatches
> 8. noreturn that returns
> 9. division by zero due to overflow (32-bit division of -2147483648 by -1)
> 10.  Access to a variable from multiple threads without proper
> locking/atomic instructions
> 11. weak symbols with an initializer, overriden  with another
> initializer at link time (optimizer may assume the  initial value it has
> seen)
> 12. use of uninitialized variable
> 13. calling function using wrong prototype (for example library compiled
> with certain flags, function has 5 params, user
> compiles with other flags, function has 4 params. At runtime it will
> crash/misbehave for C.
> Even for C++ its a problem if structures have different
> layout/elements). The types' structure should match, including pointed
> to types
> I had a list with some more ideas, but I can't find that file right now,
> if I find it, I'll follow up.

14. malloc of possibly wrapped value: x = malloc(a+b); memset(x, 0, a);
memset(x+a, 0, b); // if a+b overflowed, then a+b < a, or a+b < b
15. incorrect buffer limit checks:
     if (tainted_signed_value <= (long) some_limit)
a[tainted_signed_value]; //<--- code should check for negative values as
     same situation if comparison becomes signed due to integer
promotion rules.
16. a warning (not undef behavior, but could be a mistake) for integer
promotion of signed value to unsigned when target variable is signed:
int x=-2; unsigned y=1; long a0 = x + y; value of a0 will be 4294967295,
though a0 is a signed variable!

Best regards,

More information about the cfe-dev mailing list