メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

コードがチェックされない理由

問題

検証後、[検証でカバーされたコード] のグラフで、コードのかなりの部分でランタイム エラーがチェックされていないことがわかります。

たとえば、次のグラフでは、関数の 75% でランタイム エラーがチェックされていないことが [ダッシュボード] ペインに示されています (チェックされた関数の中でチェックされていない操作は 7% のみです)。

[検証でカバーされたコード] グラフのチェックされなかったコードの割合には以下が含まれます。

  • 到達不能と証明されたためチェックされない関数や操作。

    [ソース] ペインでグレー表示されます。

  • 到達不能とは証明されなかったが、他の理由でチェックされなかった関数や操作。

    [ソース] ペインで黒く表示されます。

[検証でカバーされたコード] グラフをクリックして、チェックされなかった関数のリストを表示します。

考えられる原因: コンパイル エラー

コンパイル エラーのないファイルのみが完全に解析されます。コンパイル エラーのあるファイルでは、コンパイル エラーの性質によって、一部の関数が解析されない場合があります。

  • コンパイル エラーが関数本体内で発生した場合、そのファイル内のコンパイル エラーがない残りの関数のみが解析されます。

  • 関数シグネチャなど、関数本体以外でコンパイル エラーが発生する場合は、コンパイル エラーの性質によって、ファイル内の残りの関数は解析される場合と解析されない場合があります。

一部のファイルがコンパイルされなかったことを確認するには、[出力の概要] または [ダッシュボード] ペインをチェックします。解析前にすべてのファイルが確実にコンパイルされるようにするには、オプションファイルがコンパイルされない場合は解析を停止 (-stop-if-compile-error)を使用します。

解決法

コンパイル エラーを修正して解析を再実行します。

詳細については、それぞれ以下を参照してください。

考えられる原因: 早い段階でのレッド チェックまたはグレー チェック

関数呼び出し階層の先頭方向にレッド チェックまたはグレー チェックがあります。レッド チェックやグレー チェックがあると、その後のコードがチェックされないことがあります。

  • レッド チェック: 検証では、レッド チェックを含むコード ブロックのその後の操作がチェックされません。

  • グレー チェック: グレー チェックは、到達不能コードを示します。検証では、到達不能コードの操作に対してランタイム エラーがチェックされません。

チェックされないコード ブロックから関数を呼び出している場合、検証ではそれらの関数もチェックされません。関数呼び出し階層の先頭方向にレッド チェックまたはグレー チェックがある場合、それ以降の階層にある関数はチェックされない場合があります。その結果、膨大な量のコードがチェックされなくなります。

たとえば、次のコードでは、4 つの関数のうち 1 つしかチェックされないため [手続き] グラフには 25% と示されます。関数 func_called_from_unreachable_1func_called_from_unreachable_2、および func_called_after_red はチェックされません。main のみチェックされます。

void func_called_from_unreachable_1(void) {
}

void func_called_from_unreachable_2(void) {     
}

void func_called_after_red(void) {
}

int glob_var;

void main(void) {
     int loc_var;
     double res;
     
     glob_var=0;
     glob_var++;
     
     if (glob_var!=1) {
           func_called_from_unreachable_1();
           func_called_from_unreachable_2();
     }
     
     res=0;
     /* Division by zero occurs in for loop */
     for(loc_var=-10;loc_var<10;loc_var++) {
	          res += 1/loc_var;
     }
     
     func_called_after_red();
}

解決法

main 関数または別のタスク関数がレッド チェックまたはグレー チェックになっているかどうかを確認します。その後のチェックされないコードから関数の大半を呼び出しているかどうかを確認します。

関数呼び出し階層を main から下方向に移動してチェックされていないコードの開始位置を特定するには、[呼び出し階層] ペインのナビゲーション機能を使用します。ペインが既定で表示されない場合、[ウィンドウ][ビューの表示/非表示][呼び出し階層] を選択します。詳細は、Polyspace デスクトップ ユーザー インターフェイスの [呼び出し階層]を参照してください。

あるいは、チェックされていない任意の関数を考慮して、その関数がチェックされない理由を調べることができます。同じ理由が多くの関数に当てはまるかどうかを確認します。エントリ ポイントからまったく呼び出されない関数または到達不能コードから呼び出される関数を検出するには、オプション呼び出されない関数の検出 (-uncalled-function-checks)を使用します。

レッド チェックまたはグレー チェックをレビューして修正します。

考えられる原因: 不適切なオプション

必要な解析オプションを指定していません。次のオプションは、指定が不適切だとコードがチェックされない原因になる可能性があります。

  • マルチタスキングのオプション: マルチタスキング コードを検証している場合、このオプションを使ってエントリ ポイント関数を指定します。

    考えられる指定エラーには次のようなものがあります。

    • 同時実行の自動検出によってスレッド作成を検出することを想定したが、まだ自動検出をサポートしないスレッド作成プリミティブを使用している。

    • 手動マルチタスキング設定で、エントリ ポイントをすべて指定しなかった。

  • main 生成のオプション: main 関数がコードに存在しない場合はこのオプションを使って生成します。モジュールまたはライブラリを検証するときは、このオプションを使用します。

    生成した main が呼び出さなければならないすべての関数を指定していません。

  • 入力オプションとスタブ オプション: これらのオプションを使って、コードの外側から変数の範囲を制約するか、関数のスタブ化を強制します。

    考えられる指定エラーには次のようなものがあります。

    • 指定した変数の範囲が狭すぎるため、到達可能だったコードが到達不能になった。

    • 一部の関数を意図しないでスタブ化した。

  • マクロ:このオプションを使用して、プリプロセッサ マクロを定義するか、または定義を解除します。

    コンパイラが暗黙的に定義されていると見なすマクロを明示的に定義しなければならない場合があります。

解決法

前述の順序でオプションをチェックします。指定が不適切な場合は修正します。

考えられる原因: main 関数が終了しない

この原因は、エントリ ポイント関数全体がチェックされない場合のマルチタスキング コードにのみ当てはまります。

マルチタスキング オプションを手動で設定する場合、Polyspace マルチタスキング モデルに対する制限に従わなければなりません。特に、main 関数には無限ループやランタイム エラーが含まれていてはなりません。そうでない場合、エントリポイント関数がチェックされません。

たとえば、次の例では、task2 をエントリ ポイントとして指定してもチェックされません。その理由は、main 関数に無限ループがあるためです。

void performTask1Cycle(void);
void performTask2Cycle(void);

void main() {
 while(1) {
    performTask1Cycle();
  } 
}

void task2() {
 while(1) {
    performTask2Cycle();
  }
}

main 関数の while キーワードは赤の破線の下線付きで表示されます。ツールヒントには、ループが終了しない可能性があることが示されます。

同様に、ランタイム エラーが発生すると、ランタイム エラーにつながる関数呼び出しは、赤の破線の下線付きで付随するツールヒントと共に表示されます。

解決法: main 関数を終了させる

main 関数が終了しない理由を修正します。

  • 理由が明確なランタイム エラー (レッド チェック) である場合、エラーを修正します。

  • 理由が無限ループの場合、ループが無限になる理由を確認します。

    main 関数の無限ループが周期タスクを表している場合、main 関数を終了して無限ループを別のエントリポイント関数に移します。main 関数を実際に変更することなく Polyspace 解析を行う目的でのみ、この変更を行うことができます。Polyspace マルチタスキング解析の手動設定を参照してください。