clang
не выполняет межпроцедурный анализ, по крайней мере, пока. Даже если бы оно и было, оно не обязательно может поймать эту «ошибку» - перестановки потенциальных путей кода имеют тенденцию к супер экспоненциальному росту, что делает это практической невозможностью.
clang
работает с набором эвристик, которые работают "большую часть времени". К счастью, правила управления памятью Какао имеют тенденцию быть достаточно единообразными, поэтому эвристика работает для большинства применений. Конкретный пример, который вы привели, на самом деле не охватывается правилами управления памятью, но я думаю, что большинство людей (включая меня) склонны классифицировать ваш пример как «Вы задокументировали через API, что вызывающий * 1005» * несет ответственность за release
возвращаемый объект ". Это по сути аналогично методам стиля - (NSString *)init...
.
clang
знает, что методы, начинающиеся с init...
, возвращают «невыпущенный» объект, и вызывающая сторона несет ответственность за обеспечение его правильного освобождения. Это является частью ядра эвристики - ему не нужен весь программный или межпроцедурный анализ для выполнения основной части проверки подсчета ссылок - если локальный блок кода получает объект с помощью метода init...
, этот локальный блок кода должен убедиться, что он правильно released
. Естественно, если локальный блок кода и рассматриваемый объект являются частью самого метода init...
, он покрывается тем же «правилом», поэтому он получает исключение.
То, что вы, вероятно, хотите, это что-то вроде:
NSString* leaker() __attribute__((ns_returns_retained))
{
return [[NSString alloc] init];
}
Это позволяет анализатору узнать, что leaker()
возвращает «сохраненный» объект, и что вызывающий абонент отвечает за его правильное освобождение. Хотя я не проверял это, я сильно подозреваю, что «утечка» будет обнаружена в точке, где вызывается leaker()
, т. Е .:
void test(void)
{
NSString *leaked = leaker();
// Previous line should be caught as a "leak" by clang.
}
Это одно из печальных ограничений любого статического анализатора, а не только clang
.