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

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

我可以做些什么来触发它们,或者我应该将其视为限制/错误?

#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。

xiongming321 回答:Clang 消毒剂未读取未初始化的内存

来自the documentation

当堆栈或堆分配的内存被分配时,会出现未初始化的值 在写之前阅读。 MSan 检测这些值的情况 影响程序执行。

MSan 是位精确的:它可以跟踪位域中未初始化的位。它 将容忍复制未初始化的内存,以及简单的逻辑 和算术运算。一般来说,MSan 默默地 跟踪内存中未初始化数据的传播,并报告一个 当代码分支被采用(或不采用)时发出警告,具体取决于 未初始化的值。

也就是说,为了尽量减少误报,在抱怨之前,clang 会等待,直到确信未初始化的内存确实对程序执行有影响(采用不同的分支,从 main 返回不同的值等)。复制未初始化的内存可能是无害的。

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

使用 MSan 构建程序中的所有代码(包括它使用的库,特别是 C++ 标准库)至关重要。

这种限制是这种消毒剂远不如 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;
      |                            ^~~~~
本文链接:https://www.f2er.com/16008.html

大家都在问