clang
少なくともまだ、手順間の分析を実行していません。たとえそれがあったとしても、必ずしもこの「エラー」をキャッチできるとは限りません。潜在的なコード パスの順列は超指数関数的に増加する傾向があり、実際には不可能です。
clang
「ほとんどの場合」機能する一連のヒューリスティックで機能します。ありがたいことに、Cocoa のメモリ管理規則はかなり統一されている傾向があるため、ヒューリスティックはほとんどの用途で機能します。あなたが与えた特定の例は、実際にはメモリ管理ルールでカバーされていませんが、ほとんどの人 (私を含む) はあなたの例を「呼び出し元leaker()
が責任を負うAPI を介して文書化した」と分類する傾向があると思いますrelease
返されたオブジェクトをing するため」です。- (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.
}
これは、 だけでなく、静的アナライザーの残念な制限の 1 つですclang
。