メインコンテンツ

無限呼び出し

呼び出された関数が呼び出しコンテキストに返されない

説明

関数呼び出しに対するこのチェックは、次の条件が当てはまる場合に表示されます。

  • 呼び出された関数が、その呼び出しコンテキストに返されない。呼び出しが、明確なランタイム エラーや、関数本体における exit() などのプロセス終了関数につながる。

  • 同じ関数に対する他の呼び出しには、明確なエラーや、関数本体におけるプロセス終了関数につながらないものがある。

一部の関数の呼び出しのみが明確なエラーにつながる場合、このチェックはその関数呼び出しの特定に役立ちます。関数本体で明確なエラーが発生していても、関数本体での検証結果はすべての関数呼び出しの集約になるため、そのエラーはレッドではなくオレンジで表示されます。その代わり、明確なエラーが発生していることを示すため、無限呼び出しのレッド チェックが "関数呼び出しに" 表示されます。

それとは異なり、関数のすべての呼び出しが明確なエラーか関数本体でのプロセス終了関数につながる場合、無限呼び出しエラーは表示されません。エラーは関数本体にレッドで表示され、関数呼び出しには下線が赤の点線で表示されます。ただし、他のレッド エラーと同様に、Polyspace® は関数呼び出しの後、同一スコープ内の残りのコードを関数呼び出しとして解析しません。

関数呼び出しから、関数本体でランタイム エラーを起こしている操作に直接移動できます。

  • エラーのソースを見つけるには、[ソース] ペインでループ キーワードにカーソルを置きツールヒントを見ます。

  • 関数本体でエラーのソースまで移動します。関数呼び出しを右クリックし、オプションがあれば [原因に移動] を選択します。

    エラーの原因が複数ある場合は、オプションを使用すると関数本体の最初の原因に移動します。複数の原因が発生する可能性があるのは、たとえば、関数の引数のある値がある特定のエラーをトリガーし、別の値が別のエラーをトリガーしている場合です。

すべて展開する

#include<stdio.h>
double ratio(int num, int den) {
  return(num/den);
}

void main() {
  int i,j;
  i=2;
  j=0;
  printf("%.2f",ratio(i,j));
}

この例では、[ゼロ除算] レッド エラーが ratio 本体内に表示されます。ratio 本文におけるこの [ゼロ除算] エラーは、ratio の呼び出しでの赤い破線の原因となります。

#include<stdio.h>
double ratio(int num, int den) {
  return(num/den);
}

int inputCh();

void main() {
  int i,j,ch=inputCh();
  i=2;

  if(ch==1)  {
    j=0;
    printf("%.2f",ratio(i,j));
  }
  else {
    j=2;
    printf("%.2f",ratio(i,j));
  }
}

この例では、ratio の呼び出しが 2 つあります。最初の呼び出しでは、[ゼロ除算] エラーは ratio 本体内で発生します。2 番目の呼び出しでは、Polyspace はエラーを検出しません。したがって、この 2 つの呼び出しを結合して、オレンジの [ゼロ除算] チェックが ratio 本体に表示されます。最初の呼び出しでの [無限呼び出し] レッド チェックによってエラーが示されます。

typedef void (*f)(void);  
// function pointer type 

void f1(void) { 
  int x; 
  x++;   
} 

void f2(void) { } 
void f3(void) { } 

f fptr_array[3] = {f1,f2,f3}; 
unsigned char getIndex(void); 

void main(void) { 
 unsigned char index = getIndex() % 3; 
 // Index is between O and 2 

 fptr_array[index]();  
 fptr_array[index]();  
} 

この例では、index は 0 から 2 の間であるため、第 1 の fptr_array[index]()f1f2 または f3 を呼び出すことができます。index がゼロである場合、ステートメントは f1 を呼び出します。f1[未初期化ローカル変数] のレッド エラーを含むため、破線のレッド エラーが関数呼び出しに表示されます。他のレッド エラーと異なり、検証は続行します。

このステートメントの後、ソフトウェアは index が 1 か 2 のいずれかであると見なします。第 2 の fptr_array[index]() にはエラーは発生しません。

#include <stdio.h>
#include <stdlib.h>

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;

typedef void (*WrFuncPtr)(const void* src, void* dest);

typedef struct {
    WrFuncPtr pWrFuncPtr;
}FuncPtrStruct;


void Write_8(const void* pSource, void* pDest) {
    *(uint8*)pDest =  *(const uint8*) pSource;
}

void Write_16(const void* pSource, void* pDest) {
    *(uint16*)pDest =  *(const uint16*) pSource;
}

void Write_32(const void* pSource, void* pDest) {
    *(uint32*)pDest =  *(const uint32*) pSource;
}

#define SIZE_ARRAY 3

const FuncPtrStruct FuncPtrArray[SIZE_ARRAY] =
{
    { &Write_8  },
    { &Write_16 },
    { &Write_32 }
};

uint8 source[4];
uint8 dest[2];

void function(int uiSignalType) {
    uint8* srcPtr = &source[0];
    uint8 *destPtr = &dest[0];
    assert (uiSignalType>=0 && uiSignalType < SIZE_ARRAY);
    FuncPtrArray[uiSignalType].pWrFuncPtr(srcPtr, destPtr);
}

この例では、関数ポインター pWrFuncPtrWrite_8Write_16Write_32 の 3 つの関数のうちのいずれかを指す可能性があります。このうち Write_32 の呼び出しにのみ、潜在的な [不適切にデリファレンスされたポインター] エラー (オレンジ チェック) が含まれます。記述された内容に対して、バッファー pDest のメモリが足りなくなる可能性があるためです。関数本体にオレンジ チェックが含まれるため、関数ポインターを介したこの関数の呼び出しに対してレッドの [無限呼び出し] エラーが表示されます。

チェック情報

グループ: 制御フロー
言語: C | C++
頭字語: NTC