Можно ли подавить предупреждения статического анализатора Xcode 4?

Статический анализатор Xcode 4 сообщает в моем коде о некоторых ложных срабатываниях. Есть ли способ их подавить?


person DreamOfMirrors    schedule 27.04.2011    source источник
comment
Ложноположительный результат возможен, хотя и редко. Разместите свой код, пожалуйста.   -  person bbum    schedule 27.04.2011
comment
Использование шаблона проектирования Apple singleton (см. Создание экземпляра синглтона руководства по основам какао ) анализатор выдает Потенциальную утечку объекта, размещенного в строке XX.   -  person DreamOfMirrors    schedule 27.04.2011
comment
Можно возразить, что дизайн, основанный на синглтоне, заслуживает сообщения статического анализатора. :-)   -  person JeremyP    schedule 27.04.2011
comment
Это хорошо заданный вопрос. Он спрашивает, как отключить предупреждения в каждом конкретном случае, а не как проектировать программное обеспечение или следует ли избегать синглтонов. Синглтоны тоже не единственный случай, когда это происходит с анализатором. Ложное срабатывание в этом случае обычно относится к ситуации, когда анализатор считает, что есть потенциальная утечка памяти, но разработчик знает лучше, потому что он/она может мыслить более абстрактно, чем компилятор.   -  person quickthyme    schedule 01.07.2011
comment
Пример: найдите strcat и strcpy здесь: boost.org /doc/libs/1_56_0/boost/regex/v4/regex_workaround.hpp   -  person GrumpyOldTroll    schedule 29.08.2014
comment
Это безопасный сторонний код (обертки с проверкой длины для strcat и strcpy), и он не позволяет мне выполнять сборку с предупреждениями как об ошибках, потому что он помечен в моей компиляции с помощью /../../../3rdParty/boost/build_result/ include/boost/regex/v4/regex_workaround.hpp:201:7: Вызов функции 'strcpy' небезопасен, поскольку он не обеспечивает ограничение буфера памяти. Замените неограниченные функции копирования аналогичными функциями, поддерживающими аргументы длины, такими как 'strlcpy'. CWE-119 A #pragma XAnalyzer ignore -W CWE-119 было бы неплохо здесь, если бы он существовал. Думаю, это безопаснее, чем редактировать мою копию boost.   -  person GrumpyOldTroll    schedule 29.08.2014
comment
У меня есть (ложь? Не ложь?) Положительный результат, когда мне дается объект, и я вызываю setObject: forKey: для слегка измененного объекта. Если мне дается нулевой объект, это ошибка, поэтому я просто передаю нулевой объект в setObject:forKey:. Это рухнет. Я знаю это. Это то, что я хочу, я хочу сбой, когда вызывающий абонент дает мне неверный параметр. Статический анализатор разбирается и жалуется.   -  person gnasher729    schedule 22.05.2015


Ответы (4)


Я нашел решение: ложных срабатываний (например, шаблона проектирования Apple singleton) можно избежать с помощью:

#ifndef __clang_analyzer__

// Code not to be analyzed

#endif

Анализатор не будет анализировать код между этими директивами препроцессора.

person DreamOfMirrors    schedule 29.04.2011

Взгляните на эту страницу, которая показывает, как использовать несколько #define для аннотирования методов и параметров Objective-C, чтобы помочь статическому анализатору (clang) делать правильные вещи.

http://clang-analyzer.llvm.org/annotations.html

С этой страницы:

Внешний интерфейс Clang поддерживает несколько аннотаций на уровне исходного кода в виде атрибутов и прагм в стиле GCC, которые могут сделать использование Clang Static Analyzer более полезным. Эти аннотации могут помочь подавить ложные срабатывания, а также повысить способность анализатора находить ошибки.

person Logachu    schedule 13.08.2011
comment
Эти аннотации кажутся лучшим выбором, чем #ifndef __clang_analyzer__, поскольку они применяются к методам, где бы они ни использовались. Например: @property (nonatomic, retain) NSString* newString NS_RETURNS_NOT_RETAINED; - person Noah Harrison; 01.12.2012

См. мой ответ >здесь. Вы можете добавить к файлам флаг компиляции, и статический анализатор их проигнорирует. Это, вероятно, лучше для стороннего кода, о котором вы не беспокоитесь, а не для собственного кода, который вы пишете.

person kcharwood    schedule 10.11.2011

в большинстве случаев использование таких вещей, как CF_RETURNS_RETAINED и соблюдение правила «создать», работает для меня, но я столкнулся с случаем, который я не мог НЕ подавить. Наконец нашел способ подавить анализатор, посмотрев исходный код llvm:

https://llvm.org/svn/llvm-project/cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m.result

«Проверьте, подавляем ли мы ошибку при сохранении указателя на глобальную переменную».

static CGLayerRef sSuppressStaticAnalyzer;
static CGLayerRef sDmxImg[2][2][1000]; // a cache of quartz drawings.
CGLayerRef CachedDmxImg(...) // which lives for lifetime of app!
{
    ...

    CGLayerRef img = sDmxImg[isDefault][leadingZeroes][dmxVal];
    if ( !img )
    {
        NSRect imgRect = <some cool rectangle>;

        [NSGraphicsContext saveGraphicsState];
        CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
        CGLayerRef cgLayerRef = CGLayerCreateWithContext(ctx, imgRect.size, NULL);
        CGContextRef layerCtx = CGLayerGetContext(cgLayerRef);
        [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort:layerCtx flipped:YES]];

        ... draw some gorgeous expensive Quartz stuff ...

        img = cgLayerRef;
        sDmxImg[isDefault][leadingZeroes][dmxVal] = cgLayerRef;
        sSuppressStaticAnalyzer = cgLayerRef; // suppress static analyzer warning!
        [NSGraphicsContext restoreGraphicsState];
   }
   return img;
}

По какой-то причине назначение статическому массиву не подавило предупреждение, но назначение простому старому статическому массиву 'sSuppressStaticAnalyzer' подавило. Кстати, описанный выше метод с использованием CGLayerRef — это самый быстрый из найденных мной способов перерисовки кэшированных изображений (помимо OpenGL).

person Keith Knauber    schedule 24.02.2016