编译器警告 C5045

如果指定了 /Qspectre 开关,编译器会插入内存负载的 Spectre 缓解

备注

警告 C5045 允许查看代码中的哪些模式会导致 Spectre 缓解,比如 LFENCE,该缓解会在指定 /Qspectre 编译器选项时被插入。 这样,便可以确定哪些代码文件受到了安全问题的影响。 此警告纯粹是信息性的:使用 /Qspectre 开关重新编译之前不会插入缓解措施。 C5045 的功能独立于 /Qspectre 开关,因此可以在同一编译中使用它们。

该警告是 Visual Studio 2017 版本 15.7 中的新增功能,但是默认关闭。 使用 /Wall 启用默认关闭的所有警告,或 /wn5045 启用 C5045 作为级别 n 警告。 在 IDE 中,默认警告级别为 /W3,可以在“项目属性页”对话框中启用此警告。 打开配置属性>C/C++>命令行,并在“其他选项”框中添加 /w35045,然后选择“确定”。 有关详细信息,请参阅默认关闭的编译器警告。 有关如何按编译器版本禁用警告的信息,请参阅由编译器版本引发的编译器警告

示例

使用 /Wall/w35045/W3 选项在 Visual Studio 2017 版本 15.7 编译时,以下示例会引发警告 C5045:

// C5045.cpp
// Compile with: cl /EHsc /W3 /w35045 C5045.cpp

int G, G1, G2;

__forceinline
int * bar(int **p, int i)
{
    return p[i];
}

__forceinline
void bar1(int ** p, int i)
{
    if (i < G1) {
        auto x = p[i]; // C5045: mitigation here
        G = *x;
    }
}

__forceinline
void foo(int * p)
{
    G = *p;
}

void baz(int ** p, int i)
{
    if (i < G1) {
        foo(bar(p, i + G2));
    }
    bar1(p, i);
}

int main() { }

启用警告时编译器输出如下所示:

C:\Users\username\source\repos\C5045>cl /W3 /w35045 C5045.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26431 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

C5045.cpp
c:\users\username\source\repos\c5045\c5045.cpp(16) : warning C5045: Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
c:\users\username\source\repos\c5045\c5045.cpp(15) : note: index 'i' range checked by comparison on this line
c:\users\username\source\repos\c5045\c5045.cpp(17) : note: feeds memory load on this line
Microsoft (R) Incremental Linker Version 14.14.26431.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:C5045.exe
C5045.obj

警告消息显示,缓解措施已插入第 16 行。 它还指出,需要缓解措施,因为第 15 行的索引 i 会馈送第 17 行的内存负载。 猜测是在 bar 和 bar1 上完成的,但缓解措施在第 16 行时有效。

另请参阅

推理执行端通道的 C++ 开发人员指南
/Qspectre
spectre