Использование #pragma для удаления предупреждений о clang на основе проверки clang

Я хочу удалить / игнорировать предупреждение о лязгах для блока кода и нашел несколько примеров того, как использовать для этого прагамы. Например, если отображается предупреждение unused-variable, вы можете отключить его, используя:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"

int a;

#pragma clang diagnostic pop

Однако проблема в том, что я не получаю предупреждения на выходе при создании репозитория, я только узнаю, какая проверка clang выдает предупреждение ... И я не могу найти никаких других вопросов или документации, где это кейс. Вот как выглядит мой результат:

warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]

Я пробовал сотни различных комбинаций того, как игнорировать это, но ничего не работает (использование // NOLINT не является жизнеспособным вариантом). Среди вещей, которые я пробовал, вот некоторые:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winline-new-delete"
#pragma clang diagnostic ignored "-Wmost"
#pragma clang diagnostic ignored "-Weverything"
#pragma clang diagnostic ignored "clang-analyzer-cplusplus.NewDelete"
#pragma clang diagnostic ignored "-Wclang-analyzer-cplusplus.NewDelete"
#pragma clang diagnostic ignored "-clang-analyzer-cplusplus.NewDelete"
#pragma clang diagnostic ignored "-W-NewDelete"
#pragma clang diagnostic ignored "-W-new-delete"

// code

#pragma clang diagnostic pop

Обратите внимание: исправление кода также не является вариантом, поскольку это сторонний код.


person JakobVinkas    schedule 24.06.2021    source источник
comment
В качестве примечания: это опасное предупреждение, которое нужно отключать даже для одной переменной, вы уверены в этом?   -  person Afshin    schedule 24.06.2021
comment
@Afshin уверен, что это ... но это не мой код, и я не собираюсь его менять ... У меня тоже никогда не было проблем, и, просматривая исходный код, кажется, что предупреждение никогда не могло появиться в любом случае. Я новичок в лязгах, но мне кажется, что это не всегда полностью логично в отношении того, какие события на самом деле могут произойти.   -  person JakobVinkas    schedule 24.06.2021
comment
какая у вас система сборки? CMake?   -  person Afshin    schedule 24.06.2021
comment
@Afshin Я использую CMake и Ninja   -  person JakobVinkas    schedule 28.06.2021


Ответы (3)


Как упоминалось в комментариях, подход #pragma clang diagnostic может использоваться только для подавления предупреждений компилятора. Предупреждения, на которые вы ссылаетесь, исходят от clang-static-analyzer, который теперь является частью clang-tidy.

Единственными двумя вариантами отключения конкретной проверки clang-tidy с помощью кода являются макросы //NOLINT и //NOLINTNEXTLINE.

Поскольку вы упомянули, что рассматриваемый код является сторонним, я предполагаю, что вы вообще не заинтересованы в его анализе. Поскольку вы используете CMake, это легко сделать с помощью .clang-tidy файлов. Вы можете поместить файл .clang-tidy в корневой каталог вашего проекта и перечислить / настроить там нужные проверки следующим образом:

Checks: '-*,cppcoreguidelines-*'

(это позволит выполнить все проверки Cpp Core Guidelines).

Затем в каталоге, в котором размещен сторонний код, вы можете отключить анализ clang-tidy с помощью файла .clang-tidy, размещенного в этом каталоге. Поскольку .clang-tidy файлы не могут быть пустыми или не указывать никаких проверок, вы можете сделать это, неправильно настроив проверку следующим образом:

Checks: '-*,misc-definitions-in-headers'
CheckOptions:
  - { key: HeaderFileExtensions,          value: "x" }

Дополнительные сведения об этом подходе см. В этом ответе.

В качестве альтернативы вы можете использовать файл .clang-tidy в стороннем каталоге, чтобы отключить только некоторые проверки.

person pablo285    schedule 01.07.2021

Согласно this, для Clang Static Analyzer вы должны использовать:

#ifndef __clang_analyzer__
// code
#endif
person 0x5453    schedule 24.06.2021
comment
Кажется, это полностью удаляет код, теперь я получаю предупреждение от других проверок ([clang-analyzer-deadcode.DeadStores]), в котором утверждается, что в коде чуть выше блока кода теперь есть неиспользуемые переменные. Это то, что нужно делать, или я реализовал это неправильно? - person JakobVinkas; 24.06.2021

Лучший подход, который приходит мне в голову, немного зависит от вашей системы сборки. Предположим, у вас есть пример такого кода:

Главный файл:

int main()
{
    // ...
    int *a = new int;
    *a = 10;
    delete a;

    if (::rand() < 10) {
        std::cout  << *a; //<-- clang tidy warning here
    }
    //...
}

Это создает предупреждение clang tidy в указанной строке. Что теперь делать? Разделите свой код на 2 файла:

Файл А:

void foo() {
    int *a = new int;
    *a = 10;
    delete a;

    if (::rand() < 10) {
        std::cout  << *a; //<-- clang tidy warning here
    }
}

Главный файл:

int main()
{
    // ...
    foo();
    //...
}

А теперь отключите cland-tidy для файла A. Это образец, но я думаю, вы понимаете мою общую идею. Вы не можете отключить clang-tidy, потому что он находится в другой библиотеке, и вы не можете прикоснуться к этому коду по нескольким причинам. //NOLINT тоже не работает на функции. Поэтому просто создайте оболочку в одном файле для использования этой библиотеки и отключите clang-tidy в этом файле оболочки для всего файла.

person Afshin    schedule 24.06.2021
comment
Итак, нет возможности использовать метод #pragma для удаления предупреждения, которое я получаю? Я бы очень предпочел не менять большую часть структуры, и #pragma казалась идеальным решением, но я не понимаю, когда ее использовать, так как я никогда не получаю никаких предупреждений, подобных тем, которые представлены в примерах #pragma ... - person JakobVinkas; 28.06.2021
comment
@JakobVinkas Я думаю, вы что-то неправильно поняли. Предупреждение, которое вы получаете, исходит от clang-tidy, а не от clang (я не получал вашего предупреждения, пока не включил clang-tidy). С другой стороны, #pragma clang diagnostic отключает предупреждение для clang, а не для clang-tidy. Единственный способ отключить clang-tidy предупреждений - это //NOLINT комментарии, поэтому вы не можете использовать #pragma для этого. - person Afshin; 28.06.2021
comment
Значит, рефакторинг кода и игнорирование файлов - единственное, что можно сделать, когда предупреждение исходит от вызова функции из сторонней базы кода? - person JakobVinkas; 28.06.2021
comment
@JakobVinkas Это единственный способ, который приходит мне в голову. Точнее, сам не тестировал, но теоретически должен работать. Вы можете протестировать его на небольшом примере (например, сначала на моем), прежде чем применять ко всему проекту. Другой способ - отключить clang-tidy для всего проекта или файла, который использует библиотеку. Но вы можете пропустить другие важные предупреждения, если сделаете это. Но если он уже включен прямо сейчас, вы, вероятно, захотите этого: D - person Afshin; 28.06.2021
comment
Как отключить в проверке только один файл? Как вы можете сказать, я новичок в clang-tidy;) У меня есть файл cmake с set(CLANG_TIDY_ARGS --checks=clang-analyzer-cplusplus.*), но это довольно большой проект, и я не могу найти, где выбрать, какие файлы следует проверить ... - person JakobVinkas; 28.06.2021
comment
Отключение @JakobVinkas для одного файла в cmake может быть немного хакерским подходом. но строка, которую вы отправляете мне из cmake, кажется настраиваемым способом запуска clang-tidy. Вам нужно проверить всю cmake, чтобы увидеть, как они ее интегрируют. - person Afshin; 28.06.2021