メインコンテンツ

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

CERT C: Rule INT34-C

Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand

説明

ルール定義

式を負のビット数分シフトしたり、オペランドに存在するビット数以上シフトしたりしないようにします。1

Polyspace 実装

ルール チェッカーは以下の問題をチェックします。

  • 負の値のシフト

  • シフト演算のオーバーフロー

チェッカーの拡張

入力値が不明であり、入力のサブセットのみが問題の原因となっている場合、既定の Bug Finder 解析では "負の値のシフト""シフト演算のオーバーフロー" が検出されない場合があります。特定のシステム入力値を原因とするこれらの問題の有無をチェックするには、より厳密な Bug Finder 解析を実行してください。特定のシステム入力値から欠陥を見つけるための Bug Finder チェッカーの拡張を参照してください。

すべて展開する

問題

負の値のシフトは、負の値をもつ可能性のある変数に対してビット単位のシフトが使用された場合に発生します。

リスク

負の値に対するシフトでは、数字が負であることを示す符号ビットが上書きされます。このシフト演算は予期しない値になる可能性があります。

修正方法

修正方法は欠陥の根本原因によって異なります。多くの場合、結果の詳細には欠陥につながる一連のイベントが表示されます。このイベント リストを使用して、シフト対象の変数がどのように負の値を取得したのかを確認します。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して逆のトレースを行い、これまでの関連するイベントを確認できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈も参照してください。

この欠陥を修正するには、ビット単位のシフト演算の前に負の値かどうかをチェックし、適切なエラー処理を実行します。

以下の修正例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

例 - 負の変数のシフト
int shifting(int val)
{
    int res = -1;
    return res << val; //Noncompliant
}

return ステートメントで、変数 res は特定のビット数だけ左にシフトします。しかし、res は負であるため、シフトにより符号ビットが上書きされる可能性があります。

修正 — データ型を変更

1 つの修正方法として、シフトする変数のデータ型を符号なしに変更することができます。この修正により符号ビットがなくなるため、左へのシフトによって変数の符号が変更されることはありません。

int shifting(int val)
{
    unsigned int res = -1;
    return res << val;
}
問題

シフト演算のオーバーフローは、シフト演算が、結果のデータ型では表せない値になる可能性がある場合に発生します。変数のデータ型によって、変数ストレージに割り当てられるバイト数が決まり、許容される値の範囲が制限されます。

異なる浮動小数点型への正確なストレージ割り当てはプロセッサに依存します。ターゲット プロセッサ タイプ (-target)を参照してください。

リスク

シフト演算のオーバーフローにより、未定義の動作が発生する可能性があります。

修正方法

修正方法は欠陥の根本原因によって異なります。多くの場合、結果の詳細には欠陥につながる一連のイベントが表示されます。このイベント リストを使用して、シフト演算で変数がどのように現在の値を取得したのかを確認します。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して逆のトレースを行い、これまでの関連するイベントを確認できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈も参照してください。

この欠陥は次のようにして修正できます。

  • すべての値に適応できるように、シフト演算の結果に対してより大きいデータ型を使用。

  • オーバーフローにつながる値をチェックし、適切なエラー処理を実行。

以下の修正例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

例 - 整数の左シフト
int left_shift(void) {

    int foo = 33;
    return 1 << foo;  //Noncompliant
}

この関数の return ステートメントで、ビット単位のシフト演算が実行され 1 が foo ビット左にシフトします。しかし int には 32 ビットしかないため、シフトの範囲は 0 から 31 の間でなければなりません。したがって、このシフト演算はオーバーフローを引き起こします。

修正 — 異なるストレージ型

1 つの修正方法として、シフト演算の結果をより大きいデータ型に保存することができます。この例では、int ではなく long long を返すことでオーバーフローの欠陥が修正されます。

long long left_shift(void) {

    int foo = 33;
    return 1LL << foo; 
}

チェック情報

グループ: Rule 04.整数 (INT)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.