Clang 消毒剂缺少未初始化内存的读取

Clang sanitizers missing a read from uninitialized memory

我有以下代码,我有信心从垃圾内存中读取,但 clang 消毒剂不会抱怨。

我可以做些什么来触发它们,还是我应该接受它作为 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;
}

我试过设置 O0,因为这有时会有帮助,但这次没有。

godbolt

我也愿意使用 gcc,但我认为 gcc 没有内存清理器,只有 asan。

来自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.

也就是为了尽量减少误报,在报错之前,clang会一直等到确信未初始化的内存确实对程序执行有影响(走不同的分支,returns不同的值来自主要等)。复制未初始化的内存可能是无害的。

在您的特定程序中,未初始化值的实际使用发生在标准库中,甚至可能仅发生在 C 库中,它尚未使用 MSan 进行检测,因此您不会收到警告。

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

这种限制是这种消毒剂不如 ASan 或 UBSan 受欢迎的主要原因。

回到这个简单的程序,各种静态分析工具都可以检测到问题,即使只是 g++ -Wall -O 也会发出警告,但要注意误报并不少见。

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;
      |                            ^~~~~