メインコンテンツ

絶対アドレスの使用

ポインターに絶対アドレスが割り当てられている

説明

このチェックは絶対アドレスがポインターに割り当てられているときに表示されます。

既定では、このチェックはグリーンになります。ソフトウェアでは、絶対アドレスについて次のように仮定します。

  • アドレスが有効である。

  • アドレスを代入するポインターの型によって、アドレスに格納される初期値が決まります。

    アドレスを int* ポインターに代入する場合、そのアドレスが指すメモリ ゾーンは int の値で初期化されます。値はデータ型 int で許容される任意の値になります。

解析は、絶対アドレスの使用に関する次の仮定に基づいて行われます。

  • アドレスで変数またはポインター演算が使用されている場合、チェックでは、そのアドレスに絶対アドレスとしてのフラグは設定されません。たとえば、アドレス x = *(int*)0x7 は絶対アドレスと見なされます。アドレス x = *(int*)(0x7 + y) は変数が使用されているため、絶対アドレスではありません。

  • ポインターに絶対アドレスが割り当てられている場合、解析では、そのポインターが指すデータ型で許容される任意の値をその参照先に格納できると仮定されます。たとえば ptr = (int*)0x32 の場合、解析では *ptr に任意の int を格納できると仮定されます。ptr = (int*)(char*)0x32 のような一連のキャストについては、一番外側のキャスト (この例では int*) のみが解析で考慮されます。

それぞれの絶対アドレスの使用について、このチェックを既定でオレンジにするには、コマンド ライン オプション-no-assumption-on-absolute-addressesを使用します。

すべて展開する

void func(int offset) {
    int *p = (int *)0x32;             // Green absolute address usage
    int *q = (int *)(0x32+offset);    // No absolute address check happens here
}

この例では、オプション -no-assumption-on-absolute-addresses を使用していません。したがって、ポインター p に絶対アドレスが代入されたときに、[絶対アドレスの使用] チェックがグリーンになります。オプション -no-assumption-on-absolute-addresses が使用されている場合、チェックはオレンジになります。

このチェックは、厳密な絶対アドレスに対してのみ行われます。アドレス int *q = (int *)(0x32+offset); には変数が含まれるため、これは厳密な絶対アドレスではありません。

enum typeList {CHAR,INT,LONG};
enum typeList showType(void);
long int returnLong(void);

void main() {
    int *p = (int *)0x32; //Green absolute address usage
    enum typeList myType = showType();

    char x_char;
    int x_int;
    long int x_long;

    if(myType == CHAR)
        x_char = *p;
    else if(myType == INT)
        x_int = *p;
    else {
        x_long = *p;
        long int x2_long = returnLong();
    }
}

この例では、オプション -no-assumption-on-absolute-addresses を使用していません。したがって、ポインター p に絶対アドレスが代入されたときに、[絶対アドレスの使用] チェックがグリーンになります。

このチェックの後の検証では、アドレスが int の値で初期化されると仮定されます。[ターゲット プロセッサ タイプ] (-target) (sizeof(char) < sizeof(int) < sizeof(long int)) に [x86_64] を使用した場合は、次のように仮定されます。

  • if(myType == CHAR) の分岐で、x_charint の変数に許容されるすべての値を格納できないため、オレンジの [オーバーフロー] が発生します。

  • else if(myType == INT) の分岐で、検証結果の x_int にカーソルを置くと、ツールヒントに x_intint の変数に許容されるすべての値をもつ可能性があることが示されます。

  • else の分岐で、x_long にカーソルを置くと、ツールヒントに x_longint の変数に許容されるすべての値をもつ可能性があることが示されます。x2_long にカーソルを置くと、ツールヒントに x2_longlong int の変数に許容されるすべての値をもつ可能性があることが示されます。x2_long は、同じターゲットで int の変数に許容される値よりも広い範囲の値をとることができます。

void main() {
    int *p = (int *)0x32;
    int x = *p;
    p++;
    x = *p;
}

この例では、オプション -no-assumption-on-absolute-addresses を使用しています。ポインター p に絶対アドレスが代入されたときに、[絶対アドレスの使用] チェックがオレンジになります。

このチェックの後には以下が続きます。

  • Polyspace® は、p がメモリの有効な場所を指すものとみなします。したがって、後続行に対する [不適切にデリファレンスされたポインター] チェックはグリーンになります。

  • 次の 2 行では、ポインター p はインクリメントされ、続いてデリファレンスされます。この場合、p がまだ絶対アドレスを指していても、[絶対アドレスの使用] チェックではなく [不適切にデリファレンスされたポインター] チェックがデリファレンス上に表示されます。

チェック情報

グループ: 静的メモリ
言語: C | C++
頭字語: ABS_ADDR