Clang Static Analyzer は、LLVM/Clang プロジェクトが提供する静的解析ツールで、主に C/C++/Objective-C 向けに、プログラムのバグをコンパイル時に検出するために設計された軽量なツールです。
Clang Static Analyzer とは?
項目 | 内容 |
---|---|
開発元 | LLVM/Clang プロジェクト(オープンソース) |
対象言語 | C、C++、Objective-C |
主な用途 | コンパイル前に、メモリミス・未定義動作・リソースリークなどを検出 |
解析方式 | 制御フロー解析(CFG)、データフロー解析(Symbolic Execution) |
実行方法 | clang --analyze または scan-build を使用 |
主な検出対象
Clang Static Analyzer は以下のような不具合を検出します。」
問題タイプ 例
- ヌルポインタ参照 NULL チェックをせずに参照
- メモリリーク malloc/free や new/delete の不整合
- ダングリングポインタ 解放後のポインタ使用
- 二重解放 同じポインタを2回 free
- 初期化されていない変数の使用 未定義動作を引き起こす
使い方
サンプルのソースコード
#include <stdlib.h>
int main() {
int *s = NULL;
*s = 42;
return 0;
}
方法①:clang --analyze
$ clang --analyze sample.cpp
sample.cpp:6:6: warning: Dereference of null pointer (loaded from variable 's') [core.NullDereference]
6 | *s = 42;
| ~ ^
1 warning generated.
これは簡単ですが、結果は標準出力に簡素な形式で出力されます。
方法②:scan-build(推奨)
scan-build を使うと、ビルド全体をラップしてHTMLレポート付きで出力できます。
$ scan-build make
scan-build: Using '/usr/lib/llvm-18/bin/clang' for static analysis
/usr/share/clang/scan-build-18/bin/../libexec/ccc-analyzer -I../inc -c sample.cpp
sample.cpp:6:6: warning: Dereference of null pointer (loaded from variable 's') [core.NullDereference]
6 | *s = 42;
| ~ ^
1 warning generated.
/usr/share/clang/scan-build-18/bin/../libexec/ccc-analyzer -o sample sample.o
scan-build: Analysis run complete.
scan-build: 1 bug found.
scan-build: Run 'scan-view /tmp/scan-build-2025-07-11-100357-3495-1' to examine bug reports.
サンプルのMakefile
CC = clang
CFLAGS =
TARGET = sample
SRCS = sample.cpp
OBJS = $(SRCS:.cpp=.o)
INCDIR = -I../inc
LIBDIR =
LIBS =
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(LIBDIR) $(LIBS)
$(OBJS): $(SRCS)
$(CC) $(CFLAGS) $(INCDIR) -c $(SRCS)
all: clean $(OBJS) $(TARGET)
clean:
-rm -f $(OBJS) $(TARGET)
出力例(ローカルHTML):
/tmp/scan-build-2025-07-11-100357-3495-1
/tmp/scan-build-2025-07-11-100357-3495-1
├── index.html
├── report-f87ed6.html
├── scanview.css
└── sorttable.js
この方法では、複雑なプロジェクトでも複数ファイルにまたがるバグを検出できます。
Makefile の修正は不要
scan-build は 環境変数を一時的に変更してくれるので、Makefile に手を加える必要はありません。
ただし、Makefile の中で gcc をハードコーディングしている場合は、少し工夫が必要です。
特殊ケース:Makefile に gcc が固定されている場合
- 方法①:環境変数を上書き
scan-build env CC=clang make
-
方法②:Makefile に CC を使うよう明示
Makefile の先頭に以下のような記述があるとより柔軟です:
CC = gcc
all:
$(CC) -o hello hello.c
このようにしておけば、scan-build のようなツールで上書き可能になります。
長所・短所
メリット
項目 | 内容 |
---|---|
LLVMと統合 | Clang コンパイラにネイティブに統合されている |
高速 | コンパイルと同時に解析できるため、非常に軽量 |
実用的 | メモリや未定義動作に関して実用的な検出能力を持つ |
無料・オープンソース | 商用ライセンス不要で自由に利用可能 |
デメリット
項目 | 内容 |
---|---|
検出範囲が狭い | セキュリティ脆弱性やコードスタイル違反などは対象外 |
インクリメンタル非対応 | 差分だけを解析する仕組みはない(毎回全体解析) |
誤検出・漏れ | 静的解析特有の「false positive(誤検出)」や「false negative(見逃し)」あり |
カスタマイズ性が低い | ルールやレポート形式の柔軟な変更は難しい |
他ツールとの比較
ツール名 | 長所 | 短所 |
---|---|---|
Clang Static Analyzer | 軽量、高速、LLVM統合 | 検出範囲がやや狭い |
Infer | 抽象解釈、高精度、CI向き | セットアップがやや複雑 |
Coverity(商用) | 非常に高精度・企業向け | 高コスト・導入が重い |
clang tidy との違い
Clang Static Analyzer と clang-tidy はどちらも Clang(LLVM)プロジェクトに属する静的解析ツールですが、目的・機能・検出対象が異なります。
clang-tidy が得意なもの
チェックカテゴリ | 例 |
---|---|
コードスタイル | Google, LLVM などのスタイル準拠違反 |
モダン化 | auto 推奨、nullptr 使用、範囲 for 文など |
セキュリティ | バッファオーバーフロー、未使用変数の削除など |
リファクタ支援 | 冗長コード検出、未使用関数削除の提案 |
C++CoreGuidelines | C++ 標準的ガイドラインに従っているかのチェック |