Analyzability (since C11)
このC言語のオプション拡張は、一部の未定義動作の実行による潜在的な結果を制限し、そのようなプログラムの静的解析の効果を向上させます。解析可能性は、 定義済みマクロ定数 __STDC_ANALYZABLE__ がコンパイラによって定義されている場合にのみ有効であることが保証されます。
コンパイラが解析可能性をサポートする場合、動作が未定義となる言語またはライブラリ構成は、 critical 未定義動作と bounded 未定義動作にさらに分類され、すべてのbounded UBケースの動作は以下に規定するように制限されます。
目次 |
重大な未定義動作
クリティカルUB(未定義動作)とは、オブジェクトの境界外でメモリ書き込みまたは揮発性メモリ読み取りを実行する可能性のある未定義動作です。クリティカルな未定義動作を含むプログラムは、セキュリティ悪用の影響を受けやすくなる可能性があります。
以下の未定義動作のみが重要です:
- 寿命範囲外のオブジェクトへのアクセス (例:ダングリングポインタ経由)
- 宣言が 互換性のない オブジェクトへの書き込み
- 指し示す関数の型と 互換性のない 型の関数ポインタ経由での関数呼び出し
- lvalue式 の評価時に、オブジェクトを指定していない場合
- 文字列リテラル の変更試行
- 無効(null、不定値など)または 終端超過 ポインタの 間接参照
- 非constポインタ経由での constオブジェクト の変更
- 無効な引数での標準ライブラリ関数またはマクロの呼び出し
- 想定外の引数型での可変引数標準ライブラリ関数の呼び出し (例:変換指定子と型が一致しない引数での printf 呼び出し)
- 呼び出しスコープ内に setjmp が存在しない、スレッドを跨ぐ、またはVM型のスコープ内からの longjmp
- free または realloc で解放されたポインタの使用
- 境界外の配列へのアクセスを行う 文字列 または ワイド文字列 ライブラリ関数の使用
境界付き未定義動作
境界付き未定義動作(Bounded UB)は、トラップが発生する可能性があり、不確定な値を生成または格納する可能性があるものの、違法なメモリ書き込みを実行できない未定義動作です。
- クリティカルとしてリストされていないすべての未定義動作は境界付けられています
-
- マルチスレッドデータ競合
- 自動記憶域期間を持つ 不定値 の使用
- 厳格なエイリアシング 違反
- 不適切なアライメント でのオブジェクトアクセス
- 符号付き整数オーバーフロー
- 順序付けられていない副作用 による同一スカラーの変更、または同一スカラーの変更と読み取り
- 浮動小数点から整数、またはポインタから整数への 変換 オーバーフロー
- ビットシフト の負数または過大なビット数によるシフト
- 整数除算 におけるゼロ除算
- void式の使用
- 不正確にオーバーラップしたオブジェクトの直接 代入 または memcpy
- restrict 違反
- など... クリティカルリストに含まれない全ての未定義動作
注記
境界付き未定義動作は特定の最適化を無効化します:解析可能性を有効にしてコンパイルすると、ソースコードの因果性が保持されます。これは、 未定義動作によって破られる可能性がある ものです。
アナライザビリティ拡張は、実装定義の振る舞いの一形態として、トラップ発生時に ランタイム制約ハンドラ が呼び出されることを許可します。
参考文献
- C23規格 (ISO/IEC 9899:2024):
-
- 6.10.10.4/1 条件付き機能マクロ (p: 188-189)
-
- 附属書L 解析可能性 (p: 672-673)
- C17規格 (ISO/IEC 9899:2018):
-
- 6.10.8.3/1 条件付き機能マクロ (p: 128-129)
-
- 附属書L 解析可能性 (p: 473-474)
- C11規格 (ISO/IEC 9899:2011):
-
- 6.10.8.3/1 条件付き機能マクロ (p: 177)
-
- 附属書L 解析可能性 (p: 652-653)