2013年2月13日水曜日

[VS2012][gtest]コード分析警告に対応させる

Visual Studio 2012 では express でもコード分析が使えます。
NULL ポインタ参照とか検出してくれて非常にありがたいのですが、
こちらのコードでも警告が出てしまいます。

#include <gtest/gtest.h>

TEST(NullCheck, Sample)
{
    int* p = (int*)malloc(4);
    ASSERT_TRUE(p != NULL);
    *p = 1;
    ASSERT_EQ(1, *p);
}


p が NULL の場合、ASSERT_TRUE(p != NULL) に失敗し return します。
従って以降の処理が走る場合、p が NULL でないことは決定しています。

こんなことも分からないとは・・・

NULL でないことを教える
C6011 の対処をするために __analysis_assume を使います。
これはコード分析ツールのためのコードの追加情報を与えます。

上記コードはこのようになります。
#include <gtest/gtest.h>

TEST(NullCheck, Sample)
{
    int* p = (int*)malloc(4);
    ASSERT_TRUE(p != NULL);
    __analysis_assume(p != NULL);
    *p = 1;
    ASSERT_EQ(1, *p);
}

結果

警告消えました!

あーでも、ASSERT_TRUE(p != NULL); で分かりきってることを、もう一度書くのはダサいですよね・・・
ASSERT_TRUE にやらせる
#undef ASSERT_TRUE
#define ASSERT_TRUE(condition) \
    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
    if( bool b = true ) { \
        __analysis_assume(condition); \
        goto GTEST_CONCAT_TOKEN_(gtest_label_analysis_assume, __LINE__); \
    } else \
        GTEST_CONCAT_TOKEN_(gtest_label_analysis_assume, __LINE__): \
        GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
                GTEST_FATAL_FAILURE_)

ちょっと変わった書き方ですが、Google Test の機能である
if( int x = 1 ) // { 省略しても OK
    ASSERT_TRUE(x==1) << "message"; // << で失敗時のメッセージを追加できる
を潰さないようするためです。

これを使って最初のコードを分析させます。

結果


うまくいきました。
コード分析、便利なんで積極的に使いたいですね。
(あれ?でも解放してないのは警告されないのか。。。)

0 件のコメント:

コメントを投稿