MISRA C++:2008 Rule 15-3-4
Each exception explicitly thrown in the code shall have a handler of a compatible type in all call paths that could lead to that point
説明
ルール定義
Each exception explicitly thrown in the code shall have a handler of a compatible type in all call paths that could lead to that point. 1
根拠
C++ では、操作で例外が発生すると、コンパイラが現在のスコープと隣接するスコープ内の互換性のある例外ハンドラーと例外を一致させようとします。発生した例外と互換性のある例外ハンドラーが存在しない場合は、コンパイラが暗黙的に関数 std::terminate() を呼び出します。関数 std::terminate() は処理系定義の方法でプログラム実行を終了します。つまり、プログラム終了の具体的なプロセスは、使用しているソフトウェアとハードウェアの特定の組み合わせに応じて異なります。たとえば、std::terminate() は std::abort() を呼び出してスタックのアンワインドを行わずに実行を異常終了させる可能性があります。プログラムが終了する前にスタックがアンワインドされなかった場合は、スタック内の変数のデストラクターが呼び出されず、リソース リークやセキュリティの脆弱性につながります。
コードの try ブロック内で複数の例外が発生する次のコードについて考えます。
class General{/*... */};
class Specific : public General{/*...*/};
class Different{}
void foo() noexcept
{
try{
//...
throw(General e);
//..
throw( Specific e);
// ...
throw(Different e);
}
catch (General& b){
}
}General への参照を受け入れます。この catch ブロックは、基底クラス General とその派生クラス Specific の例外と互換性があります。クラス Different の例外と互換性のあるハンドラーは存在しません。この未処理例外は、このルールに違反しているため、リソース リークやセキュリティの脆弱性につながる可能性があります。未処理例外はリソース リークやセキュリティの脆弱性につながる可能性があるため、コード内で明示的に発生した例外と互換性のあるハンドラーを一致させます。
Polyspace 実装
Polyspace® は、互換性のある catch ステートメントが関数の呼び出しパス内に存在しない場合に、関数内の
throwステートメントにフラグを設定します。関数がnoexceptとして指定されていない場合は、Polyspace がその呼び出しパスからmain()などのエントリ ポイントが欠落している場合にその関数を無視します。Polyspace は、
catch(…)ステートメントを使用して発生した例外を処理するthrowステートメントにフラグを設定します。Polyspace は、再スロー ステートメント、つまり、catch ブロック内の
throwステートメントにはフラグを設定しません。関数の入れ子になった try-catch ブロック内に
throwステートメント用の互換性のある catch ブロックがあっても、Polyspace は入れ子になった try-catch ブロックを無視します。コメントを使用して、入れ子構造内に互換性のある catch ブロックが入っているthrowステートメントを正当化します。または、関数で単一レベルの try-catch を使用します。
トラブルシューティング
ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。
例
チェック情報
| グループ: Exception Handling |
| カテゴリ: 必要 |
バージョン履歴
R2020b で導入
1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.
The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:
MISRA C:2004
MISRA C:2012
MISRA C:2023
MISRA C++:2008
MISRA C++:2023
MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.