Поделиться через


Предупреждение компилятора C5045

Компилятор вставляет устранение рисков Spectre для загрузки памяти, если указан параметр /Qspectre

Замечания

Предупреждение C5045 позволяет увидеть, какие шаблоны в коде вызывают устранение рисков Spectre, например LFENCE, для вставки при указании параметра компилятора /Qspectre . Это позволяет определить, какие файлы кода влияют на проблему безопасности. Это предупреждение является чисто информационным: устранение рисков не вставляется до тех пор, пока не выполняется повторная компиляция с помощью переключателя /Qspectre . Функциональные возможности C5045 не зависят от коммутатора /Qspectre , поэтому их можно использовать в одной компиляции.

Это предупреждение новое в Visual Studio 2017 версии 15.7 и по умолчанию отключено. Используйте /Wall для включения всех предупреждений, отключенных по умолчанию, или /wn5045, чтобы включить C5045 в качестве предупреждения уровня n. В интегрированной среде разработки уровень предупреждения по умолчанию — /W3, и это предупреждение можно включить в диалоговом окне страниц свойств проекта. Откройте командную строку свойств>конфигурации C/C++>и в поле "Дополнительные параметры" добавьте /w35045 и нажмите кнопку "ОК". Дополнительные сведения см. в разделе "Предупреждения компилятора", отключенные по умолчанию. Сведения об отключении предупреждений по версии компилятора см. в предупреждениях компилятора по версии компилятора.

Пример

В следующем примере возникает предупреждение C5045 при компиляции Visual Studio 2017 версии 15.7 с параметрами /Wall или /w35045 и /W3 :

// 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. Кроме того, отмечается, что требуется устранение рисков, так как индекс i в строке 15 передает нагрузку памяти в строке 17. Спекуляции выполняются через бар и бар1, но устранение является эффективным при размещении в строке 16.

См. также

Руководство разработчика C++ по сторонним каналам при спекулятивном выполнении команд
/Qspectre
spectre