Do clang sanitisers check for uninitialised memory?

Viewed 90

I have a simple example:

#include <stdio.h>

int main()
{
    unsigned long int a;
    
    printf("a = 0x%lx\n", a);

    return 0;
}

demo

Clearly, this code has UB. But when I try to sanitise it with:

clang -fsanitize=undefined -O0 -xc main.cpp && ./a.out

it runs "fine". Is this behaviour expected? Should I be using another sanitiser for this?

Update:

  • It doesn't seem to work for c++ too with -fsanitize=memory.
  • And for dynamic allocations as well.

Update:

I understand that my example is trivial. And a good compiler could detect such issue. I just wrote a simple example to understand if the feature works at all. There is a wide range on uninitialised memory errors that cannot be detected by a compiler. For instance, if an uninitialised memory chunk was allocated in one .cpp and used in another .cpp.

1 Answers

The issue here is that the standard library is not compiled with sanitiser enabled. And the uninitialised variable is referenced in printf. It's enough to read from this variable in the same function to trigger the sanitiser:

#include <stdio.h>

int main()
{
    unsigned long int a;
    
    if (a == 42) {
        printf("a = 0x%lx\n", a);
    }

    return 0;
}
clang++ -fsanitize=memory -O0 main.cpp && ./a.out
==28857==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x494af6 in main (/tmp/1622902848.6385949/a.out+0x494af6)
    #1 0x7fefc72bc82f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291
    #2 0x419de8 in _start (/tmp/1622902848.6385949/a.out+0x419de8)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/tmp/1622902848.6385949/a.out+0x494af6) in main
Exiting

demo

And yes, as @Alan Birtles noted, it needs -fsanitize=memory.

Related