はじめに
LLVMをベースにしたC/C++、Objective-C/C++のコンパイラフロントエンドとしてClangがあります。 Clangプロジェクトでは、コンパイラだけでなく、静的解析ツールも開発しています。
今回は、その静的解析ツールである、scan-buildについて紹介します。
scan-buildをインストールしよう
以下にUbuntu 14.04 LTS(Trusty)でのインストール手順を示します。Trustyでは、clang-3.3、clang-3.4もしくはclang-3.5をインストールできます。 scan-buildはclangパッケージに含まれているので、今回は新しめのバージョンであるclang-3.5をインストールすることにします。1
% sudo apt-get install clang-3.5
scan-buildを使ってみよう
scan-buildをインストールできたので、実際に試してみましょう。例として使うのは、ククログで何度か登場しているのでおなじみカラムストア機能つき全文検索エンジンGroongaのコードです。
まずは、ソースコードをcloneして、configureファイルを生成します。
% git clone https://github.com/groonga/groonga.git
% cd groonga
% ./autogen.sh
configureファイルが生成されたら、次はconfigureでclangを使うようにします。
% ./configure CC=clang CXX=clang++
では、scan-buildにかけてみましょう。 configureを実行するとMakefileができるので、あとはscan-buildを単に実行するだけです。
% scan-build make
検出された問題点
scan-buildの実行が完了すると、次のようなサマリが最後に出力されます。
scan-build: 216 bugs found.
scan-build: Run 'scan-view /tmp/scan-build-2014-12-22-164614-28182-1' to examine bug reports.
どんな問題が実際に検出されたのか、確認してみましょう。 scan-buildが最後に出力したコマンドの例を実行します。
% scan-view /tmp/scan-build-2014-12-22-164614-28182-1
すると、自動的にブラウザが起動してレポートを表示します。
Bug Summaryをみると次のような問題が検出されていることがわかります。
- NULLポインタの参照(の可能性)
- 代入しているけど使っていない
- NULLが期待されていない箇所でNULLが渡された
中には可能性があると指摘されているものの、実際には問題ないというケースもあります。そのあたりは確認が必要です。
検出された個別の問題については、Reportsのリンクをたどると該当箇所のコードも表示してくれます。
例えば、無駄な代入を行っている箇所として次のような箇所が検出されました。
みるとわかるのですが、whileループの先頭で変数c
に先頭の文字を毎回設定しています。しかし、case文の条件であるGRN_LOADER_BEGIN
では、スペースを読みとばしたときには、変数c
に先頭の文字を設定してからcontinue
で抜けています。
つまり、その場合には
c = *str;
が重複して実行されています。これは明らかな無駄ですね。
まとめ
今回は、Clangの静的解析ツールを使ってコードの潜在的な問題点や使われていないコードを検出する方法を紹介しました。 scan-buildをうまく使って、既存のコードにつもった埃をキレイにしてみるといいかも知れませんね。
-
sudo apt-get install clangで標準インストールされるのはclang-3.4です。 ↩