c++clangsanitizermemory-sanitizer

Clang sanitizers missing a read from uninitialized memory


I have the following code, that I am confident reads from garbage memory, but clang sanitizers do not complain.

Is there something I can do to make them trigger or I should just accept this as limitation/bug?

#include <algorithm>
#include <iostream>
#include <vector>

struct B{
    int x;
};

struct D : public B{
    short y;
    D& operator = (const D& other) {
        y = other.y;
        return *this;
    }
};

int main() {
    D var1{4,7},var2;
    var2=var1;
    std::cout << var2.x << "   " << var2.y << std::endl;
}

I have tried setting O0 since that sometimes helps, but this time it did not.

godbolt

I am open to using gcc also, but I think gcc does not have memory sanitizer, only asan.


Solution

  • From the documentation

    Uninitialized values occur when stack- or heap-allocated memory is read before it is written. MSan detects cases where such values affect program execution.

    MSan is bit-exact: it can track uninitialized bits in a bitfield. It will tolerate copying of uninitialized memory, and also simple logic and arithmetic operations with it. In general, MSan silently tracks the spread of uninitialized data in memory, and reports a warning when a code branch is taken (or not taken) depending on an uninitialized value.

    That is, in order to minimize false positives, before complaining, clang waits until it is convinced that the uninitialized memory really has an impact on the program execution (takes a different branch, returns a different value from main, etc). Copying uninitialized memory around could be innocuous.

    In your particular program, the actual use of the uninitialized value happens in the standard library, possibly even just in the C library, which haven't been instrumented with MSan, so you do not get a warning.

    It is critical that you should build all the code in your program (including libraries it uses, in particular, C++ standard library) with MSan.

    This constraint is the main reason why this sanitizer is much less popular than say ASan or UBSan.

    To come back to this simple program, various static analysis tools can detect the issue, even just g++ -Wall -O will warn, but be aware that false positives are not rare.

    x.cc: In function 'int main()':
    x.cc:20:28: warning: 'var2.D::<anonymous>.B::x' is used uninitialized [-Wuninitialized]
       20 |     std::cout << var2.x << "   " << var2.y << std::endl;
          |                            ^~~~~