(57)【要約】【課題】コンピュータプログラム中のプログラミングエラーを検出する。【解決手段】メモリ１０４に格納された、関数のようなコンピュータプログラムのステートメント（命令）をＣＰＵ１０２により実行する。ＣＰＵ１０２は、コンピュータプログラムの処理対象のリソース（メモリ１１４）の状態の変化を監視し、予め定められた状態変化を逸脱した場合に、プログラムエラーと判定する。【選択図】図１
2006252583.tif 000002
【特許請求の範囲】
【請求項１】
複数のステートメントを有するプログラムコンポーネントのエラーをチェックするための、コンピュータにおける方法であって、
前記コンピュータは前記プログラムコンポーネントを記憶する記憶手段と、情報処理手段と、判定手段と前記プログラムコンポーネントの処理対象となるリソースとを有し、
前記記憶手段に記憶されたプログラムコンポーネントの複数のステートメントを前記情報処理手段により実行するステップと、
前記情報処理手段により前記複数のステートメントを実行することにより生じた前記リソースの状態の変化が予め定められた変化であるか否かを判定することで前記プログラムコンポーネントがエラーか否かを前記判定手段により判定するステップと
を備えたことを特徴とする方法。
【発明の詳細な説明】
【技術分野】
【０００１】
コンピュータプロセスのリソースのモデル化方法及び装置付録Ａについて本開示の一部である付録Ａは、以下により詳しく説明する本発明の一実施例におけるコンピュータプログラム及び関連するデータのリストである。
【０００２】
本特許文献の開示の一部には著作権保護に従う題材が含まれている。本著作権所有者は、特許商標庁の特許ファイルまたは記録に掲載される場合は、本特許文献または特許開示が誰によって複製されてもそれに異議を唱えるものではないが、それ以外の場合は全ての著作権を保留するものである。
【０００３】
本発明はコンピュータプログラムの解析に関する。特に、コンピュータプログラムによって定められたリソースの使用の解析を通して、コンピュータプログラム内のプログラミングエラーを検出することに関する。
【背景技術】
【０００４】
既存のプログラミングエラー検出方法には、特定のプログラムが従うべきコンピュータ命令プロトコル（ｃｏｍｐｕｔｅｒ  ｉｎｓｔｒｕｃｔｉｏｎｐｒｏｔｏｃｏｌ）における違反を検出するものがある。そのようなプログラムエラー検出方法は“スタティックチェック法（ｓｔａｔｉｃ  ｃｈｅｃｋｉｎｇ）”と呼ばれているが、それはコンピュータプログラムのコンピュータ命令（または“ステートメント”）の文法が、それらのステートメントの実行から生じる挙動の文脈（ｃｏｎｔｅｘｔ）の外で解析されるからである。“ステートメント”という用語は、本明細書中では、Ｈｅｒｂｅｒｔ  Ｓｃｈｉｌｄｔによる“注釈版ＡＮＳＩ  Ｃスタンダード（Ｏｓｂｏｒｎｅ  ＭｃＧｒａｗ−Ｈｉｌｌ  １９９０）”（以下、Ｃスタンダードと呼ぶ）として再版された“Ａｍｅｒｉｃａｎ  Ｎａｔｉｏｎａｌ  Ｓｔａｎｄａｒｄ  ｆｏｒ  ＰｒｏｇｒａｍｍｉｎｇＬａｎｇｕａｇｅｓ−−Ｃ（Ａｍｅｒｉｃａｎ  Ｎａｔｉｏｎａｌ  Ｓｔａｎｄａｒｄｓ  Ｉｎｓｔｉｔｕｔｅ／Ｉｎｔｅｒｎａｔｉｏｎａｌ  Ｏｒｇａｎｉｚａｔｉｏｎ  ｆｏｒ  Ｓｔａｎｄａｒｄｉｚａｔｉｏｎ  ＡＮＳＩ／ＩＳＯ  ９８９９−１９９０）”のセクション６．６において定義されている意味で使用される。簡単に説明すると、Ｃ言語の文脈において、ステートメントとは宣言ではないコンピュータ命令である。言い換えると、ステートメントとは、コンピュータに指示を与えて１または複数の処理過程を実行させる任意の式または命令である。Ｃ言語の文脈におけるスタティックチェック法には、（ｉ）コンピュータプログラム中に同じ名前が付けられた２つの変数がないことを確認すること、（ｉｉ）各“ｂｒｅａｋ”ステートメントが先行する“ｗｈｉｌｅ”、“ｆｏｒ”または“ｓｗｉｔｃｈ”ステートメントに対応していることを確認すること、及び（ｉｉｉ）演算子が適切なオペランドに対して施されていることをベリフィケーションすることなどが含まれる。スタティックチェック法については、例えば、Ａｌｆｒｅｄ  Ｖ．Ａｈｏ  らによる“Ｃｏｍｐｉｌｅｒｓ（Ａｄｄｉｓｏｎ  Ｗｅｓｌｅｙ  １９８８）”に記載されている。
【０００５】
一般に“データ流れ解析”技法と呼ばれている、既存のスタティックチェック法のあるものは、プログラミングエラーを検出するため、プログラム中のデータの流れを解析する。このような解析は、例えば、ある変数に値が代入される前にその変数を使用するといった不適切なデータオブジェクトの使用を検出するため、ステートメント及びループステートメントを順に並べるなどして、制御流れ情報を活用する。あるコンピュータプログラムにおける制御流れとは、そのコンピュータプログラムによって定義されるコンピュータプロセスにおいてそのコンピュータプログラムのコンピュータ命令が実行されていく特定の順序のことである。コンピュータプログラム及びプロセス、及びそれらの関係については、後により詳しく説明する。データ流れ技法については、Ｂｅｉｚｅｒによる“Ｓｏｆｔｗａｒｅ  Ｔｅｓｔｉｎｇ  Ｔｅｃｈｎｉｑｕｅｓ，（１９９０）ｐｐ．１４５−１７２”に記載されている。
【０００６】
既存のスタティックチェック法には、まとまってコンピュータプログラムを形成する関数のようなコンピュータプログラムの幾つかの個々のコンポーネントを通じたリソースの使用の追跡が不可能であるという欠点がある。例えば、ある変数が第１の関数において初期化され、第２のそれに続いて実行される関数における計算において使用されるということがあり得る。第２の関数のコンピュータ命令を解析するだけでは、その変数は初期化される前に使用されるようにみえ、これは誤ってエラーとして通知される可能性がある。更に、既存のスタティックチェック法は本質的に静的（ｓｔａｔｉｃ）であり、特定のデータオブジェクトに関連付けられる特定のデータ値を考慮することはない。静的な解析は、プログラムの実行の動的な効果を考慮することなく決定することができることに限定される。Ｂｅｉｚｅｒは、静的な解析が不適当である幾つかの領域について述べている。それらには、配列、特に動的に計算される指標及び動的に割り当てられる配列；レコード及びポインタ；ファイル；及び交互状態テーブル（ａｌｔｅｒｎａｔｅ  ｓｔａｔｅ  ｔａｂｌｅｓ）が含まれる。これらは同じプログラムにおいて異なる型の異なる意味（ｓｅｍａｎｔｉｃｓ）を表す。
【０００７】
スタティックチェッカ（ｓｔａｔｉｃ  ｃｈｅｃｋｅｒ）は、動的に割り当てられるメモリ（ｄｙｎａｍｉｃａｌｌｙ  ａｌｌｏｃａｔｅｄ  ｍｅｍｏｒｙ）に対応して計算されるアドレスまたは配列をなすように計算される指標を含むエラーを検出しない。計算されるアドレス及び指標は、それぞれコンピュータプロセスの実行中に計算されるアドレス及び指標である。スタティックチェッカがそのようなエラーをコンピュータプログラム中で検出しないのは、そのようなエラーの調査には、通常、計算されるアドレス及び指標の正確な値を決定することが含まれ、それには実行時のコンピュータプログラムの挙動を考慮すること即ちコンピュータプロセスとして考慮することが含まれるからである。
【０００８】
またスタティックチェッカは、正常に割り当てられるか疑わしいリソースの使用や、変数または他のデータオブジェクトの値によって状態を決定されるリソースの使用を含むエラーを検出しない。Ｃ言語では、リソース（例えば、動的に割り当てられるメモリまたはファイル）が正常に割り当てられるかどうか疑わしい。言い換えると、リソースを割り当てる関数は、リソースの割り当てに失敗しても正常に終了する。割り当てが成功したかどうかは、関数の戻り値項目（割り当てられたリソースを指すポインタ）を無効値（例えばＮＵＬＬ）と比較することによって判定されるのだが、スタティックチェッカは呼び出される関数の挙動を考慮することはせず、被呼び出し関数に対する呼び出しの文法が、特定のコンピュータ言語において定められた文法に従っているかどうかのみをベリフィケーションする。従って、スタティックチェッカは正常に割り当てられるかどうか疑わしいリソースの使用を含むエラーを検出しない。
【０００９】
上述したように、スタティックチェッカは呼び出される関数の挙動を考慮しない。従って、複数の関数にまたがったリソースの使用をベリフィケーションすることは不可能である。例えば、第１の関数がリソースを割り当てを行い（ａｌｌｏｃａｔｅ）、第２の関数がそのリソースを使用し、第３の関数がそのリソースを開放（ｄｅａｌｌｏｃａｔｅ）する場合、第１、第２、及び第３の関数のいずれかを単独で、または３つの関数の全ての呼び出しをする一つの関数を静的に調べることによっては、リソースの適切な使用をベリフィケーションすることはできない。
【００１０】
実行時のコンピュータプログラムの挙動に関する情報を十分に使用しないエラー検出技法が用いられる場合、そのような技法によって検出されるエラーは過小に検出されるかあるいは過大に検出されるかのいずれかとなる。例えば、ある関数が、割り当てられるリソース（例えば、ファイル）を指定するポインタをパラメータとして受け取り、そのパラメータを無効ポインタと比較することなく使用するような場合、その関数はエラーを含む可能性を有する。その関数がエラーを含むかどうかは、その関数の文脈内ではわからない様々な状況に依存する。例えば、そのポインタが関数が呼び出される前に有効なポインタであるとベリフィケーションされる場合、その関数はエラーを含まない。そのポインタの使用をエラーとして通知することは、誤ったエラー通知でその関数の解析を混乱させ、エラーを過大にすることとなる。大きなプログラムの解析において誤ってエラーを通知することは、よくてもプログラム開発者をわずらわせ、悪ければコンピュータプログラムの解析を役に立たないものとしてしまう。関数を呼び出す前にポインタが有効であるかチェックされない場合に、エラーの通知をしないと、実行時にコンピュータプログラムを突然アボートさせ、データ構造の破壊や有効なデータの損失といった結果を生じさせ得るエラーの検出がなされないこととなる。
【００１１】
コンピュータプログラムの動的な挙動を考慮しないスタティックチェック法の欠点の１つは、明白な、しかし“虚偽の”エラーの通知をすることである。即ち、制御が流れ得ないコンピュータ命令から生じるエラーを通知することである。
制御流れ経路（ｃｏｎｔｒｏｌ  ｆｌｏｗｐａｔｈ）が特定のデータ構造及びプログラム変数に関連付けられる特定の値に依存するような関数では、制御流れはこれらのデータ構造及び変数に関連付けられる値を考慮することなくして決定することはできない。また、これらのデータ構造及び変数に関連付けられる値は、一般に、実行時の関数の挙動を考慮することなくして決定することはできない。その結果、実行されない命令または特定の状態の下でしか実行されない命令は一般にスタティックチェッカでは常に実行されるものと仮定される。
【００１２】
既存のプログラミングエラー検出技法の別のタイプに、プログラムベリフィケーション（ｐｒｏｇｒａｍ  ｖｅｒｉｆｉｃａｔｉｏｎ）と呼ばれるものがある。プログラムベリフィケーションでは、コンピュータプログラムは形式的な数学的対象として扱われる。コンピュータプログラム中のエラーは理論数学を用いてコンピュータプログラムの所定の特性を立証すること、または立証するのに失敗することによって検出される。一般に立証が試みられる特性の１つは、所定の入力が与えられたとき、コンピュータプログラムによって定義されたコンピュータプロセスが所定の出力を生成するということである。その立証が失敗に終わる場合、コンピュータプログラムはプログラミングエラーを含む。このようなプログラムベリフィケーション技法は、例えば、Ｅｒｉｃ  Ｃ．Ｒ．Ｈｅｈｎｅｒらによる“Ａ  ＰｒａｃｔｉｃａｌＴｈｅｏｒｙ  ｏｆ  Ｐｒｏｇｒａｍｍｉｎｇ，（Ｖｅｒｌａｇ  １９９３）”及び  Ｏｌｅ−Ｊｏｈａｎ  Ｄａｈｌによる“Ｖｅｒｉｆｉａｂｌｅ  Ｐｒｏｇｒａｍｍｉｎｇ，（Ｐｒｅｎｔｉｃｅ  Ｈａｌｌ  １９９２）”に記載されている。
【００１３】
プログラムベリフィケーション技法は少なくとも２つの意味で制約を受ける。
即ち、（ｉ）形式的論理を用いて表現し自動的に立証することができるコンピュータプログラムの特性のみがベリフィケーション可能である、（ｉｉ）コンピュータプログラムの開発者は、コンピュータプログラムの特性を形式的に明確に表さなければならない。コンピュータプログラムの特性を形式的に表すことは、どんな場合にも極めて困難なことであり、大きなプログラムでは殆ど不可能である。そのため、プログラムベリフィケーション技法を用いた商業的に成功した商品は極めて希である。
【００１４】
プログラミングエラー検出技法の別のタイプでは、コンピュータプログラムが実行され、従ってコンピュータプロセスが形成され、コンピュータプロセスの挙動が監視される。コンピュータプログラムの解析がプログラムの実行中になされるため、そのようなプログラムエラー検出技法は“ランタイムチェック法（ｒｕｎｔｉｍｅ  ｃｈｅｃｋｉｎｇ）”と呼ばれる。ランタイムチェック技法の中には、コンピュータ命令をコンピュータプログラム中に自動的に挿入して、コンピュータプログラムの実行時に、挿入されたコンピュータ命令が実行されることによって、コンピュータプログラムの変数及びリソースの状態が示されるようにするものがある。そのようなエラー検出技法は、Ｈａｓｔｉｎｇｓに付与された米国特許第５，１９３，１８０号明細書に記載されている。
【００１５】
ランタイムチェックでは、通常、メモリリーク（ｍｅｍｏｒｙ  ｌｅａｋｓ）や禁止領域に入った配列の指標のようなエラーを検出することができる。ランタイムチェックの例として、カリフォルニア州サニーベイル（Ｓｕｎｎｙｖａｌｅ，Ｃａｌｉｆｏｒｎｉａ）“Ｐｕｒｅ  Ｓｏｆｔｗａｒｅ  Ｉｎｃ．”から入手可能な“Ｐｕｒｉｆｙ”や、カリフォルニア州パサデナ（Ｐａｓａｄｅｎａ，Ｃａｌｉｆｏｒｎｉａ）の“Ｐａｒａｓｏｆｔ  Ｃｏｒｐｏｒａｔｉｏｎ”から入手可能な“Ｉｎｓｉｇｈｔ”などがある。“Ｐｕｒｉｆｙ”は、コンピュータがコンパイルされてオブジェクトコード形式になった後にコンピュータプログラムをモニタリングするためのコンピュータ命令を挿入する。“Ｉｎｓｉｇｈｔ”は、コンピュータプログラムがコンパイルされる前に、即ちコンピュータプログラムがまだソースコード形式のときに、コンピュータプログラムをモニタリングするためのコンピュータ命令を挿入する。
【発明の開示】
【発明が解決しようとする課題】
【００１６】
ランタイムチェックは、一般に、実際の特定の入力を使ってコンピュータプログラムのコンピュータ命令を実際に実行することによって判定可能なものに限定される。ランタイムチェッタ法はコンピュータプログラムの制御の流れの全経路を考慮することはせず、実行時にコンピュータプログラムに与えられる特定の入力に対応した経路しか考慮しない。一般に、コンピュータプログラムのコンピュータ命令の実行によって形成されるコンピュータプロセスを、全ての可能な制御流れ経路を通るようにすることは実際的ではない。そのようにするには、プログラマーが、コンピュータプログラムのコンピュータ命令の実行時に発生し得る全ての事象を予期し、そのような事象発生の全ての組み合わせを生じさせるまたはエミュレートすることが必要であるからである。
【００１７】
更に、ランタイムチェックは、コンピュータプログラムが完成しているときしか使用することができない。ランタイムチェックでは、ある１つの関数が完成したプログラムに組み込まれる前に、その関数を解析することは不可能である。なぜなら、解析するにはその関数を実行しなければならないからである。従って、ランタイムチェックを用いて関数を解析するには、（ｉ）コンピュータプログラムの全ての関数が、それらの関数のどれかを解析するよりも前に、開発され、組み合わされてコンピュータプログラムを形成していること、または（ｉｉ）その関数を組み込んだ特別なテストプログラムが開発されていることが必要である。従って、完成したコンピュータプログラムへの組み込み前に個々の関数の設計、制作及びテストを行う、複雑なコンピュータプログラムを開発する好適な方法であり広く知られているトップダウン式のプログラミングは、ランタイム解析にはなじまない。
【００１８】
スズキらに付与された米国特許第５，２５３，１５８号（以下「スズキ」と言う）明細書には、自動化された機器の動作を制御するために用いられるべきソウトウェア（シーケンサソウトウェア）の実行時間チェックを行う装置が開示されている。「スズキ」によれば、自動化された機器を用いずにシーケンサソフトウェアの試験ができる。「スズキ」の発明では、ソフトウェアの動作環境に関する情報、自動化された機器の特性に関する情報、実行されるべきテストケースに関する情報が、記憶装置に格納されている（第１図）。次に、「スズキ」の発明では、シーケンサソフトウェアによって制御された自動化された機器の動作をシミュレートし、シミュレートされた結果が得られる（第１欄の第５４行から第５９行）。「スズキ」の発明のシミュレーションは、シーケンサソフトウェアの実行を必要とする（第４欄の第５０行）。「スズキ」に開示された実行時間チェック装置は、  これまで説明されたように、実行時間の解析の限界に対する主題であった。
【００１９】
フ・ティン・チャン及びツォン・ユゥエ・チェンは、「ＡＩＤＡ−Ａ  Ｄｙｎａｍｉｃ  Ｄａｔａ  Ｆｌｏｗ  Ａｎｏｍａｌｙ  Ｄｅｔｅｃｔｉｏｎ  Ｓｙｅｔｅｍ  ｆｏｒ  Ｐａｓｃａｌ  Ｐｒｏｇｒａｍｓ，  Ｓｏｆｔｗａｒｅ  Ｐｒａｃｔｉｃｅ  Ａｎｄ  Ｅｘｐｅｒｉｅｎｃｅ第２２７頁−第２３９頁（１９８７年３月）」で、パスカルプログラム用の動的データ流れ解析システムについて説明している。ＡＩＤＡ（ａｕｔｏｍａｔｅｄ  ｉｎｓｔｒｕｃｔｉｏｎ  ｓｙｓｔｅｍ）は、文法的に補正されたパスカルプログラムを解析し、このプログラムをインストラクションプログラムに変換する。インストラクションプログラムは、もとのパスカルソースコードに挿入された変数の状態を初期化、追従、若しくはチャックするための手続コールの形式を検査する。プログラムの実行中、ＡＩＤＡは、データの流れの異常と、初期化されていない変数、変数の不正な使用、変数の誤った分類化、定義された変数の意図しない破壊などのプログラミングエラーを検出する。ＡＩＤＡは、上述されたように、実行時間解析の限定に対する主題となっている。
【００２０】
必要とされているのは、コンピュータプログラムの動的な挙動を考慮し、自動的にコンピュータプログラムの概ね全ての制御流れ経路を考慮し、コンピュータプログラムのプログラマーがコンピュータプログラムを別の形式、例えば数学的形式、で表すことを必要としないプログラミングエラー検出技術である。更に必要とされているのは、プログラムの個々のコンポーネントを、実行時のそのコンポーネントの挙動を考慮して解析するプログラミングエラー検出技術である。更に必要とされているのは、解析中のコンピュータプログラムコンポーネントによって実行を喚起されるコンポーネントの挙動を考慮するプログラミングエラー検出技術である。
【課題を解決するための手段】
【００２１】
このような課題を解決するために、本発明は、複数のステートメントを有するプログラムコンポーネントのエラーをチェックするための、コンピュータにおける方法であって、前記コンピュータは前記プログラムコンポーネントを記憶する記憶手段と、情報処理手段と、判定手段と前記プログラムコンポーネントの処理対象となるリソースとを有し、前記記憶手段に記憶されたプログラムコンポーネントの複数のステートメントを前記情報処理手段により実行するステップと、前記情報処理手段により前記複数のステートメントを実行することにより生じた前記リソースの状態の変化が予め定められた変化であるか否かを判定することで前記プログラムコンポーネントがエラーか否かを前記判定手段により判定するステップとを備えたことを特徴とする。
【００２２】
本発明の一形態によると、コンピュータプログラムによって使用されるリソースの挙動をモデル化し、それらのリソースにおいて発生する可能性のある状態違反を検出することによって、コンピュータプログラムの解析がなされコンピュータプログラム中のプログラミングエラーが検出される。リソースは、リソース状態とリソースの挙動を表すリソース状態遷移（変化）とに基づいてモデル化される。コンピュータプログラムのコンピュータ命令は動的に検査される。即ち、コンピュータ命令の動的挙動が決定され、コンピュータ命令の動的挙動に従ってリソースの状態が変化させられる。
【００２３】
コンピュータプログラムの各コンポーネントは個々に解析される。使用が複数のコンポーネントに渡るリソース、例えば第１コンポーネントによって割り当てられ、第２コンポーネントによって使用され、第３コンポーネントによって開放されるリソースの使用は、各コンポーネントのエクスターナル（ｅｘｔｅｒｎａｌ）をモデル化することによって解析される。コンピュータプログラムの２つのコンポーネントは、各コンポーネントのエクスターナルを通じて互いにコミュニケートする。例えば、第１コンポーネントによって割り当てられるリソースに関する情報が、そのリソースを使用する第２コンポーネントに、第１及び第２コンポーネントのエクスターナルを通して伝達される。各コンポーネントの挙動をそのコンポーネントのエクスターナルに関して解析することによって、使用が複数のコンポーネントに渡るリソースの適切なモデル化がなされる。
【００２４】
各コンポーネントが解析されると、コンポーネントの実行がそのコンポーネントの各エクスターナルに与える影響が決定される。コンポーネントの解析から、コンポーネントのモデルが生成される。コンポーネントのモデルは、そのコンポーネントの実行がそのコンポーネントの各エクスターナルに対して与える影響を、エクスターナルのそれぞれの状態の変化とそのコンポーネントのいずれかのエクスターナルに関連付けられる新たなリソースの導入とに関して記述するものである。モデル化されるコンポーネントの実行が与える影響の数及び影響されるエクスターナルは任意であり、これらの影響はエクスターナルの複合状態（ｃｏｍｐｏｓｉｔｅ  ｓｔａｔｅ）に表される。生成されたコンポーネントのモデルは、モデル化されたコンポーネントの実行を喚起する他のコンポーネントの解析に用いることができる。
【発明の効果】
【００２５】
本発明によると、コンピュータプログラム中のエラーは、そのコンピュータプログラムによって使用されるリソースをモデル化し、それらのリソースに於いて発生し得る状態違反（ｓｔａｔｅ  ｖｉｏｌａｔｉｏｎ）を検出することによって検出される。
【００２６】
まず、リソースの挙動をリソースの状態と状態遷移とに関して模擬することによってリソースをモデル化する。コンピュータプログラムの各コンピュータ命令を解析し、コンピュータ命令の実行がリソースに及ぼす影響に基づいてリソースの状態を変化させる。状態違反、即ちリソースの状態に於ける無効な状態及び無効な状態遷移を検出し、プログラムエラーとして通知する。このようにして、本発明によるエラー検出はコンピュータプログラムによって定義されたコンピュータプロセスの挙動を考慮し、それによって従来技術のスタティックチェック法の制約の多くを克服するものである。
【発明を実施するための最良の形態】
【００２７】
各リソースは所定の挙動を有し、それは有効な状態とそれらの状態間の有効な遷移とに関して記述することができる。コンピュータプログラムに於けるエラー発生の源は、しばしばコンピュータプログラムの開発者がリソースの所定の挙動を把握していないことにある。コンピュータプログラム中のコンピュータ命令によって、リソースの所定の挙動に違反したリソースの使用がコンピュータに指示されると状態違反が発生する。状態違反の例として、例えば、ファイルの所定の挙動によれば読み出しをするにはファイルが開かれていなければならない場合において、ファイルを閉じた後のファイルからのレコードの読み出しがある。
【００２８】
コンピュータ１００（第１図）には、中央演算装置（ＣＰＵ）１０２、メモリ１０４、及び入力／出力回路（Ｉ／Ｏ回路）１０６が含まれており、これらは全てバス１０８を介して互いに接続されている。メモリ１０４は、磁気ディスクのような二次記憶装置、ランダムアクセスメモリ（ＲＡＭ）、読み出し専用メモリ（ＲＯＭ）を含む任意のタイプのメモリを含み得る。ＣＰＵ１０２は、メモリ１０４からコンピュータプロセス１１０を読み出して実行する。コンピュータプロセス１１０は、ライブラリ関数１１２、動的に割り当てられるメモリ１１４、及び第２コンピュータプロセス１１６に対するアクセスを有する。Ｉ／Ｏ回路１０６は、ドライバ１０６Ａ、１０６Ｂ、１０６Ｃ、１０６Ｄ、及び１０６Ｅを含んでおり、これらのドライバはそれぞれビデオモニタ１１８、二次記憶装置１２０、ネットワーク１２６、ポインティングデバイス（マウス１２２など）、キーボード１２４を駆動・制御する。
【００２９】
本明細書中では、リソースはコンピュータプロセスによって使用されるコンピュータシステムの一部であり、一般に、使用前に割り当てられ、使用後に開放、即ちフリーにされなければならない。リソースの例として、グローバルメモリ、ファイル、ウインドウ、メニュー、及びダイアログ（ｄｉａｌｏｇ）がある。コンピュータプロセス１１０のリソースには、例えば、動的に割り当てられるメモリ１１４、コンピュータプロセス１１６、磁気ディスク１２０が含まれる。
【００３０】
また本明細書中において、コンピュータプロセスとはコンピュータによって実行される一連の過程（ｓｔｅｐ）である。コンピュータプログラムはコンピュータによって実行されうる一連の命令である。コンピュータプログラムの命令によって過程が定義され、それらがコンピュータにより実行されると、コンピュータプロセスが形成される。従って、コンピュータプロセス１１０の挙動をモデル化するため、コンピュータプロセス１１０を定義するコンピュータプログラムの解析がなされる。
【００３１】
関数レベルでの解析 
コンピュータプログラムは、通常、既に開発されているコンポーネントと新たに開発されるコードとを組合せたものである。本明細書中において、“コード”はソースコード、即ち人間に理解可能な形式の一連のコンピュータ命令、及び／またはオブジェクトコード、即ちコンピュータに理解可能な形式の一連のコンピュータ命令を表す。コンピュータプログラムのコンポーネントとは、特定の部分プロセスを実行するように既に開発され、通常、その部分プロセスが忠実に実行されることが試験済みであるコンピュータ命令及び／またはデータ構造の集まりである。部分プロセスとは、コンピュータプロセス中の１または複数の過程であり、即ちコンピュータプロセスの一部である。コンピュータプログラムの開発者は、特定の部分プロセスを実行するためこのようなコンポーネントを使用し、通常、そのコンポーネントを信頼しており、実行時には定められた通りに機能するものと思っている。そのようなコンポーネントは、開発者が既に開発したコンポーネントまたは商業的に入手可能なコンポーネントの実行の要求、即ち呼び出し（ｃａｌｌ）を含むことができる。そのようにして、コンピュータプログラムの開発に於ける作業の重複が避けられている。
【００３２】
新たなコンピュータプログラムは、通常、開発済みのコンポーネントを組み合わせ、新たに書かれたコンピュータ命令を用いてこれらのコンポーネントを互いに接続することによって開発される。そのような組合せ及び相互接続の結果、他のコンポーネントまたはコンピュータプログラムによって使用可能な新たなコンポーネント、または新たなコンピュータプログラムが生成される。あるコンピュータプログラムのコンポーネントは、そのコンピュータプログラムによって定義されるコンピュータプロセスの部分プロセスを定義する。コンピュータプロセスの各部分プロセスは、そのコンピュータプロセスによって用いられるリソースの状態を変化させ得る。従って、あるコンピュータプロセスによって用いられるリソースの状態及び状態遷移を適切に解析するには、コンピュータプログラムのコンポーネントによって定義される部分プロセスの実行がリソースの状態に与える影響を確かめなければならない。例えば、第１コンポーネントによって定義される第１部分プロセスに於いて割り当てられ、第２コンポーネントによって定義される第２部分プロセスに於いて使用され、第３コンポーネントによって定義される第３部分プロセスに於いて開放されるリソースの使用を適切に解析するには、第１、第２、及び第３部分プロセスのリソースに対する影響を解析することが必要である。
【００３３】
コンピュータプログラムは、様々なコンピュータ言語の何れで書かれていても良い。典型的なコンピュータ言語は手続き型である。手続き型言語において、コンピュータプログラムのコンピュータ命令は編成されてコンポーネントを形成し、これらのコンポーネントは、しばしば手続き、または“関数”と呼ばれる。それらは各々実行されたとき特定の部分プロセスを実行するように設計される。手続き型言語の例として、Ｃ、Ａｄａ、Ｐａｓｃａｌ、Ｆｏｒｔｒａｎ及びＢａｓｉｃがある。手続き型言語にはオブジェクト指向のものがあり、そのようなものとして例えばＣ＋＋やＳｍａｌｌＴａｌｋがある。オブジェクト指向コンピュータ言語では、関数及びデータ構造が結合されてオブジェクトが形成され、それらのオブジェクトが更に編成されて“クラス（ｃｌａｓｓ）”として知られるコンポーネントが形成される。
【００３４】
コンピュータ言語にはグラフィックベースのものがあり、そのようなコンピュータ言語では、命令はコンピュータスクリーン上に表示されるグラフィックイメージとして表される。プログラマーはそれらのグラフィックイメージをリンクしてコンピュータプログラムを形成する。例えば、ワシントン州レッドモンド（Ｒｅｄｍｏｎｄ，Ｗａｓｈｉｎｇｔｏｎ）のマイクロソフト社（Ｍｉｃｒｏｓｏｆｔ  Ｃｏｒｐｏｒａｔｉｏｎ）から入手可能な“Ｍｉｃｒｏｓｏｆｔ  Ｖｉｓｕａｌ  Ｂａｓｉｃ”は、そのようなグラフィックベースのコンピュータ言語である。コンピュータ言語には、マイクロソフト社から入手可能な“Ｍｉｃｒｏｓｏｆｔ  Ｗｏｒｄ”ワープロソフト用の“Ｍｉｃｒｏｓｏｆｔ  Ｗｏｒｄ  Ｂａｓｉｃ”というコンピュータ言語や、マサチューセッツ州ケンブリッジ（Ｃａｍｂｒｉｄｇｅ，Ｍａｓｓａｃｈｕｓｅｔｔｓ）のロータスディベロップメント社（Ｌｏｔｕｓ  Ｄｅｖｅｌｏｐｍｅｎｔ  Ｃｏｒｐｏｒａｔｉｏｎ）から入手可能な“Ｌｏｔｕｓ  １−２−３”表計算ソフト用の“Ｌｏｔｕｓ  １−２−３”マクロ言語のように、特定のソフトウェア製品を対象としたものもある。本発明は、任意のコンピュータ言語、即ちリソースが使用される任意のコンピュータ命令プロトコルに適用可能である。ソースコードのコンピュータ命令プロトコルについて上記で述べたが、本明細書中に開示することは、オブジェクトコード形式のコンピュータ命令にも同じように適用可能であることを理解されたい。以下に示す例示的な実施形態では、解析されるコンピュータ言語はＣスタンダードに説明されている良く知られたＣ言語である。
【００３５】
Ｃ言語で書かれたコンピュータプログラムは、通常、いくつかの関数に分割される。関数は、実行されると、入力として０または１以上のパラメータを受け取り、出力として１つの戻り値項目（ｒｅｔｕｒｎｅｄ  ｉｔｅｍ）を生成することもあるが、戻り値項目を生成しないこともある。これらのパラメータ及び戻り値項目はデータ構造であり、その関数によってアクセス可能なデータを含み、例えばメモリ１０４のようなメモリに格納される。Ｃ言語で定義された関数の例を、後にコンピュータコードの抜粋（１）に示す。
【００３６】
本明細書中で述べる例示的な実施形態では、コンピュータプログラム内の各関数は個々に解析される。関数は、その関数のコンピュータ命令によって影響されるその関数のリソース、エスクターナル及び項目の使用及び変化をモデル化することによって解析される。関数の項目（ｉｔｅｍ）は、その関数によってアクセス可能なメモリ（例えばメモリ１０４）中の位置を表す。項目は型（ｔｙｐｅ）と値（ｖａｌｕｅ）とを有する。本発明の一実施例においてサポートされる項目の型には、整数、浮動小数点、及びポインタ（ｐｏｉｎｔｅｒ）データが含まれる。項目の値とは、その項目によって表されるメモリ内の位置に格納された特定のデータによって表される値である。エクスターナル及びリソースは、関数の各項目に関連付けられ得る。項目については後により詳細に説明する。変数（ｖａｒｉａｂｌｅ）が、識別子（ｉｄｅｎｔｉｆｉｅｒ）と１または複数の項目との間を関連付ける。
【００３７】
関数のエクスターナルは、その関数の文脈の外、即ち、その関数の実行の始まる前またはその関数の実行が終了した後に存在するコンピュータプログラムの一部を表す。関数のエクスターナルの例には、関数のパラメータ及び戻り値項目、グローバル定義変数、及びスタティック変数が含まれる。用語（ｉ）“グローバル定義変数”及び（ｉｉ）“スタティック変数”は、本明細書中では、それぞれ（ｉ）リンケージが“外部的（ｅｘｔｅｒｎ）”な変数、及び（ｉｉ）リンケージが“内部的（ｉｎｔｅｒｎ）”で格納期間が“静的”な変数を表すのに使用される。“ローカル定義変数”はリンケージが“内部的”で格納期間が“自動的（ａｕｔｏｍａｔｉｃ）”な変数である。リンケージ（ｌｉｎｋａｇｅ）については、Ｃスタンダードのセクション６．１．２．２に説明されており、格納期間（ｓｔｏｒａｇｅ  ｄｕｒａｔｉｏｎ）についてはＣスタンダードのセクション６．１．２．４に説明されている。簡単に説明すれば、グローバル定義変数は、コンピュータプロセスの全部分プロセスに対し定義され、スタティック変数は幾つかの部分プロセスに対し定義されるが、コンピュータプロセスの全部分プロセスに対して定義されるとは限らない。
【００３８】
各部分プロセスは幾つかのリソースを使用する。例えば、プロセス１１０（第１図）の関数２０２（第２図）は、動的に割り当てられるメモリ１１４、及びコンピュータプロセス１１６を使用する。また関数２０２（第２図）は、（ｉ）関数２０２Ａ及び２０２Ｂ及び他の関数によってもアクセス可能なグローバル定義メモリ２０４と、（ｉｉ）ローカルメモリと、（ｉｉｉ）パラメータ２０８Ａ〜２０８Ｃと、（ｉｖ）戻り値項目２１０も使用する。関数２０２は、これらのリソースの１または複数をモデル化することによって解析される。
【００３９】
各リソース及びエクスターナルは状態（ｓｔａｔｅ）を有する。関数の各コンピュータ命令の実行は、コンピュータ命令の実際の実行によって生じるであろうその関数のリソースまたはエクスターナルの状態の変化をモデル化することによってエミュレートされる。エクスターナルまたはリソースの状態が変化する場合、その状態変化はそれぞれ対応するエクスターナル挙動モデルまたはリソース挙動モデルと比較され、その状態変化がエクスターナルまたはリソースの適切な使用を反映しているかどうかが判定される。状態変化が不適切である場合は、状態違反が発生し、エラーが通知される。エラーのユーザへの通知は、（ｉ）エラーメッセージをビデオモニタ１１８（第１図）または同様の出力装置に表示することによって、（ｉｉ）エラーメッセージをメモリ１０４または二次記憶装置１２０のエラーログファイルに記録することによって、または（ｉｉｉ）エラーメッセージの表示とエラーメッセージの記録を両方とも行うことによって可能である。
【００４０】
挙動モデル 
関数モデルは、関数をその関数が割り当てる新たなリソース及びその関数のエクスターナルにその関数が施す演算に関して、抽象して表したものである。
上述したように、リソースは状態を有する。リソースの有効な状態及び有効な状態間遷移は、リソース挙動モデルによって表される。リソースの挙動のモデル化は、そのリソースの実際の挙動よりも大幅に簡略化され得る。例えば、リソースの状態は、状態図３００（第３Ａ図）によって表されるリソース挙動モデルに基づいてモデル化される。状態図３００に基づくと、リソースは次の状態の何れかを取り得る。
【００４１】
【表１】
2006252583.tif 000003
【００４２】
状態ＵとＸは似ているが別のものである。未割り当てのリソースに関連付けられた項目は不定値を有し、無効なリソースに関連付けられた項目は既知の無効値（ｉｎｖａｌｉｄ  ｖａｌｕｅ）を有する。リソース挙動モデルは挙動がモデル化されるリソースの実際の挙動と同程度に複雑になり得る。しかしながら、状態図３００に表されたような大幅に簡略されたリソース挙動モデルでも、そのようなリソースの使用に於いて発生し得る全エラーのほとんどを検出する上で有効である。
【００４３】
リソースは最初は割り当てられていないため、状態Ｕにある。各コンピュータ命令のエミュレートされた実行（それらを実際に実行するとリソースの状態変化を引き起こす）によって、リソースに演算（ｏｐｅｒａｔｉｏｎ）が施される。リソースに演算を施すことによって、リソースの状態は状態図３００に従って変化する。
以下にリソースに施すことのできる演算を示す。
【００４４】
【表２】
2006252583.tif 000004
【００４５】
このように、状態図３００に従うと、未割り当てのリソース、即ち状態Ｕにあるリソースに対し、ある関数内の命令によって適確な割り当てがなされる場合、即ち演算ａが施される場合、そのリソースは状態Ａ、即ち割り当てられた状態となる。しかしながら、未割り当てのリソース、即ち状態Ｕにあるリソースが計算に於いて使用される（従って演算ｃを施される）と、そのリソースは状態Ｅとなる。状態Ｅは、プログラミングエラーの結果、状態違反が起こったことを示す。状態Ｅはリソースの予め定められた挙動を表すものではなくオプション的なものであるが、開示する実施例に於いては、状態違反を表す便利な方法として使用される。別の実施例では状態Ｅは省略され、状態違反は上記の例に於いてリソースが状態Ｕにあるとき、演算ｃが定義されないことに注目することによって検出される。
状態図３００（第３Ａ図）は表Ｃのようにまとめられる。
【００４６】
【表３】
2006252583.tif 000005
【００４７】
状態図３００中の演算識別子に対応している上付の数字、及び表Ｃに於いて新たな状態識別子に付されている上付の数字は、特定のエラーを示している。これらのエラーは、次の表Ｄに示す通りである。
【００４８】
【表４】
2006252583.tif 000006
【００４９】
上述の例では、演算ｃを状態Ｕにあるリソースに施すことによって、状態図３００に於いて状態Ｕから状態Ｅへと向かう“ｃ２”によって識別される矢印によって示されているように、リソースは状態Ｅに置かれる。このように、この例に於けるエラーは表Ｄに示したエラー番号２、即ち未割り当てのリソースの使用である。
【００５０】
各関数モデルは、対応する関数の各エクスターナルにどの演算が施されるかを規定する。例えば、Ｃスタンダードのセクション７．９．５．３に説明されているＣ言語用に定義された関数ｆｏｐｅｎ  （）  は、２つのパラメータを定め、そのうち第１のパラメータは入力として受け取られ、開かれるべきファイルを特定する。また、開かれたファイルに対応するファイルポインタである戻り値項目を定める。ファイルポインタ、即ち、型“ＦＩＬＥ”の項目を指定するポインタは、Ｃスタンダードのセクション７．９．１に説明されておりよく知られている。ファイルポインタは関数ｆｏｐｅｎ  （）  のエクスターナルであり、このパラメータによって特定されるファイルは、このエクスターナルに関連付けられるリソースである。関数ｆｏｐｅｎ  （）  に対する関数モデルは、初期状態が状態Ｑの新たなリソースが生成されることを定める。このリソースの初期状態は状態Ａではなく状態Ｑであるが、それは関数ｆｏｐｅｎ  （）  はファイルが正常に開かれることを保証するものではないからである。
【００５１】
Ｃスタンダードのセクション７．９．５．１に説明されているＣ言語用に定義された関数ｆｃｌｏｓｅ  （）  は、ファイルポインタであるパラメータを定める。
【００５２】
関数ｆｃｌｏｓｅ  （）  を実行することによって、そのパラメータが指定するファイル記述子（ｆｉｌｅ  ｄｅｓｃｒｉｐｔｏｒ）を有するファイルが閉じられる。関数ｆｃｌｏｓｅ  （）  に対する関数モデルは、関連するファイルが閉じられること、従って開放されることが反映されるように、そのパラメータに演算ｋが施されることを定める。同様に、ファイルに対する読み出し及び書き込み演算を定義するＣ言語の関数に対する関数モデルは、ファイルが使用されたことが反映されるように、そのファイルを表すリソースに演算ｃが施されることを規定する。
【００５３】
あるリソースに対応する項目（例えば関数ｆｏｐｅｎ  （）  の戻り値項目であるファイルポインタなど）が、決定命令（ｄｅｃｉｓｉｏｎ  ｉｎｓｔｒｕｃｔｉｏｎ）中で述語（ｐｒｅｄｉｃａｔｅ）として使用される場合、演算ｐがそのリソースに施され、リソースの状態は状態図３００に基づいて変化される。項目が関係式（例えば演算子の＞、＜、＜＝、＞＝、及び！＝の何れかを含む演算）またはブール式（例えば演算子＆＆、｜｜、及び！の何れかを含む演算）中にオペランドとして現れる場合、または項目が“ｓｗｉｔｃｈ”ステートメントに於いて制御式（ｃｏｎｔｒｏｌ  ｅｘｐｒｅｓｓｉｏｎ）として用いられる場合、項目は述語中で用いられることとなる。“ｓｗｉｔｃｈ”ステートメントはＣ言語用に定義されており、制御式の値に応じて関数の流れを制御する。“ｓｗｉｔｃｈ”ステートメントについては、Ｃスタンダードのセクション６．６．４．２に詳細に説明されている。
【００５４】
あるリソースに対応する項目が計算中で用いられる場合、演算ｃがリソースに施され、それにより状態図３００に基づいてそのリソースの状態が変わる。項目が計算中で使用されるのは、（ｉ）数学的演算（例えば＋、／、＊、または−）に対するオペランドとして現れる場合、または（ｉｉ）リソースがポインタのデリファレンス（ｄｅｒｅｆｅｒｅｎｃｅ）または配列へのアクセスとして現れる場合、または（ｉｉｉ）リソースが配列指標として現れる場合である。
【００５５】
ポインタ及び配列については良く知られており、Ｃスタンダードにも記載されているが、念のためにポインタ及び配列について以下に簡単に説明する。Ｃ言語の文脈に於いて、ポインタはその値が他の項目のメモリ中のアドレスであるような項目である。従って、ポインタは他の項目を“指定（ｐｏｉｎｔ）”する。ポインタをデリファレンスすることは、ポインタが指定する項目を検索することである。
【００５６】
開示される本発明の実施例を具現するべく用いられる以下により詳細に説明されるデータ構造は、他のデータ構造を指定するポインタを含むものとして説明される。データ構造を一意に特定するためのポインタ以外の機構も知られているが、これらの機構は本発明の原理を逸脱することなくポインタの代わりとなり得るものであることを理解されたい。
【００５７】
配列は、同様の構造の１または複数の項目の集合である。配列の項目はエレメントと呼ばれ、順番に番号付けされる。配列へのアクセスは、エレメントの番号、即ちエレメントの指標を参照することによる配列のエレメントへのアクセスである。
【００５８】
演算ｘは、ＮＵＬＬであるとされる項目に対応するリソースに施される。ＮＵＬＬは一般に無効値であり、ある項目が有効な値を有していないことを示すためにその項目に代入される。例えば、値がＮＵＬＬであるポインタは項目の指定をしない。Ｃ言語の文脈では、ＮＵＬＬは“ｆａｌｓｅ（偽）”を表すブール値でもある。ある項目がＮＵＬＬと比較されてその比較の結果がｔｒｕｅ（真）であるとされる場合、その項目はＮＵＬＬである、即ちＮＵＬＬの値を有するとされる。後により詳細に説明するように、関数を解析するには、実行時の関数の特定の挙動に関して様々な仮定を設定することが必要である。例えば、関数ｆｏｐｅｎ  （）  は、正常にファイルを開くか、またはファイルを開くのに失敗するか何れかである。戻り値項目、即ちファイルポインタがＮＵＬＬと比較されその結果がｔｒｕｅであるとされる場合、即ち関数ｆｏｐｅｎ  （）  がファイルを開くのに失敗したとされる場合、そのファイルを表すリソースに演算ｘが施される。これについては、後により詳細に説明する。
【００５９】
本発明の基本的原理を説明するための例 
リソースのモデル化の有用性について以下に例を用いて説明する。以下のソースコード抜粋（１）はプログラミングエラーを含んでおり、開示される本発明の実施例ではそのプログラミングエラーを検出する。このソースコード抜粋（１）は公知のＣ言語に適合するものであり、関数ｅｘａｍｐｌｅ １  （）  を定義している。ライン番号はＣ言語の一部ではないが、以下の説明をよりわかりやすくするために付け加えたものである。
【００６０】
2006252583.tif 000007
【００６１】
関数ｅｘａｍｐｌｅ １  （）  を解析するとき、エクスターナルを含む各項目の状態が追跡される。変数“ｓｔｒ”はローカルに定義された、即ち関数ｅｘａｍｐｌｅ １  （）  の文脈内でのみ定義されたものである。変数“ｓｔｒ”はライン１０で定義されているように、型が“ｃｈａｒ”であるデータを指定するポインタである。しかし最初、変数“ｓｔｒ”は初期化されておらず特定のデータを指定しない。従って、変数“ｓｔｒ”はリソースに関連付けられていない。
【００６２】
Ｃスタンダードのセクション７．１０．３．３に説明されているＣ言語用に定義された関数ｍａｌｌｏｃ  （）  の実行では、割り当てられるメモリ（例えばメモリ１０４（第１図））に対するリクエストを受け付け、そのメモリを割り当てるかまたはその割り当てに失敗する。関数ｍａｌｌｏｃ  （）  は、戻り値項目として、メモリの割り当てに成功した場合は割り当てられたメモリを指定するポインタを、そうでない場合はＮＵＬＬポインタをリターンする。このように、関数ｍａｌｌｏｃ  （）  は初期状態がＱである新たなリソースを生成し、その新たなリソースを関数ｍａｌｌｏｃ  （）  の戻り値項目に関連付ける。ライン２３で関数ｍａｌｌｏｃ  （）  の戻り値項目の値が代入された後において、変数“ｓｔｒ”は、メモリが割り当てられた場合は新たに割り当てられたメモリを指定し、そうでない場合はＮＵＬＬポインタである。
【００６３】
ソースコード抜粋（１）のライン２５において、変数“ｓｔｒ”は関数ｆｇｅｔｓ  （）  内でパラメータとして用いられている。この関数ｆｇｅｔｓ  （）  もＣスタンダードのセクション７．９．７．２に説明されているＣ言語用に定義された関数である。関数ｆｇｅｔｓ  （）  を実行すると、ソースコード抜粋（１）のライン２５の文脈において、第１パラメータ、即ち、変数“ｓｔｒ”がデリファレンスされる。従って、変数“ｓｔｒ”に関連付けられたリソースに対して演算ｉが施される。状態図３００（第３Ａ図）及び表Ｃ、表Ｄに示されているように、状態Ｑのリソースに演算ｉを施すとリソースは状態Ａに置かれ、割り当てられているかどうか不確実なデータがチェックされることなしに使用されたことを示すエラーメッセージが生成される。
【００６４】
ソースコード抜粋（１）のライン２９において、変数“ｓｔｒ”は、変数“ｓｔｒ”が指定するメモリをフリーにする即ち開放する関数ｆｒｅｅ  （）  にパラメータとして渡されている。従って、関数“ｓｔｒ”に関連付けられたリソースに対し演算ｋが施される。状態図３００及び表Ｃ、表Ｄに示されているように、演算ｋを状態Ａにあるリソースに施すと、リソースは状態Ｕに置かれる。割り当てられているリソースを開放することは適正であるため、エラーは通知されない。
【００６５】
以下のテキスト（２）は、ソースコード抜粋（１）の関数ｅｘａｍｐｌｅ １  （）  を解析する、開示される本発明の実施例によって生成されるエラーメッセージを示したものである。
【００６６】
2006252583.tif 000008
【００６７】
テキスト（２）において、“ｅｘａｍｐｌｅ １．ｃ”は、上記のソースコード抜粋（１）を含む、従って関数ｅｘａｍｐｌｅ １  （）  を定義しているファイルを表している。関数ｅｘａｍｐｌｅ １  （）  は、ソースコード抜粋（１）のライン２３において関数ｍａｌｌｏｃ  （）  の呼び出し（即ち実行要求）において、割り当てを要求されるメモリ量に対してメモリが足りないかもしれないということを考慮していない。関数ｅｘａｍｐｌｅ １  （）  の実行時に関数ｍａｌｌｏｃ  （）  が要求されたメモリの割り当てに失敗すると、関数ｅｘａｍｐｌｅ １  （）  の実行を含むコンピュータプロセスが突然アボートし、ユーザにはプロセスの予期されない終了に対する理由も示されないことになる。しかしながら、例えば上記のテキスト（２）を用いてそのような事態が考慮されていないことを検出し通知することによって、関数ｅｘａｍｐｌｅ １  （）  の開発者に、関数ｅｘａｍｐｌｅ １  （）  中の欠陥を修正するのに必要な情報が与えられ、そのような事態に適切に対処することが可能となる。
【００６８】
本発明の有用性は、ソースコード抜粋（１）の関数ｅｘａｍｐｌｅ １  （）  におけるファイルポインタ“ｆｐｔｒ”の状態の追跡について検討することによって更に明らかとなる。ファイルポインタ“ｆｐｔｒ”は関数ｅｘａｍｐｌｅ １  （）  のローカル定義変数である。ファイルポインタ“ｆｐｔｒ”は、型“ＦＩＬＥ”のデータを指定するポインタである。最初、ファイルポインタ“ｆｐｔｒ”は初期化されておらず、どのリソースにも関連付けられていない。
【００６９】
ライン１４において、関数ｆｏｐｅｎ  （）  の戻り値項目がファイルポインタ“ｆｐｔｒ”に代入される。上述したように、関数ｆｏｐｅｎ  （）  は、初期状態Ｑの新たなリソースを生成し、その新たなリソースに関数ｆｏｐｅｎ  （）  の戻り値項目を関連付ける。ライン１５の“ｉｆ”ステートメントは、ファイルポインタ“ｆｐｔｒ”が指定するファイルが正常に開かれたかどうかをファイルポインタ“ｆｐｔｒ”と“ＮＵＬＬ”とを比べることによって判定する。
【００７０】
ファイルポインタ“ｆｐｔｒ”がＮＵＬＬである場合、ファイルは正常に開かれておらず、関数ｅｘａｍｐｌｅ １  （）  は、ユーザにファイルを正常に開くことができなかったことを通知して終了する。逆に、ファイルポインタ“ｆｐｔｒ”がＮＵＬＬでない場合は、ファイルポインタ“ｆｐｔｒ”が指定するファイルは正常に開かれていることがわかり、関数ｅｘａｍｐｌｅ １  （）  はライン２２へと進む。ライン１５においてファイルポインタ“ｆｐｔｒ”の比較をすることによって、ファイルポインタ“ｆｐｔｒ”に関連付けられたリソースに演算ｐが施される。従って、ファイルポインタ“ｆｐｔｒ”に関連付けられたリソースの状態は状態Ｑから状態Ａへと変化する。従って、状態図３００及び表Ｃに示されているように、計算（演算ｃの適用）または述語（演算ｐの適用）のどちらでファイルポインタ“ｆｐｔｒ”を使用しても、エラーメッセージは生成されない。従って、ファイルポインタ“ｆｐｔｒ”の処理に関してエラーは検出されない。
【００７１】
上述したように、関数ｆｏｐｅｎ  （）  及びｍａｌｌｏｃ  （）  は、実行時、パラメータ及び戻り値項目のリソースに対して特定の処理を実行する。関数ｆｏｐｅｎ  （）  やｍａｌｌｏｃ  （）  のような関数は、コンピュータプロセス１１０によってアクセス可能なライブラリ関数１１２（第１図）内に含まれる。そのような関数の呼び出しは、関数２０２（第２図）に含まれる。本明細書中において、関数に対する“呼び出し（ｃａｌｌ）”とは、実行時にＣＰＵ１０２（第１図）のようなプロセッサに次のような処理をさせるステートメントである。即ち、（ｉ）関数に０または１以上の項目をパラメータとして与え、（ｉｉ）関数を実行し、（ｉｉｉ）関数の評価により生じる値を表す戻り値項目（戻り値項目が関数によって定められる場合）を生成する。第１の関数が第２の関数に対する呼び出しを含んでいる場合、第１の関数は“呼び出し関数（ｃａｌｌｉｎｇ  ｆｕｎｃｔｉｏｎ）”と呼ばれる。また、第２の関数は“被呼び出し関数（ｃａｌｌｅｄ  ｆｕｎｃｔｉｏｎ）”と呼ばれる。
【００７２】
関数２０２のステートメントによって呼び出される関数の実行によって影響される関数２０２のリソース（第２図）を適切に解析するため、そのような被呼び出し関数の挙動を記述する関数モデルがサポートされる。一実施例では、そのような関数モデルは、例えばＣスタンダードにあるこのような関数の挙動を定める公知のテキスト形式の記述から生成され、コンピュータ１００のメモリ１０４内に格納される。これらの関数モデルはその後コンピュータプログラムの解析に先立ってメモリ１０４から検索され取り出される。これについては以下により詳細に説明する。
【００７３】
以下に、上記のソースコード抜粋（１）の関数ｅｘａｍｐｌｅ １  （）  によって呼び出される関数の関数モデルの例を示す。これらの被呼び出関数は全てＣスタンダードのライブラリの“ｓｔｄｉｏ”（入力／出力）ヘッダファイルからのものである。このヘッダファイルはＣ言語で使用される広く知られたファイルであり、Ｃスタンダードのセクション７．９以下に示されている。
【００７４】
2006252583.tif 000009
【００７５】
開示される本発明の実施例に基づく関数モデルをメモリ１０４（第１図）において表す関数モデル構造体については、後に詳述する。関数モデル（３）は、関数ｍａｌｌｏｃ  （）  の実行が関数ｍａｌｌｏｃ  （）  のエクスターナルの状態に与える効果について定めている。関数モデル（３）によると、新たなリソースが生成され、状態Ｑに初期化され、関数ｍａｌｌｏｃ  （）  の戻り値項目に関連付けられる。また関数モデル（３）は、関数ｍａｌｌｏｃ  （）  の第１パラメータ、即ち、パラメータ０（ｐａｒａｍｅｔｅｒ  Ｏ）に演算Ｃが施されることも規定している。
【００７６】
2006252583.tif 000010
【００７７】
関数モデル（４）は、関数ｆｒｅｅ  （）  の実行が関数ｆｒｅｅ  （）  のエクスターナルに及ぼす効果について規定しており、演算ｋが引数リスト（ａｒｇｕｍｅｎｔ  ｌｉｓｔ）の第１パラメータ即ちパラメータ０に施されることを示している。
2006252583.tif 000011
【００７８】
関数モデル（５）は、関数ｆｇｅｐｓ  （）  を呼び出すことによって、（ｉ）演算ｉがパラメータ０、即ち第１パラメータに施され、（ｉｉ）演算ｃがパラメータ１、即ち第２パラメータに施され、（ｉｉｉ）演算ｉがパラメータ２、即ち第３パラメータに施されることを示している。
【００７９】
リソースリークの検出 
リソースをモデル化しリソースと関数のエクスターナルとの関連を追跡することによって、開示するエラー検出機構は、リソースリークを検出する有用な機構を提供する。リソースは、ある関数がそのリソースを割り当てられた状態にしたまま終了するとき、即ち、その関数のどのエクスターナルによってもそのリソースがアクセスできなくなったとき、その関数によって“リーク”される。リークされると、そのリソースはリークを発生させた関数の実行が終了した後にはそのリソースを指定するポインタが保持されないため、使用することができなくなる。リソースが再使用可能な場合、例えば、動的に割り当てられるメモリ１１４（第１図）のような場合、関数の実行の終了前にリソースをフリーにしないと、他の関数がそのリソースを再使用することができなくなる。ある部分プロセスが動的に割り当てられるメモリを繰り返しリークさせると、遂にはその部分プロセス含むコンピュータプロセスに使用可能な全メモリが消耗される結果となり得る。
リソースリークの検出の例として、ソースコード抜粋（６）の関数ｅｘａｍｐｌｅ ２  （）  について考えてみる。
【００８０】
2006252583.tif 000012
【００８１】
変数“ｓｔｒ”は関数ｅｘａｍｐｌｅ ２  （）  のローカル変数であり、従って関数ｅｘａｍｐｌｅ ２  （）  以外の関数にはアクセス可能でない。変数“ｓｔｒ”が指定するメモリは、ソースコード抜粋（６）のライン２５の“ｒｅｔｕｒｎ”命令の前にフリーにされていないため、このメモリは関数ｅｘａｍｐｌｅ ２  （）  をその一部として含むコンピュータプロセス１１０が終了するまで使用することができず、開放または再割り当てをすることもできない。従って、このリソースはコンピュータプロセス１１０から“リーク”する。
【００８２】
関数のエクスターナルは関数の実行の終了後も存在する項目であるため、エクスターナルを通じて到達可能（ｒｅａｃｈａｂｌｅ）な割り当てられたリソースはリークされない。特定のエクスターナルに関連付けられていないリソースも、ある場合には、エクスターナルを通じて到達可能である。例えば、項目の配列の特定のエレメントに関連付けられたリソースは、その項目の配列の別のエレメントであるエクスターナルを通じて到達可能である。これは、Ｃ言語によると、ある配列のエレメントのメモリ中の位置は、その配列の他のエレメントの位置から計算可能であるからである。
【００８３】
リークは、関数のトラバース（ｔｒａｖｅｒｓａｌ）の終了時にチェックされる。リークの検出については後により詳細に説明するので、ここでは簡単に要約する。エクスターナルを通じて到達可能な全てのリソースをマーク（印し付け）する。マークされず且つ割り当てられているリソースはリークされたものとして通知する。ライン２５において変数“ｓｔｒ”はリターンされないため、変数“ｓｔｒ”はエクスターナルではない。従って、変数“ｓｔｒ”によって指定されるメモリは、割り当てられており且つ関数ｅｘａｍｐｌｅ ２  （）  のトラバースの終了時にマークされていない。よって、変数“ｓｔｒ”によって示されるメモリはリークされる。
関数ｅｘａｍｐｌｅ ２  （）  の解析によって、次のエラーメッセージが生成される。
【００８４】
2006252583.tif 000013
【００８５】
従来技術のスタティックチェッカは、リソースリークを検出することができない。従来技術のランタイムチェッカ（ｒｕｎｔｉｍｅ  ｃｈｅｃｋｅｒ）は、関数にリソースリークを発生させ得る全ての起こり得るイベントを考慮しないことがしばしばあり、一般に大きなコンピュータプログラムの文脈の外で単一の関数を解析してその単一の関数内のリソースリークを検出することはできない。対照的に、開示される本発明の実施例では、大きなコンピュータプログラムの単一の関数を解析することによって、リソースリークが効果的に検出される。以下により詳細に説明するように、開示するエラー検出機構は、関数がリソースリークを発生させるような起こり得るイベントを全て考慮する。従って、本発明は、従来技術に対して大幅に向上している。
【００８６】
エクスターナルの複合状態 
以下に詳細に説明するように、関数の解析は、その関数の制御の流れを追い、その関数の個々のステートメントの実行をエミュレートし、エクスターナル及びリソースの状態を追跡することによってなされる。関数の制御の流れとは、その関数の特定の実行時に実行されるその関数のコンピュータ命令の特定の順番である。制御が第１コンピュータ命令から第２コンピュータ命令へと移るとき、第２コンピュータ命令は第１コンピュータ命令の実行に続いて実行される。関数の制御の流れは、しばしば本明細書中では、関数の制御流れ経路と呼ばれる。関数の制御の流れは、しばしば、コンピュータプロセスに於いてその関数によって定義される部分プロセスの実行中に発生する特定のイベントに依存する。
【００８７】
関数の解析においては、関数の全ての可能な制御流れ経路を考慮することが望ましい。従って、関数の制御流れ経路に影響を与えうる全てのイベントを考慮することが望ましい。従来技術のスタティックチェッカは、しばしば、制御流れ経路を全く考慮しない。ランタイムチェッカは、関数の制御流れ経路に影響を与えるイベントを操作することによって、コンピュータプロセスの実行中にそのコンピュータプロセスが各制御流れ経路をたどるようにユーザが強制し得る範囲に於いて、特定の関数の制御流れ経路を考慮するのみである。一方、開示されるエラー検出機構は、ユーザが介入することなく、自動的に関数の各制御流れ経路の解析を行う。更に、開示するエラー検出機構は、関数の解析をその関数を含むコンピュータプロセスまたはコンピュータプログラムの文脈の外で行うことができる。従って、個々の関数を、より大きな関数またはコンピュータプログラムまたはプロセス中に組み込む前にエラーに対してより完全にチェックすることができる。
【００８８】
例として、ソースコード抜粋（６）の関数ｅｘａｍｐｌｅ ２  （）  について考えてみる。関数ｅｘａｍｐｌｅ ２  （）  の正確な制御流れ経路は、関数ｅｘａｍｐｌｅ ２  （）  をコンピュータプロセス内で実行するまでは未知である。例えば、ライン１４に於いて呼び出される関数ｍａｌｌｏｃ  （）  がリクエストされた通りにメモリを割り当てるのに成功した場合、制御は、ライン１６の“ｉｆ”ステートメントからライン１９の関数ｆｏｐｅｎ  （）  の呼び出しへと流れる。言い換えると、ライン１４で呼び出されたとき関数ｍａｌｌｏｃ  （）  がリクエストされた通りに正常にメモリを割り当てる場合、ライン１９の関数ｆｏｐｅｎ  （）  の呼び出しは、ライン１６の“ｉｆ”ステートメントの実行の後に続く。逆に、メモリの割り当てが失敗した場合、制御はライン１６の“ｉｆ”ステートメントからライン１７の“ｒｅｔｕｒｎ”ステートメントへと流れる。ライン１４に於いて呼び出されたとき関数ｍａｌｌｏｃ  （）  によるメモリの割り当てが正常になされるかどうかは、通常、コンピュータプロセスに於いて関数ｅｘａｍｐｌｅ ２  （）  が実行されるまでわからない。
【００８９】
関数ｅｘａｍｐｌｅ ２  （）  の解析に於いて、関数ｅｘａｍｐｌｅ２  （）  の全ての制御流れ経路が考慮されることが望ましい。様々に仮定を変えて関数を何度もトラバースすることによって、複数の制御流れ経路が考慮される。例えば、関数ｅｘａｍｐｌｅ ２  （）  は、一度はライン１４で呼び出される関数ｍａｌｌｏｃ  （）  がリクエストされたメモリを正常に割り当てるという仮定の下で、一度は関数ｍａｌｌｏｃ  （）  がリクエストされたメモリの割り当てに失敗するという仮定のもとでトラバースされる。
【００９０】
後に詳細に説明する本発明の一実施例では、一つの関数に対し繰り返しトラバースがなされ、各トラバースに於いて、ランダムに仮定が設定される。関数ｅｘａｍｐｌｅ ２  （）  の各トラバースは、関数ｅｘａｍｐｌｅ ２  （）  のエクスターナルの状態を追跡する。各エクスターナルは、関数ｅｘａｍｐｌｅ ２  （）  の複数回のトラバースの結果得られる各エクスターナルの幾つかの状態を反映する複合状態（ｃｏｍｐｏｓｉｔｅ  ｓｔａｔｅ）を有する。
【００９１】
エクスターナルは、複合ＲＳ、ＣＰ及びＤＫ状態を有する。これらの複合状態は、２つの目的に用いられる。即ち、（ｉ）関数の様々な制御流れ経路を考慮したとき不整合を生じるエクスターナルの使用を検出するため、（ｉｉ）関数の実行がその関数のエクスターナルに与える影響を記述する関数モデルを構築するため、に用いられる。構築された関数モデルは、その後、モデル化された関数を呼び出す他の関数を解析するのに用いることができる。
【００９２】
ある特定の関数の文脈内で、各エクスターナルはＣＰ状態、ＤＫ状態、及びＲＳ状態を有する。エスクターナルのＣＰ状態は、使用される前にエクスターナルがチェックされるかどうかを判定するのに用いられる。“ＣＰ”という用語は、主として関心のある演算、即ち、演算ｐ（エクスターナルのチェックを表す）の前の演算ｃ（エスクターナルの使用を表す）、からきている。エクスターナルのＤＫ状態は、関数によってエスクターナルの割り当て及び／または開放がなされるかどうかを判定するのに用いられる。“ＤＫ”という用語は、ＤＫ状態の目的、即ち、リソースがキル（“Ｋ”）される、即ち開放される前に定義（“Ｄ”）されるかどうかを判定するという目的から使用されている。エスクターナルのＲＳ状態は、そのエクスターナルにリソースが関連付けられている場合に、関連付けられているリソースの状態である。“ＲＳ”という用語は、リソース（“Ｒ”）状態（“Ｓ”）からきている。
【００９３】
ある関数の各エクスターナルは、その関数の複数回のトラバースの結果生じる複数のＣＰ、ＤＫ、及びＲＳ状態をそれぞれ反映する複合ＣＰ状態、複合ＤＫ状態、及び複合ＲＳ状態を有する。繰り返しなされる関数の各トラバースの後において、エクスターナルの新たな複合ＲＳ状態が求められるが、以下により詳細に述べるように、エクスターナルの新たな複合ＲＳ状態は、そのエクスターナルの前の複合ＲＳ状態と、その関数の最も新しいトラバースの結果生じるそのエクスターナルに関連付けられたリソースのＲＳ状態とから求められる。同様に、以下により詳細に述べるように、新たな複合ＣＰ及びＤＫ状態は、前の複合ＣＰ及びＤＫ状態と、関数の最も新しいトラバースの結果生じるＣＰ及びＤＫ状態とからそれぞれ求められる。
【００９４】
状態図３５０（第３Ｂ図）は、複合ＲＳ状態に対する状態及び状態遷移を表している。状態図３５０に於いて矢印は、関数のトラバースの結果生じるＲＳ状態に基づく、前の複合ＲＳ状態からの複合ＲＳ状態遷移を表す。状態図３５０は表Ｅのようにまとめられる。
【００９５】
【表５】
2006252583.tif 000014
【００９６】
状態図４００（第４Ａ図）は、エスクターナルのＣＰ状態に対する状態及び状態遷移を表す。状態図４００に於いて矢印は、演算を施した結果生じるＣＰ状態遷移を表す。エクスターナルは次のＣＰまたは複合ＣＰ状態を有し得る。
【００９７】
【表６】
2006252583.tif 000015
【００９８】
エスクターナルに施すことのできる演算は、表Ｂを参照して上記に示した通りである。状態図４００は、以下の表Ｈにまとめられる。
【００９９】
【表７】
2006252583.tif 000016
【０１００】
状態図４５０（第４Ｂ図）は、エクスターナルの複合ＣＰ状態に対する状態及び状態遷移を表している。状態図４５０で使用されている矢印は、関数のトラバースの結果生じるＣＰ状態に基づく、前の複合ＣＰ状態からの複合ＣＰ状態の遷移を表す。状態図４５０は以下の表Ｉにまとめられる。
【０１０１】
【表８】
2006252583.tif 000017
【０１０２】
状態図５００（第５Ａ図）は、エスクターナルのＤＫ状態に対する状態及び状態遷移を表している。状態図５００に於いて矢印は、演算を施した結果生じるＤＫ状態遷移を表すのに使用されている。エスクターナルは、エスクターナルに関連付けられるリソースに関数の実行が与える効果を反映する、以下のＤＫまたは合成ＤＫ状態を有し得る。
【０１０３】
【表９】
2006252583.tif 000018
【０１０４】
エクスターナルに施すことのできる演算は、表Ｂを参照して上述した通りである。状態図５００は以下の表Ｋにまとめられる。
【０１０５】
【表１０】
2006252583.tif 000019
【０１０６】
状態図５５０（第５Ｂ図）はエクスターナルの複合ＤＫ状態に対する状態及び状態遷移を表す。状態図５５０に於いて矢印は、関数のトラバースから生じるＤＫ状態に基づく、前の複合ＤＫ状態からの複合ＤＫ状態遷移を表すのに使用されている。状態図５５０は以下の表Ｌにまとめられる。
【０１０７】
【表１１】
2006252583.tif 000020
【０１０８】
上記のソースコード抜粋（６）の関数ｅｘａｍｐｌｅ ２  （）  は、エクスターナルの複合状態の有用性を示す例となる。
【０１０９】
上述したように、関数ｅｘａｍｐｌｅ ２  （）  の制御の流れは、エミュレーションによる関数の実行時のイベントに関連して設定される仮定に依存して複数の経路の内の何れかを通る。例えば、変数“ｓｔｒ”がＮＵＬＬでない場合は、ライン１６の“ｉｆ”ステートメントの後に、ライン１７の“ｒｅｔｕｒｎ”ステートメントが続き、そうでない場合はライン１９の式が続く。関数ｅｘａｍｐｌｅ ２  （）  の戻り値項目は、関数ｅｘａｍｐｌｅ ２  （）  のエクスターナルである。関数ｅｘａｍｐｌｅ ２  （）  の戻り値項目への代入は、関数ｅｘａｍｐｌｅ ２  （）  の特定のトラバースに於いて設定される特定の仮定にのみ基づいて、ソースコード抜粋（６）のライン１７、ライン２５またはライン２９に於いてなされる。
【０１１０】
ライン１７またはライン２５では、戻り値項目にリソースは関連付けられない。従って、ソースコード抜粋（６）のライン１７またはライン２５の何れかを通って制御が流れるような関数ｅｘａｍｐｌｅ ２  （）  のトラバースの後において、戻り値項目を表すエスクターナルの複合ＲＳ状態は状態Ｕとなる。続いて、制御がライン２９を通るように関数ｅｘａｍｐｌｅ−２  （）  をトラバースすると、戻り値項目を表すエクスターナルは、関数ｅｘａｍｐｌｅ ２  （）  内で生成されたリソースに関連づけられ、適確に割り当てられる。即ち、状態Ａとなる。ソースコード抜粋（６）のライン１６乃至１７により、関数ｍａｌｌｏｃ  （）  の実行によってメモリが正常に割り当てられないというイベントに対して取られるべき動作が適切に記述されているため、リソースの適確な割り当てがなされるのである。
【０１１１】
状態図３５０（第３Ｂ図）に示されているように、前の複合ＲＳ状態が状態Ｕで次のＲＳ状態が状態Ａであるようなエクスターナルは、状態Ｑの新たな複合ＲＳ状態を有する。これは、関数ｅｘａｍｐｌｅ ２の実行によって、その戻り値項目が指定するメモリの割り当てがなされ得るが、必ずしも割り当てがなされるというわけではないということを反映している。従って、関数ｅｘａｍｐｌｅ ２の挙動を記述する関数モデルを形成するとき、関数ｅｘａｍｐｌｅ ２の戻り値項目は、初期状態が状態Ｑである新たに生成されるリソースに関連付けられるものとして記述される。
【０１１２】
また、複合状態を用いて、関数によるエクスターナルのつじつまのあわない使用を検出することができる。例えば、ある関数が、エクスターナルが割り当てられた状態、即ち状態ＡのＲＳ状態で終了し、その関数のその後のトラバースに於いて、その関数が同じエクスターナルを開放した状態で、即ち状態ＫのＲＳ状態で終了する場合、そのエスクターナルの複合ＲＳ状態は状態Ｅとなる。これはエラーとみなすことができる。なぜなら、一般に、呼び出し関数がある場合の実行においてはあるエクスターナルに関連付けられたリソースの割り当てをすることを求め、別の場合の実行においては同じエクスターナルに関連付けられたリソースを開放することを求めるということは考えられないからである。
【０１１３】
コンピュータプログラムの解析 
コンピュータプログラム６１０（第６図）の解析は、本発明に基づいて、本明細書中に説明するように、コンピュータプログラム６１０によって定められたリソースの使用を解析するリソースチェッカ（ｒｅｓｏｕｒｃｅｃｈｅｃｋｅｒ）６０２によってなされる。開示する実施例では、リソースチェッカ６０２は、バス１０８を介してＣＰＵ１０２に接続されたメモリ１０４から読み出されてＣＰＵ１０２において実行されるコンピュータプロセスである。
【０１１４】
コンピュータプログラム６１０の本発明に基づく解析を、論理流れ図９００（第９図）に示す。プロセスはステップ９０２において開始される。例えばキーボード１２４（第１図）やマウス１２２を用いてユーザが入力するコマンドによって、コンピュータプログラム６１０が解析される環境特性が特定され、コンピュータプログラム６１０（第６図）の解析が開始される。ユーザによって変更可能な環境特性には、（ｉ）検出するべきエラーのタイプ、（ｉｉ）通知するべきエラーの最大数、（ｉｉｉ）解析するべき関数の最大数、（ｉｖ）各関数のトラバースの繰り返しの最大回数、及び（ｖ）関数の全ての可能な制御流れ経路をトラバースするための特定の方法などがある。
【０１１５】
プロセスは、ステップ９０２（第９図）からステップ９０４に進み、そこでリソースチェッカ６０２（第６図）は、コンピュータプログラムによって使用される様々な関数の実行がリソースに与える影響を記述する関数モデルを初期化する。リソースチェッカ６０２はモデルパーザ７０２（第７図）を含んでおり、モデルパーザ７０２は、モデル記述ファイル６０４（第６図）からモデルを読み出し、読み出したモデルから後述する関数モデル構造体を構築する。リソースチェッカ６０２において関数モデル構造体を生成することによって、関数モデルが初期化される。
【０１１６】
ステップ９０４（第９図）については、後に論理流れ図９０４（第１０図）を参照してより詳細に説明する。
【０１１７】
プロセスはステップ９０４（第９図）からステップ９０６に進み、そこでリソースチェッカ６０２の一部であるプログラムパーザ７０４（第７図）は、コンピュータプログラム６１０（第６図）を読み出してきて、従来の技術を用いて、コンピュータプログラム６１０が従う言語に基づきパージング（ｐａｒｓｉｎｇ）を行う。プログラムパーザ７０４（第７図）はコンピュータプログラム６１０（第６図）をパージングして、より小さなプログラムコンポーネント、例えば関数、に分解する。ステップ９０６（第９図）では、１つの関数がコンピュータプログラム６１０（第６図）からパージングにより抽出され、抽出されたその関数を表す関数構造体が、後に詳述する動的検査エンジン（ｄｙｎａｍｉｃ  ｉｎｓｐｅｃｔｉｏｎ  ｅｎｇｉｎｅ）７０６に送られる。別の実施例では、後述するプリプロセッサがコンピュータプログラム６１０をパージングし、パージングにより抽出されたコンピュータプログラム６１０内の複数の関数を表現する複数の関数構造体が格納される。この別の実施例では、プログラムパーザ７０４は関数構造体を一つ取り出しては、取り出した関数構造体を動的検査エンジン７０６に送る働きをする。プロセスはステップ９０６（第９図）からステップ９０８に進む。
【０１１８】
ステップ９０８において、リソースチェッカ６０２の一部である動的検査エンジン７０６（第７図）によって、“サブジェクト関数（ｓｕｂｊｅｃｔｆｕｎｃｔｉｏｎ）”、即ちステップ９０６（第９図）においてプログラムパーザ７０４によって動的検査エンジン７０６に送られた関数構造体によって表される関数、の解析がなされる。言い換えると、サブジェクト関数の実行の結果コンピュータプログラム６１０によって使用されるリソースに生じる効果が求められ、サブジェクト関数の実行によって影響される各リソースの状態遷移が解析される。これについては後により詳細に説明する。ステップ９０４において初期化された関数モデルが、サブジェクト関数のエクスターナル、リソースの状態及び状態遷移を解析するのに用いられる。検出された状態違反はプログミングエラーとして通知される。
【０１１９】
サブジェクト関数の挙動が、そのエクスターナル及びリソースに関して定められると、モデルパーザ７０２はモデル記述ファイル６０４内にサブジェクト関数の挙動を記述する関数モデルを形成し格納する。ステップ９０８（第９図）については、論理流れ図９０８（第２４図）を参照して後により詳細に説明する。
【０１２０】
プロセスは、ステップ９０８（第９図）からテストステップ９１０に進み、そこでプログラムパーザ７０４（第７図）は更にコンピュータプログラム６１０（第６図）をパージングして、コンピュータプログラム６１０に、ステップ９０８（第９図）に基づいて動的検査エンジン７０６（第７図）によって解析されるべき関数がまだ含まれているかどうか判定する。上述した別の実施例では、プログラムパーザ７０４（第６図）は、ステップ９０８（第９図）に基づいて動的検査エンジン７０６（第７図）によって解析されなければならないコンピュータプログラム６１０の関数を表す関数構造体がまだあるかどうか判定する。動的検査エンジン７０６（第７図）がまだ処理していないコンピュータプログラム６１０の関数を表す関数構造体がある場合、プロセスはステップ９０６（第９図）に進み、そこでプログラムパーザ７０４（第６図）は、その関数構造体を上述したように動的検査エンジン７０６（第７図）に送る。動的検査エンジン７０６（第７図）がコンピュータプログラム６１０の関数を表す関数構造体を全て処理し終わっている場合は、プロセスは論理流れ図９００に従って終了する（第９図）。
【０１２１】
モデルの初期化 
論理流れ図９００のステップ９０４（第９図）を参照して上述したように、関数の挙動を記述する関数モデルは初期化される。ステップ９０４を、論理流れ図９０４（第１０図）に詳細に示す。プロセスはステップ１００２において開始され、上述したような関数モデルを含むモデル記述ファイル６０４（第６図）が開かれる。
【０１２２】
一実施例では、関数モデルはテキスト形式で格納され、読み込まれ、そしてメモリ１０４（第１図）内の後に詳述するデータ構造内に格納される。関数モデルは、関数を識別する情報と、関数のエクスターナルに対するエクスターナルモデルのシングルリンクトリスト（ｓｉｎｇｌｙ−ｌｉｎｋｅｄｌｉｓｔ）とを含む。関数を識別する情報には（ｉ）関数名、（ｉｉ）関数が定義されているソースコードファイルの名前、（ｉｉｉ）関数の定義が始まるソースコードファイル中のテキストラインの番号、及び（ｉｖ）関数の簡単な説明が含まれる。ソースコードファイルは、メモリ１０４（第１図）（通常、磁気ディスクのような二次記憶装置）に格納された、コンピュータプログラム６１０のようなコンピュータプログラムを格納するファイルである。シングルリンクトリストの形態で格納されたエクスターナルモデルは、関数の実行が関数のエクスターナルに与える影響を、これらのエクスターナルに施される演算と、それらのエクスターナルに関連して生成されるリソースとに関して定めるものである。
【０１２３】
エクスターナルモデルは、エクスターナルの型を特定する情報、エクスターナルを識別する情報、及び関数の実行がエクスターナルに与える影響を定める情報を含む。エクスターナルを識別する情報は、エクスターナルがパラメータの場合はパラメータ番号（ｐａｒａｍｅｔｅｒ  ｎｕｍｂｅｒ）、エクスターナルがグローバルまたはスタティック変数の場合は変数名、エクスターナルが戻り値項目である場合はＮＵＬＬである。関数の実行がエクスターナルに与える影響を定める情報には、（ｉ）エクスターナルに施される演算のリスト、（ｉｉ）エクスターナルに関連して新たなリソースが生成されるかどうかを示すフラグ、及び（ｉｉｉ）新たなリソースが生成される場合、その新たなリソースの初期状態が含まれる。
【０１２４】
モデル記述ファイル６０４（第６図）に格納されているモデルのテキスト書式は、以下の“Ｂａｃｋｕｓ−Ｎａｕｒ  Ｆｏｒｍ（ＢＮＦ）”定義（８）に従う。“Ｂａｃｋｕｓ−Ｎａｕｒ  Ｆｏｒｍ”は形式的言語を記述するためのよく知られた書式である。
【０１２５】
2006252583.tif 000021
【０１２６】
関数モデルは、テキスト書式においては、ＢＮＦ定義（８）のノンターミナル＜ｆｕｎｃｔｉｏｎ−ｓｐｅｃ＞によって表される。ＢＮＦにおいて、ターミナル（ｔｅｒｍｉｎａｌ）とは、ある特定のＢＮＦ定義においてそれ以上拡張されない項目であり、一方ノンターミナル（ｎｏｎ−ｔｅｒｍｉｎａｌ）とは更に拡張される項目である。ターミナル＜ｆｕｎｃｔｉｏｎ−ｎａｍｅ＞は、関数に割り当てられる識別予、即ち関数モデルによって表された関数を他の関数が呼び出すとき使用する識別子である。ターミナル＜ｆｕｎｃｔｉｏｎ−ｎａｍｅ＞は、関数の定義に使われるコンピュータ言語において有効な関数識別子であればどのようなものでもよい。ターミナル＜ｄｅｆｉｎｉｎｇ−ｆｉｌｅ＞は、関数の定義がなされるソースコードファイルを英数字で識別するものである。このような英数字による識別として、例えばソースコードファイルのパスを記述してもよい。ターミナル＜ｄｅｆｉｎｉｎｇ−ｌｉｎｅ＞は、負でない数字、即ち０乃至９の数字を用いたテキスト表現によって、ターミナル＜ｄｅｆｉｎｉｎｇ−ｆｉｌｅ＞によって識別されるソースコードファイルのどのテキストラインにおいてモデル化される関数の定義が始まるのかを特定するものである。
【０１２７】
ＢＮＦでは、オプション項目は、角型括弧（“［］”）で囲って表される。従って、ターミナル＜ｆｕｎｃｔｉｏｎ−ｐｒｅｆｉｘ＞、ターミナル＜ｄｅｆｉｎｉｎｇ−ｆｉｌｅ＞、＜ｄｅｆｉｎｉｎｇ−ｌｉｎｅ＞、及び＜ｄｅｓｃｒｉｐｔｉｏｎ＞は、オプションである。また、連続したスラッシュ記号（“／／”）はコメント文の開始を表すものであり、これらのスラッシュ、及びこれらのスラッシュの後にそのテキストラインの最後まで続くテキスト文は、ＢＮＦ定義の一部とはみなされないことに注意されたい。
【０１２８】
ＢＮＦ定義（８）のターミナル＜ｄｅｓｃｒｉｐｔｉｏｎ＞は、１または複数のキャラクタ（即ち、文字、数字、及び／またはシンボル）の並びである。ターミナル＜ｄｅｓｃｒｉｐｔｉｏｎ＞はリソースチェッカ６０２（第６図）によっては使用されないが、テキスト書式で表されたモデルを読むユーザの便宜及び理解のために提供されるものである。ＢＮＦ定義（８）のターミナル＜ｐａｒａｍ−ｎｕｍｂｅｒ＞は、０乃至９の数字を用いた負でない整数のテキスト表現であり、パラメータリスト中の特定のパラメータを指定するものである。パラメータゼロが、関数の呼び出しにおけるパラメータリストの中の最初の、即ち最も左側のパラメータである。後続のパラメータには順番に番号が付される。ＢＮＦ定義（８）のターミナル＜ｖａｒ−ｎａｍｅ＞は、変数の識別子である。
【０１２９】
モデル記述ファイル６０４（第６図）から抽出される関数モデルは、それぞれ、各関数の実行がその関数のエクスターナルに及ぼす影響を記述する。プロセスはステップ１００２（第１０図）からループステップ１００４に進み、モデル記述ファイル６０４（第６図）に格納されている各関数モデルは、ループステップ１００４（第１０図）とＮＥＸＴステップ１００４とによって定められるループに従って取り出され処理される。ループの各繰り返しにおいて、処理されている関数モデルは、現関数モデル（ｃｕｒｒｅｎｔ  ｆｕｎｃｔｉｏｎ  ｍｏｄｅｌ）と呼ばれる。ループステップ１００４とＮＥＸＴステップ１０１４とによって定められるループに従って、モデル記述ファイル中に格納された全ての関数モデルの処理が完了すると、プロセスはループステップ１００４からステップ１００６に進み、モデル記述ファイル６０４（第６図）は閉じられ、論理流れ図９０４（第１０図）に基づくプロセスは終了する。
【０１３０】
モデル記述ファイルから取り出される各関数モデルに対し、プロセスはループステップ１００４からステップ１００８に進み、そこで上述したＢＮＦ定義（８）のノンターミナル＜ｆｕｎｃｔｉｏｎ−ｐｒｅｆｉｘ＞に対応する現関数モデルの一部が、現関数モデルから分離される。プロセスはステップ１０１０に進み、そこで関数モデル構造体が初期化されて、ステップ１００８において現関数モデルから分離された情報が関数モデル構造体に格納される。
【０１３１】
関数モデル構造体１１００（第１１図）は、フィールド“ｎａｍｅ”１１０２、フィールド“ｆｉｌｅ”１１１０、フィールド“ｌｉｎｅ”１１１２、及びフィールド“ｄｅｓｃｒｉｐｔｉｏｎ”１１０８を含んでいる。ＢＮＦ定義（８）のターミナル＜ｆｕｎｃｔｉｏｎ−ｎａｍｅ＞、＜ｄｅｆｉｎｉｎｇ−ｆｉｌｅ＞、＜ｄｅｆｉｎｉｎｇ−ｌｉｎｅ＞、及び＜ｄｅｓｃｒｉｐｔｉｏｎ＞（これらは全てノンターミナル＜ｆｕｎｃｔｉｏｎ−ｐｒｅｆｉｘ＞の部分である）に対応する関数モデルの部分が関数モデルから抽出され、関数モデル構造体１１００のフィールド“ｎａｍｅ”１１０２、フィールド“ｆｉｌｅ”１１１０、フィールド“ｌｉｎｅ”１１１２、及びフィールド“ｄｅｓｃｒｉｐｔｉｏｎ”１１０８にそれぞれ格納される。プロセスはステップ１０１０（第１０図）からループステップ１０１２に進む。
【０１３２】
ループステップ１０１２とＮＥＸＴステップ１０２８とによってループが定められており、その各繰返しにおいて、上述したＢＮＦ定義（８）のノンターミナル＜ｅｘｔｅｒｎ−ｌｉｓｔ＞に対応する関数モデルの部分に示されたエクスターナルの処理がなされる。ループステップ１０１２とＮＥＸＴステップ１０２８とによって定められたループの各繰返しにおいて処理されているエクスターナルは、サブジェクトエクスターナルと呼ばれる。現関数モデル中に定められた全エクスターナルの処理がループステップ１０１２とＮＥＸＴステップ１０２８とによって定められたループに従って終了すると、プロセスはループステップ１０１２からＮＥＸＴステップ１０１４へ進む。プロセスはＮＥＸＴステップ１０１４からループステップ１００４へと進み、モデル記述ファイル６０４（第６図）から取り出された別の関数モデルが更に処理されるか、あるいは全ての関数モデルが処理されている場合は、上述したように、プロセスはステップ１００６（第１０図）へと進む。
【０１３３】
ＢＮＦ定義（８）のノンターミナル＜ｅｘｔｅｒｎ−Ｉｉｓｔ＞に対応する現関数モデルの部分に示された各エクスターナルに対し、プロセスはループステップ１０１２からステップ１０１６へと進む。ステップ１０１６では、例えばエクスターナルモデル構造体１２００（第１２図）のような、新たなエクスターナルモデル構造体が生成される。
【０１３４】
エクスターナルモデル構造体１２００は、フィールド“ｅｑｕｉｖａｌｅｎｔ”１２０２、フィールド“ｔｙｐｅ”１２０４、フィールド“ｐａｒａｍｅｔｅｒ ｎｕｍｂｅｒ”１２０６、フィールド“ｎａｍｅ”１２０８、フィールド“ｎｅｘｔ”１２１０、フィールド“ｎｕｍｂｅｒ ｏｆ ｏｐｅｒａｔｉｏｎｓ”１２１２、フィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４、フィールド“ｎｅｗ ｒｅｓｏｕｒｃｅ”１２１８、フィールド“ｉｎｉｔｉａｌ ｓｔａｔｅ”１２２０、及びフィールド“ｄｅｓｃｒｉｐｔｉｏｎ”１２２２を含んでいる。ステップ１０１６（第１０図）では、ＢＮＦ定義（８）のノンターミナル＜ｅｘｔｅｒｎａｌ＞の定義内のターミナル＜ｐａｒａｍ−ｎｕｍｂｅｒ＞に対応するサブジェクトエクスターナルモデルの部分が、サブジェクトエクスターナルモデルから取り出され、エクスターナルモデル構造体１２００のフィールド“ｐａｒａｍｅｔｅｒ ｎｕｍｂｅｒ”１２０６（第１２図）に格納される。
【０１３５】
一実施例では、フィールド“ｅｑｕｉｖａｌｅｎｔ”１２０２が用いられて、第２のエクスターナルモデル構造体が特定される。そうすることによって、エクスターナルモデル構造体１２００が、第２のエクスターナルモデル構造体に関係付けられる。例えば、関数の戻り値項目が第１パラメータである場合、そのようにすることが適切であろう。本明細書中に開示する実施例では、フィールド“ｅｑｕｉｖａｌｅｎｔ”１２０２は使用されず、従ってこのフィールドはＮＵＬＬ値に初期化される。ステップ１０１６（第１０図）から、プロセスはステップ１０１８へと進む。
【０１３６】
ステップ１０１８では、サブジェクトエクスターナルモデルによって表されたエクスターナルの型を定める、ＢＮＦ定義（８）のノンターミナル＜ｅｘｔｅｒｎ−ｔｙｐｅ＞に対応するサブジェクトエクスターナルモデルの部分が、サブジェクトエクスターナルモデルから抽出される。上記のＢＮＦ定義（８）に示されているように、エクスターナルモデルによって表されるエクスターナルは、戻り値項目、パラメータ、あるいはグローバル定義／スタティック変数であり得る。
【０１３７】
サブジェクトエクスターナルモデルによって表されたエクスターナルの型を示すデータは、エクスターナルモデル構造体１２００のフィールド“ｔｙｐｅ”１２０４（第１２図）に格納される。プロセスはステップ１０１８（第１０図）からループステップ１０２０へと進む。
【０１３８】
上記のＢＮＦ定義（８）に示されているように、関数の実行は、その関数の各エクスターナルに１または複数の影響または“結果（ｒｅｓｕｌｔ）”を与え得る。各結果はＢＮＦ定義（８）においてノンターミナル＜ｒｅｓｕｌｔ＞として表される。１または複数の結果がノンターミナル＜ｒｅｓｕｌｔ−ｌｉｓｔ＞に含まれる。ループステップ１０２０とＮＥＸＴステップ１０２４とによって定められるループにおいて、サブジェクトエクスターナルモデルのノンターミナル＜ｒｅｓｕｌｔ−ｌｉｓｔ＞のリスト内の各結果の処理がなされる。ループステップ１０２０とＮＥＸＴステップ１０２４とによって定められるループの繰返しにおいて、処理されている結果を、処理対象結果（ｓｕｂｊｅｃｔ  ｒｅｓｕｌｔ）と呼ぶ。以下に述べるように、サブジェクトエクスターナルモデルの全ての結果をループステップ１０２０とＮＥＸＴステップ１０２４とによって定められるループに基づいて処理すると、プロセスはループステップ１０２０からステップ１０２６へ進む。
【０１３９】
サブジェクトエクスターナルモデルに対する各結果に対し、プロセスはループステップ１０２０からステップ１０２２に進む。ステップ１０２２において、処理対象結果がサブジェクトエクスターナルモデルから抽出される。この結果は、エクスターナルモデル構造体１２００（第１２図）のようなエクスターナルモデル構造体に格納される。例えば、上記で定義した関数モデル（３）は、第１エクスターナル、即ち戻り値項目に対し１つの結果を、第２エクスターナル、即ちパラメータ０に対し１つの結果を定めている。戻り値項目の結果は‘（ｎｅｗ  Ｑ“ｍｅｍｏｒｙ”）’と定められており、戻り値項目に対し新たなリソースが生成されること、そのリソースの初期状態は状態Ｑであることが示され、更に、そのリソースの簡単な説明として“ｍｅｍｏｒｙ（メモリ）”が与えられている。  
【０１４０】
従って、この戻り値項目に対するエクスターナルモデルをエクスターナルモデル構造体１２００が表現する場合、（ｉ）フィールド“ｎｅｗ ｒｅｓｏｕｒｃｅ”１２１８が“ｔｒｕｅ”のブール値に設定され、新たなリソースが生成されることが示され、（ｉｉ）新たなリソースの初期状態が状態Ｑであることを示すようにフィールド“ｉｎｉｔｉａｌ ｓｔａｔｅ”１２２０がセットされ、（ｉｉｉ）テキスト“ｍｅｍｏｒｙ“がフィールド“ｄｅｓｐｒｉｐｔｉｏｎ”１２２２に格納される。
【０１４１】
第２の例として、上記の関数モデル（３）は、第２エクスターナル、即ちパラメータ０に対して結果“（ｏｐ  ｃ）”を定めている。結果“（ｏｐ  ｃ）”は、エクスターナルに演算Ｃが施されることを表す。従って、エクスターナルモデル構造体１２００がパラメータ０に対するエクスターナルモデルを表す場合、初期値として０を有するフィールド“ｎｕｍｂｅｒ ｏｆ ｏｐｅｒａｔｉｏｎｓ”１２１２がインクリメント（１増加）され、演算識別子“ｃ”が、フィールド“ｎｕｍｂｅｒ ｏｆ ｏｐｅｒａｔｉｏｎｓ”１２１２によって示される位置に対応するフィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４に格納される。この例では、フィールド“ｎｕｍｂｅｒ ｏｆ ｏｐｅｒａｔｉｏｎｓ”１２１２は値１を格納し、フィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４内の最初の演算識別子は演算ｃの識別子となる。もし、第２の演算が第２のエクスターナルに施されるとすると、フィールド“ｎｕｍｂｅｒ ｏｆ ｏｐｅｒａｔｉｏｎｓ”１２１２はもう一度インクリメントされ値２となり、フィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４内の第２の演算識別子が第２の演算の識別子となる。
【０１４２】
プロセスはステップ１０２２（第１０図）からＮＥＸＴステップ１０２４を介して上述したループステップ１０２０へ戻る。上述したようにプロセスは、サブジェクトエクスターナルモデルに対する全ての結果の処理が終了すると、ループステップ１０２０からステップ１０２６に進む。
【０１４３】
ステップ１０２６では、サブジェクトエクスターナルモデルを表すエクスターナルモデル構造体が、現関数モデル構造体内のエクスターナルのシングルリンクトリストに加えられる。上記の関数モデル（３）の文脈において説明する。まず、関数モデル構造体１１００Ａのフィールド“ｆｉｒｓｔ ｅｘｔｅｒｎａｌ”１００４Ａ及び“ｌａｓｔ ｅｘｔｅｒｎａｌ”１１０６Ａにエクスターナルモデル構造体１２００Ａを指定するポインタを格納することによって、エクスターナルモデル構造体１２００Ａ（第１３図）が関数モデル構造体１１００Ａに付け加えられる。続いて、エクスターナルモデル構造体１２００Ａのフィールド“ｎｅｘｔ”１２１０Ａ及び関数モデル構造体１１００Ａのフィールド“ｌａｓｔ ｅｘｔｅｒｎａｌ”１１０６Ａに、第１３図に示すようにエクスターナルモデル構造体１２００Ｂを指すポインタを格納する（フィールド“ｌａｓｔ ｅｘｔｅｒｎａｌ”１１０６Ａに前に格納されたポインタは取って代わられる）ことによって、第２エクスターナルモデル構造体１２００Ｂが関数モデル構造体１１００Ａに加えられる。
【０１４４】
プロセスはステップ１０２６（第１０図）からＮＥＸＴステップ１０２８を介してループステップ１０１２へと進む。上述したように、全エクスターナルモデルが処理されていると、プロセスはループステップ１０１２からＮＥＸＴステップ１０１４を介してループステップ１００４へ進む。上述したように、全関数モデルの処理が終了していると、プロセスはループステップ１００４からステップ１００６へ進み、上述したようにテキストフォーマットで記載された関数モデルを含むファイルが閉じられる。論理流れ図９０４に基づくプロセスは、ステップ１００６の後終了する。
【０１４５】
関数の内部表現 
プログラムパーザ７０４（第７図）によってコンピュータプログラム６１０（第６図）のパージングがなされると、コンピュータプログラム６１０はメモリ１０４において一連の関数構造体によって表される。上述した別の実施例では、プログラムパーザ７０４は、コンピュータプログラム６１０から、例えばＣ言語のような特定のコンピュータ言語に従うソースコンピュータプログラムを予めパージングすることによって形成された関数構造体を取り出す働きをする。ソースコンピュータプログラムはソースコードプリプロセッサによってパージングされるが、このソースコードプリプロセッサは、ソースコンピュータプログラムが従うコンピュータ言語に基づいてソースコンピュータプログラムのパージングを行い、コンピュータプログラム６１０中にソースコンピュータプログラム内に定義された関数を表す関数構造体を形成し格納するものである。このソースコードプリプロセッサ（図示せず）はリソースチェッカ６０２とは別個のコンピュータプロセスである。
【０１４６】
この別の実施例では、ソースコードプリプロセッサはマサチューセッツ州、ケンブリッジ（Ｃａｍｂｒｉｄｇｅ，Ｍａｓｓａｃｈｕｓｅｔｔｓ）の“Ｆｒｅｅ  Ｓｏｆｔｗａｒｅ  Ｆｏｕｎｄａｔｉｏｎ，Ｉｎｃ”から入手可能な“ＧＮＵ  Ｃ  Ｃｏｍｐｉｌｅｒ”に基づくものである。本明細書の一部であり、全体が本出願に引証として含まれる付録Ｂとして示されているコンピュータ命令のリストは、抽出されたコンピュータプログラムの関数を、ソースコードプロセッサから、抽出された関数を表すための後に詳述するデータ構造へと移すためのデータ構造及び関数を定義したものである。一実施例では、公知の上記した“ＧＮＵ  Ｃ  Ｃｏｍｐｉｌｅｒ”のような従来のコンパイラが用いられてコンピュータプログラムのパージングがなされ、パージングされたプログラムは、付録Ｂに定義されているようなデータ構造中に表される。
【０１４７】
以下に、関数構造体について説明する。関数構造体内のフィールド及び関係について理解を深めることによって、以下の動的検査エンジン７０６（第７図）の処理に対する説明がより容易となる。
【０１４８】
関数構造体１４００（第１４図）は、コンピュータプログラム６１０、または上述したような別の実施例ではソースコードプログラム、によって定められた関数を表すものであり、（ｉ）フィールド“ｎａｍｅ“１４０２、（ｉｉ）フィールド“ｌｉｎｅ”１４０４、（ｉｉｉ）フィールド“ｆｉｌｅ”１４０６、（ｉｖ）フィールド“ｒｅｓｕｌｔ”１４０８、（ｖ）フィールド“ｅｘｔｅｒｎａｌｓ”１４１０及び（ｖｉ）フィールド“ｓｔａｔｅｍｅｎｔ”を含んでいる。関数構造体１４００のフィールド“ｎａｍｅ”１４０２は、関数構造体１４００によって表される関数の識別予を特定する。例えば、上記のソースコード抜粋（１）の関数ｅｘａｍｐｌｅ １  （）  の識別子は“ｅｘａｍｐｌｅ １”である。
【０１４９】
フィールド“ｆｉｌｅ”１４０６及びフィールド“ｌｉｎｅ”１４０４は、それぞれ、関数構造体１４００によって表される関数が定義されるソースコードファイル及びそのファイル内のライン番号を示す。例えば、上記のソースコード抜粋（１）が、ファイル名“ｅｘａｍｐｌｅ １．ｃ”のソースコードファイルの全内容であるとした場合、関数ｅｘａｍｐｌｅ １  （）  を表す関数構造体のフィールド“ｆｉｌｅ”１４０６及びフィールド“ｌｉｎｅ”１４０４は、それぞれ、テキスト“ｅｘａｍｐｌｅ １．ｃ”及び整数値７のデータを格納する。
【０１５０】
フィールド“ｒｅｓｕｌｔ”１４０８は、宣言構造体１４１８を指定する。この宣言構造体１４１８は、以下に述べる宣言構造体１５０６と同様であり、関数構造体１４００によって表される関数がリターンする結果（ｒｅｓｕｌｔ）の型を規定する。例えば、上記のソースコード抜粋（１）の関数ｅｘａｍｐｌｅ １  （）  は、ソースコード抜粋（１）のライン７に示されているように、整数型の結果をリターンする。即ち、型“ｉｎｔ”のデータをリターンする。従って、関数構造体１４００が関数ｅｘａｍｐｌｅ １  （）  を表す場合、フィールド“ｒｅｓｕｌｔ”１４０８は、整数データを規定する宣言構造体１４１８を指定する。
【０１５１】
関数構造体１４００のフィールド“ｅｘｔｅｒｎａｌｓ”１４１０は、後により詳細に説明するエクスターナルリスト構造体１４１４を指定するポインタである。後に詳述するように、エクスターナルリスト構造体１４１４のようなエクスターナルリスト構造体は、複数のエクスターナルリスト構造体をシングルリンクトリスト（ｓｉｎｇｌｙ−ｌｉｎｋｅｄ  ｌｉｓｔ）を形成するようにリンクするのに用いられるポインタを含んでいる。従って、リストの長さが１の場合も含み、一つのエクスターナルリスト構造体を指定することは、エクスターナルリスト構造体のシングルリンクトリストを指定することである。関数構造体１４００のフィールド“ｅｘｔｅｒｎａｌｓ”１４１０によって指定されるこのようなシングルリンクトリストは、関数構造体１４００によって表される関数のエクスターナルを表すエクスターナルリスト構造体を含む。
【０１５２】
関数構造体１４００のフィールド“ｆｉｒｓｔ ｓｔｍｔ”１４１２は、後により詳細に説明するステートメント構造体１４１６を指定するポインタである。後により詳細に説明するように、ステートメント構造体１４１６のようなステートメント構造体は、複数のステートメント構造体をシングルリンクトリストを形成するようにリンクするのに用いられるポインタを含んでいる。従って、リストの長さが１の場合も含み、一つのステートメント構造体を指定することは、ステートメント構造体のシングルリンクトリストを指定することである。関数構造体１４００のフィールド“ｆｉｒｓｔ ｓｔｍｔ”１４１２によって指定されるこのようなシングルリンクトリストは、関数構造体１４００によって表される関数のステートメントを表すステートメント構造体を含む。
【０１５３】
エクスターナルリスト構造体 
エクスターナルリスト構造体１４１４を第１５図に詳細に示す。エクスターナルリスト構造体１４１４は、関数構造体１４００（第１４図）によって表される関数のエクスターナルを表すものであり、フィールド“ｆｉｒｓｔ ｄｅｃｌ”１５０２（第１５図）、フィールド“ｎｅｘｔ”１５０４、及びフィールド“ｆｉｒｓｔ ｅｘｔｅｒｎａｌ”１５１０を含んでいる。フィールド“ｆｉｒｓｔ ｄｅｃｌ”１５０２は、後により詳細に説明するように、エクスターナルリスト構造体１４１４によって表されるエクスターナルのデータ型を規定する宣言構造体１５０６を指定するポインタである。フィールド“ｎｅｘｔ”１５０４は、エクスターナルのシングルリンクトリストにおいてエクスターナルリスト構造体１４１４のすぐ後にエクスターナルリスト構造体１５０８が続く場合、エクスターナルリスト構造体１５０８を指定するポインタである。エクスターナルリスト構造体のシングルリンクトリストにおいてエクスターナルリスト構造体１４１４に続くエクスターナルリスト構造体がない場合、エクスターナルリスト構造体１４１４のフィールド“ｎｅｘｔ”１５０４はＮＵＬＬとなる。即ち、ＮＵＬＬデータを含む。フィールド“ｆｉｒｓｔ ｅｘｔｅｒｎａｌ”１５１０は、後により詳細に説明するように、エクスターナルリスト構造体１４１４によって表されるエクスターナルの状態を示すエクスターナル状態構造体（図示せず）を指定するポインタである。
【０１５４】
宣言構造体 
宣言構造体１５０６を第１６図に詳細に示す。宣言構造体は、宣言される変数または関数、即ち宣言において規定される変数または関数を規定する構造体である。Ｃ言語の文脈中の宣言については周知であり、Ｃスタンダードにも示されている。宣言構造体１５０６は、フィールド“ｋｉｎｄ”１６０２、フィールド“ｎａｍｅ”１６０４、フィールド“ｔｙｐｅ”１６０６、フィールド“ｉｔｅｍ”１６０８、及びフィールド“ｍｏｄｅｌ”１６１０を含んでいる。
【０１５５】
フィールド“ｋｉｎｄ”１６０２は、宣言される項目または関数が、グローバルに定義されるものであるか、スタティックなものであるか、あるいはローカルに定義されるものであるかを示すデータを含む。フィールド“ｎａｍｅ”１６０４は、項目または関数の識別子を特定するテキストデータを含む。上述したように、Ｃ言語の文脈において、項目または関数はテキスト形式の識別子によって識別され、識別子はＣスタンダードのセクション６．１．２に述べられているような所定の書式に従わなければならない。
【０１５６】
宣言構造体１５０６のフィールド“ｔｙｐｅ”１６０６は、宣言される項目または関数によって表されるデータの特定の型を定める型構造体１６１２を指定するポインタである。型構造体１６１２については、後で説明する。フィールド“ｉｔｅｍ”１６０８は、宣言される項目を表す項目構造体２７００を指定するポインタである。宣言構造体１５０６が宣言される関数を表現する場合、フィールド“ｉｔｅｍ”１６０８はＮＵＬＬであり、従って項目構造体は指定されない。
【０１５７】
宣言構造体１５０６のフィールド“ｍｏｄｅｌ”１６１０は、宣言構造体１５０６が関数の宣言を表し、その関数のモデルが関数モデル構造体１１００によって表される場合、関数モデル構造体１１００を指定するポインタである。宣言構造体１５０６が関数の宣言を表さない場合、フィールド“ｍｏｄｅｌ”１６１０はＮＵＬＬであり、即ち、ＮＵＬＬデータを含む。従って関数モデル構造体は指定されない。また、宣言構造体１５０６が関数の宣言を表すが、その関数の関数モデル構造体が存在しない場合も、フィールド“ｍｏｄｅｌ”１６１０はＮＵＬＬとなる。
【０１５８】
型構造体 
第１７図に型構造体１６１２を詳細に示す。型構造体１６１２のような型構造体は、整数、浮動小数点、英数文字、及び構造体のようなユーザ定義による型、のような特定のデータ型を規定する。型構造体１６１２は、フィールド“ｋｉｎｄ”７０２、フィールド“ｎａｍｅ”１７０４、フィールド“ｓｉｚｅ”１７０６、フィールド“ｐｏｉｎｔｓ ｔｏ”１７０８、及びフィールド“ｆｉｅｌｄｓ”１７１０を含んでいる。フィールド“ｋｉｎｄ”１７０２は、型構造体１６１２によって表される型が、整数、実数（即ち浮動小数点数値データ）、ポインタ、配列、構造体（即ち、Ｃ言語に対しデータ型“ｓｔｒｕｃｔ”で定義されたもの）、あるいはユニオン（ｕｎｉｏｎ）のいずれであるか特定するデータを含む。これらの各型は公知であり、Ｃスタンダードのセクション６．１．２．５及び６．５以降に述べられている。
【０１５９】
型構造体１６１２のフィールド“ｎａｍｅ”１７０４は、型構造体１６１２によって表される型がユーザ定義されるものである場合、その型の識別子を特定する英数字データを含む。型構造体１６１２によって表される型がＣ言語によって予め定められたものである場合、フィールド“ｎａｍｅ”１７０４はＮＵＬＬである。
【０１６０】
フィールド“ｓｉｚｅ”１７０６は、型構造体１６１２によって表される型のサイズを規定する。型が配列でない場合、フィールド“ｓｉｚｅ”１７０６は、型構造体１６１２によって表される型の項目に含まれるデータのビット数を示す。例えば、型が３２ビット整数の場合、型構造体１６１２のフィールド“ｓｉｚｅ”１７０６は値３２を示す。型が配列の場合、フィールド“ｓｉｚｅ”１７０６は配列全体に含まれるデータのビット数、即ちその配列のエレメントによって表されるその型の項目に含まれるデータのビット数にその配列全体に含まれるエレメントの数を掛けたものを表す。例えば、宣言“ｉｎｔ  ａｒｒａｙ［１０］；”によって、１０個のエレメントからなる配列が宣言されるとする。型“ｉｎｔ”が３２ビット整数の場合、宣言された配列のサイズは、１０エレメント×３２ビットとなる。従って、その配列のサイズは３２０ビットとなる。
【０１６１】
構造体１６１２によって表される型が別のデータ型を指定するポインタの場合、フィールド“ｐｏｉｎｔｓ ｔｏ”１７０８は別のデータ型を表す型構造体、即ち型構造体１７１２を指定するポインタである。型構造体１７１２は型構造体１６１２と同様である。逆に、型構造体１６１２によって表される型がポインタでない場合、フィールド“ｐｏｉｎｔｓ ｔｏ”１７０８はＮＵＬＬとなる。
【０１６２】
型構造体１６１２によって表される型が構造体型（即ちＣ言語の型“ｓｔｒｕｃｔ”）またはユニオン型の場合、フィールド“ｆｉｅｌｄｓ”１７１０は、それぞれ、その構造体型またはユニオン型の第１フィールドを表すフィールド構造体１７１４を指定するポインタとなる。後により詳細に説明するように、ある特定の構造体型またはユニオン型のフィールドに対応するフィールド構造体は、シングルリンクトリストを形成するようにリンクされる。型構造体１６１２によって表される型が構造体型でもユニオン型でもない場合、型構造体１６１２のフィールド“ｆｉｅｌｄｓ”１７１０はＮＵＬＬとなる。
【０１６３】
フィールド構造体 
フィールド構造体１７１４を第１８図に詳細に示す。フィールド構造体１７１４は、フィールド“ｎａｍｅ”１８０２、フィールド“ｓｉｚｅ”１８０４、フィールド“ｏｆｆｓｅｔ”１８０６、及びフィールド“ｎｅｘｔ”１８０８を含んでいる。フィールド構造体１７１４について、Ｃ言語に基づく以下の型定義の例の文脈において説明する。
【０１６４】
2006252583.tif 000022
【０１６５】
ソースコード抜粋（９）の型定義は、識別子が“ｐｏｉｎｔ”であり２つのフィールドを有する構造体型を定義している。型“ｐｏｉｎｔ”は従って構造体型である。各フィールドは型“ｉｎｔ”であり、これは通常３２ビット整数である。また、各フィールドは、識別子“ｘ”または“ｙ”を有している。
【０１６６】
フィールド構造体１７１４のフィールド“ｎａｍｅ”１８０２は、フィールド構造体１７１４によって表されるフィールドの識別子を特定する英数字データを含む。例えば、ソースコード抜粋（９）に定義されている構造体の第１フィールドを表すフィールド構造体のフィールド“ｎａｍｅ”はテキスト“ｘ”を含む。
【０１６７】
フィールド構造体１７１４のフィールド“ｓｉｚｅ”１８０４は、フィールド構造体１７１４によって表されるフィールドに含まれるデータのビット数を示す。例えば、カリフォルニア州、マウンテンビュー（Ｍｏｕｎｔａｉｎ  Ｖｉｅｗ）のサンマイクロシステムズ社（Ｓｕｎ  Ｍｉｃｒｏｓｙｓｔｅｍｓ，Ｉｎｃ．）から販売されている“ＳｕｎＯＳ  Ｃ  ｃｏｍｐｉｌｅｒ”によってコンパイルされるようなＣ言語の典型的な例では、型“ｉｎｔ”の項目は３２ビット長さである。ソースコード抜粋（９）の例では、各フィールドは３２ビット整数であり、従って３２ビットのデータを含む。従って、個々のフィールドを表す各フィールド構造体のフィールド“ｓｉｚｅ”は整数値３２を示す。
【０１６８】
フィールド構造体１７１４のフィールド“ｏｆｆｓｅｔ”は、フィールド構造体１７１４によって表されるフィールドのデータまでの構造体の開始からのオフセットを表す。例えば、ソースコード抜粋（９）におけるフィールド“ｘ”は型“ｐｏｉｎｔ”の第１フィールドであるため、オフセットは０である。
【０１６９】
型“ｐｏｉｎｔ”を第１９図に図式的に示す。型“ｐｏｉｎｔ”のフィールド“ｘ”は３２ビット長さであり、オフセット０で始まる。型“ｐｏｉｎｔ”のフィールド“ｙ”は３２ビット長さであり、オフセット３２で始まる。従って、フィールド構造体１７１４Ｘ（これはフィールド構造体１７１４（第１８図）と全く同様であり、型“ｐｏｉｎｔ”のフィールド“ｘ”を表すものである。）のフィールド“ｏｆｆｓｅｔ“１８０６Ｘ（第２０図）は、整数値０を示す。同様に、フィールド構造体１７１４（第１８図）と全く同様な、型“ｐｏｉｎｔ”のフィールド“ｙ”を表すフィールド構造体１７１４Ｙのフィールド“ｏｆｆｓｅｔ”１８０６Ｙ（第２０図）は、整数値３２を示す。
【０１７０】
フィールド構造体１７１４のフィールド“ｎｅｘｔ”１８０８（第１８図）は、所与の構造体型のフィールド構造体のシングルリンクトリストにおける次のフィールド構造体を指定するポインタである。例えば、型“ｐｏｉｎｔ”を表す型構造体１６１２Ｐのフィールド“ｆｉｅｌｄｓ”１７１０Ｐ（第２０図）は、型“ｐｏｉｎｔ”の第１フィールドであるフィールド“Ｘ”を表すフィールド構造体１７１０Ｘを指定する。型“ｐｏｉｎｔ”の次のフィールドはフィールド“Ｙ”である。従って、フィールド構造体１７１４Ｘのフィールド“ｎｅｘｔ”１８０８Ｘは、型“ｐｏｉｎｔ”のフィールド“ｙ”を表すフィールド構造体１７１４Ｙを指定する。型“ｐｏｉｎｔ”のフィールド“ｙ”は、型“ｐｏｉｎｔ”の最後のフィールドであり、その後に型“ｐｏｉｎｔ”の他のフィールドはない。
従って、フィールド構造体１７１４Ｙのフィールド“ｎｅｘｔ”１８１０ＹはＮＵＬＬである。
【０１７１】
ステートメント構造体 
上述したように、関数構造体１４００のフィールド“ｆｉｒｓｔ ｓｔｍｔ”１４１２（第１４図）は、ステートメント構造体１４１６を指定する。ステートメント構造体１４１６は第２１図に詳細に示されている。ステートメント構造体１４１６のようなステートメント構造体は、Ｃ言語に基づきまとまってある関数を形成する複数のステートメントを表す。ステートメント１４１６は次のフィールドを含んでる：（ｉ）フィールド“ｋｉｎｄ”２１０２、（ｉｉ）フィールド“ｌｉｎｅ”２１０４、（ｉｉｉ）フィールド“ｎｅｘｔ”２１０６、（ｉｖ）フィールド“ｆｌａｇｓ”２１０８、及び（ｖ）フィールド“ｐｏｉｎｔｅｒｓ”２１１０。
【０１７２】
ステートメント構造体１４１６のフィールド“ｋｉｎｄ”２１０２は、ステートメント構造体１４１６によって表されるステートメントの種類を表す。フィールド“ｋｉｎｄ”２１０２は、以下のステートメント種類のうちの１つを特定する：エラー、宣言、式、ブロック、“ｉｆ”、“ｅｌｓｅ”、“ｒｅｔｕｒｎ”、ループ、“ｓｗｉｔｃｈ”、“ｂｒｅａｋ”、“ｃｏｎｔｉｎｕｅ”、及び“ｇｏｔｏ”。ステートメント構造体によるこれらのステートメント種類の各々の表現について、以下により詳細に説明する。
【０１７３】
ステートメント構造体１４１６のフィールド“ｌｉｎｅ”２１０４は、関数構造体１４００（第１４図）によって表される関数を定義するソースコードファイル内において、ステートメント構造体１４１６によって表されるステートメントが現れる、即ち、ステートメント構造体１４１６によって表されるステートメントを含むテキストラインを表す。ステートメントが現れるラインは、エラーを生じさせる特定のステートメントが、検出されたエラーの通知によってユーザに特定されるようにするため、ステートメント構造体１４１６内に保持される。
【０１７４】
ステートメント構造体１４１６のフィールド“ｎｅｘｔ”２１０６（第２１図）は、ステートメントのブロックにおいてステートメント構造体１４１６によって表されるステートメントのすぐ後に続くステートメントを表す別のステートメント構造体２１１２を指定するポインタである。このようにして、ステートメントブロックの全ステートメントが、シングルリンクトリストを形成するようにリンクされたステートメント構造体によって表される。ステートメント構造体１４１６（第２１図）によって表されるステートメントがステートメントブロックの最後のステートメントの場合、フィールド“ｎｅｘｔ”２１０６はＮＵＬＬとなり、他のステートメント構造体を指定しない。
【０１７５】
ステートメント構造体１４１６のフィールド“ｆｌａｇｓ”２１０８は符号なし３２ビット整数であり、その個々のビットはステートメント構造体１４１６によって表されるステートメントに関連するエラーがユーザに通知されたかどうかを示すフラグとして用いられる。エラーが通知されるときにはいつも、通知されるべきエラーに対応するフィールド“ｆｌａｇｓ”２１０８のフラグがチェックされる。フラグがセットされている場合、そのフラグはステートメント構造体１４１６によって表されるステートメントの文脈において既にそのエラーの通知がなされていることを表すため、エラーは通知されない。フラグがセットされていない場合は、エラーは通知され、エラーの通知を反映するようにフラグがセットされる。このようにして、各タイプのエラーは、ある特定のステートメントに対して１回だけ通知される。
【０１７６】
ステートメント構造体１４１６のフィールド“ｐｏｉｎｔｅｒｓ”２１１０は、ステートメント構造体１４１６によって表されるステートメントの各部分を表す構造体を指定する１または複数のポインタの配列である。この配列中のポインタの数は、ステートメント構造体１４１６によって表されるステートメントの特定の種類に依存する。
【０１７７】
エラー、“ｂｒｅａｋ”、及び“ｃｏｎｔｉｎｕｅ”ステートメントは部分を有さず、従ってステートメント構造体１４１６がエラー、“ｂｒｅａｋ”、あるいは“ｃｏｎｔｉｎｕｅ”ステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０はＮＵＬＬである。エラーステートメントとは、Ｃ言語に従わないステートメントである。“ｂｒｅａｋ”及び“ｃｏｎｔｉｎｕｅ”ステートメントは周知であり、それぞれＣスタンダードのセクション６．６．６．３及び６．６．６．２に説明されている。
【０１７８】
宣言ステートメントには、特定の型のデータを有する宣言される変数が含まれ、更に恐らくはその変数に対する初期値も含まれる。従って、ステートメント構造体１４１６が宣言ステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０は２つのポインタからなる配列となる。第１のポインタは宣言される変数を表す宣言構造体を指定する。初期値が定められる場合、第２のポインタは、宣言される変数の初期値を与えるべく評価される式を表す式構造体を指定する。宣言される変数に対し初期値が定められない場合は、第２のポインタはＮＵＬＬである。
【０１７９】
式ステートメント（ｅｘｐｒｅｓｓｉｏｎ  ｓｔａｔｅｍｅｎｔ）とは、それ自身が式であるステートメントである。式（ｅｘｐｒｅｓｓｉｏｎ）はＣ言語の公知のコンポーネントであり、１または複数の項目、関数に対する呼び出し、及び演算子の集まりである。Ｃ言語では、全ての式は値（ｖａｌｕｅ）を有する。式の評価の結果は、値がその式の値であるような項目となり、この項目はしばしば式の項目と呼ばれる。本明細書中では、しばしば、式の項目の値を式の値と言う。式の評価については、以下により詳細に説明される。
【０１８０】
ステートメント構造体１４１６が式ステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０は、式構造体２２００（第２２図）のような式構造体を指定する１つのポインタからなる配列となる。式構造体２２００は、フィールド“ｋｉｎｄ”２２０２、フィールド“ｔｙｐｅ”２２０４、フィールド“ｉｔｅｍ”２２０６、フィールド“ｎｕｍ ｏｐｅｒａｎｄｓ”２２０８、及びフィールド“ｏｐｅｒａｎｄｓ”２２１０を含んでいる。フィールド“ｋｉｎｄ”２２０２は、式構造体２２００によって表される式の種類を特定する。式が演算子を含む場合、フィールド“ｋｉｎｄ”２２０２はその演算子を示す。
【０１８１】
フィールド“ｔｙｐｅ”２２０４は、式のデータ型、即ち、その式の評価の結果を示す項目の型を表す型構造体２２１２を指定するポインタである。型構造体２２１２は、上述した型構造体１６１２と同様である。式構造体２２００のフィールド“ｉｔｅｍ”２２０６は、式の評価の結果を示す項目を表す項目構造体２２１４を指定するポインタである。項目構造体２２１４は上述した項目構造体２７００（第２７図）と同様である。式構造体２２００によって表された式の評価の前においては、フィールド“ｉｔｅｍ”２２０６はＮＵＬＬである。
【０１８２】
式構造体２２００によって表される式の中のオペランドの数はフィールド“ｎｕｍ ｏｐｅｒａｎｄｓ”２２０８によって示される。フィールド“ｏｐｅｒａｎｄｓ”２２１０は式構造体の配列であり、その各々は式構造体２２００によって表される式の一つのオペランドを表す。この配列の長さは、フィールド“ｎｕｍ ｏｐｅｒａｎｄｓ”２２０８に示されたオペランドの数に等しい。Ｃ言語において定義される式の様々な型、及び各型の式のオペランドの数及び型については周知であり、Ｃスタンダードにも記載されている。
【０１８３】
ブロックステートメントとは、１または複数のステートメントをグループにまとめたステートメントである。ブロックステートメントの実行は、１または複数のステートメントの実行である。ブロックステートメントは部分、即ち、１または複数のステートメントを有する。ステートメント構造体１４１６（第２１図）がブロックステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０はシングルポインタであり、このポインタは１または複数のステートメントの最初のステートメントを表すステートメント構造体を指定する。１または複数のステートメントを表すステートメント構造体は、上述したようにフィールド“ｎｅｘｔ”２１０６を用いることによってシングルリンクトリストを形成するようにリンクされる。
【０１８４】
“ｉｆ”ステートメントは、“ｉｆ”ステートメントの述語としばしば呼ばれる式を評価して、その評価の結果が“ｔｒｕｅ”のブール値になる場合は、第２のステートメントを実行させるものである。ステートメント構造体１４１６が“ｉｆ”ステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０は２つのポインタからなる配列となる。第１のポインタは、その値によって第２ステートメントが実行されるか否かが判定される式を表す式構造体を指定する。第２ポインタは、第２ステートメントを表すステートメント構造体を指定する。
【０１８５】
“ｅｌｓｅ”ステートメントは、“ｉｆ”ステートメントのすぐ後に置かれ、“ｉｆ”ステートメントの述語の評価が“ｆａｌｓｅ”のブール値なる場合、第３ステートメントを実行させる。ステートメント構造体１４１６が“ｅｌｓｅ”ステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０は２つのポインタからなる配列となる。第１ポインタは、第３ステートメントを表すステートメント構造体を指定する。第２ポインタは、ある式構造体を指定するかまたはＮＵＬＬである。この式構造体によって表される式は、しばしば、“ｅｌｓｅ”ステートメントの述語と呼ばれる。第２ポインタが式構造体を指定する場合、第３ステートメントは、“ｉｆ”ステートメントの述語の評価が“ｆａｌｓｅ”のブール値となり、“ｅｌｓｅ”ステートメントの述語の評価が“ｔｒｕｅ”のブール値となる場合にのみ実行される。Ｃスタンダードにも記載され広く知られているように、これは“ｅｌｓｅ  ｉｆ”ステートメントを表す。第２ポインタがＮＵＬＬの場合、第３ステートメントは、“ｉｆ”ステートメントの述語の評価が“ｆａｌｓｅ”のブール値となる場合にのみ実行される。
【０１８６】
“ｒｅｔｕｒｎ”ステートメントは、被呼び出し関数の実行を終了させ、制御を呼び出し関数に移すとともに、場合によっては呼び出し関数に戻り値項目を与える。呼び出し関数に制御を移すとともに、呼び出し関数に戻り値項目を与えることは、呼び出し関数に戻り値項目をリターンすると言われる。ステートメント構造体１４１６が“ｒｅｔｕｒｎ”ステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０はシングルポインタであり、このポインタは式構造体を指定するかまたはＮＵＬＬである。このポインタが式構造体を指定する場合、その式構造体によって表される式の評価の結果を示す項目が呼び出し関数にリターンされる。
【０１８７】
ループステートメントは、０回または１回以上実行される第２ステートメントを生成するものである。Ｃ言語におけるループステートメントの例として、“ｆｏｒ”ステートメント、“ｄｏ”ステートメント、及び“ｗｈｉｌｅ”ステートメントがあるが、それらはＣスタンダードのセクション６．６．５に記載されており広く知られている。ステートメント構造体１４１６がループステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０はシングルポインタであり、第２ステートメントを表すステートメント構造体を指定する。
【０１８８】
“ｓｗｉｔｃｈ”ステートメントは、式を評価し、式の評価の結果を示す値に応じてブロックステートメント内の制御をそのブロックステートメント内の特定のステートメントへ移す。式は、しばしば“ｓｗｉｔｃｈ”ステートメントの述語と呼ばれる。ステートメント構造体１４１６が“ｓｗｉｔｃｈ”ステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０は２つのポインタからなる配列となる。第１のポインタは、その値に応じて制御が移行する式を表す式構造体を指定する。第２のポインタは、ブロックステートメントを表すステートメント構造体を指定する。
【０１８９】
“ｇｏｔｏ”ステートメントは第２ステートメントへの制御の移行を発生させる。一実施例では、ステートメント構造体１４１６が“ｇｏｔｏ”ステートメントを表す場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０は、第２ステートメントを表すステートメント構造体を指定するシングルポインタからなる配列である。より簡略化された実施例では、“ｇｏｔｏ”ステートメントは被呼び出しルーチンの実行を終了させるものとして取り扱われる。この実施例では“ｇｏｔｏ”ステートメントは部分を有さず、フィールド“ｐｏｉｎｔｅｒｓ”２１１０はポインタを含まない配列である。
【０１９０】
このようにして、関数構造体１４００（第１４図）は動的検査エンジン７０６によって解析されるべき関数を表現する。
【０１９１】
関数の解析 
上述したように、動的検査エンジン７０６（第７図）は、ステップ９０８（第９図）においてコンピュータプログラム６１０（第６図）のパージングの結果得られた各関数構造体を解析する。ステップ９０８は論理流れ図９０８（第２４図）に、より詳細に示されている。ステップ９０８の実行において、処理されている関数構造体はサブジェクト関数構造体と呼ばれる。同様に、サブジェクト関数構造体によって表される関数は、サブジェクト関数と呼ばれる。論理流れ図９０８のステップ２４０４及び２４０８において、サブジェクト関数は様々な仮定のもとで解析される。
【０１９２】
上記において詳しく説明したように、ある特定の関数の制御流れ経路は、しばしばその関数が実行されるまでは未知であるイベントに依存する。実行後でも、その関数のある実行時に生じたイベントがその関数の全ての実行においても常に発生するとは限らない。そのため、制御の流れが未知のイベントに依存するような関数の解析は、それらの未知のイベントについての様々な仮定の下で繰り返しなされる。
【０１９３】
一実施例では、関数の全ての可能な制御流れが決定され解析される。例えば、制御は、関数内の全ての“ｉｆ”ステートメントに対して２つの可能な経路の一方に沿って流れ得るし、また、関数内の全ての“ｓｗｉｔｃｈ”ステートメントに対して複数の可能な経路の内の１つに沿って流れ得る。“ｓｗｉｔｃｈ”ステートメントの場合、可能な経路の数は、その“ｓｗｉｔｃｈ”ステートメントに関連する“ｃａｓｅ”ステートメントの数に等しい。これには、存在する場合には、“ｄｅｆａｕｌｔ”ステートメントも含まれる。いったん関数の全ての可能な制御流れ経路が決定されると、その関数の各制御流れ経路が１回ずつ用いられるようにして、その関数は繰り返し解析される。このようにして、その関数の制御の流れに影響を与え得る全ての可能なイベントを考慮して関数の解析がなされる。
【０１９４】
より簡略化された実施例では、関数の特定の制御流れ経路がその関数内の各“ｉｆ”ステートメント及び各“ｓｗｉｔｃｈ”ステートメントにおけるイベントに関してランダムな仮定を設定することによってランダムに選択される。関数は様々な制御流れ経路がランダムに選択されるようにして繰り返し解析される。関数を解析する回数は、関数の全ての可能な制御流れ経路が解析される可能性が十分高くなるように選択されるか、あるいは別の方法として１つのルーチンを解析するのに費やされる労力を制限するように選択することもできる。
【０１９５】
ステップ２４０４及び２４０８（第２４図）は、後者のより簡略化された方の実施例を例示したものである。ステップ２４０４において、サブジェクト関数が解析される回数が決定される。ステップ２４０４は、論理流れ図２４０４（第２５図）としてより詳細に示されている。ステップ２５０２において、サブジェクト関数内で“ｉｆ”ステートメントが使用される回数が決定される。詳述すると、実行エンジン８０２（第８図）によって、関数構造体１４００のフィールド“ｆｉｒｓｔ−ｓｔａｔｅｍｅｎｔ”１４１２（第１４図）により直接的または間接的に指定されたステートメント構造体のシングルリンクトリスト内の各ステートメント構造体のフィールド“ｋｉｎｄ”２１０２（第２１図）が、“ｉｆ”ステートメントを示すデータと比較される。ステートメント構造体のフィールド“ｋｉｎｄ”と“ｉｆ”ステートメントを示すデータとが整合する回数が、“ｉｆ”ステートメントがそのサブジェクト関数内で使用される回数として記録される。
【０１９６】
ステップ２５０２から、プロセスはステップ２５０４に進み、そこでサブジェクト関数が解析される回数が決定される。一実施例では、サブジェクト関数が解析される回数は、“ｉｆ”ステートメントがサブジェクト関数内で使用される回数に対応する。その例を表Ｍに示す。
【０１９７】
【表１２】
2006252583.tif 000023
【０１９８】
ステップ２５０４の後、論理流れ図２４０４に基づくプロセス、従ってステップ２４０４（第２４図）は、終了する。プロセスはステップ２４０４からステップ２４０８へ進み、サブジェクト関数は上述したステップ２４０４で決定された数だけ繰り返し解析される。ステップ２４０８の一回の繰返し、即ち、サブジェクト関数の１回の解析は、論理流れ図２６００（第２６図）に示される。
【０１９９】
サブジェクト関数の１回の繰返しの解析は、ステップ２６０２で開始され、そこで、各エクスターナルに対するエクスターナル状態構造体が初期化される。エクスターナル状態構造体は、まずそのエクスターナル状態構造体に対応する、即ちそのエクスターナル状態構造体によって表される状態を有するエクスターナルに対応する項目構造体を生成し、続いてそのエクスターナルのＤＫ及びＣＰ状態を状態Ｏに設定することによって初期化される。項目構造体は、項目を表すメモリ１０４（第１図）内の構造体である。
【０２００】
項目構造体２７００（第２７図）は、以下のフィールドを含んでいる。
即ち、フィールド“ｒｅｓｏｕｒｃｅ”２７０２、フィールド“ｅｘｔｅｒｎａｌ”２７０４、フィールド“ｖａｌｕｅ”２７０６、フィールドｆｉｒｓｔ ｉｎ ｂｕｎｃｈ２７０８、フィールド“ｓｉｚｅ ｏｆ ｂｕｎｃｈ”２７１０、フィールド“ｔｙｐｅ ｃｏｄｅ”２７１２、フィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４、フィールド“ｈｅａｄ ｉｎ ｂｕｎｃｈ”２７１６、フィールド“ｋｎｏｗｎ ｂｕｎｃｈ ｓｉｚｅ”２７１８、及びフィールド“ｉｎｖａｌｉｄ ｐｏｉｎｔｅｒ”２７２０を含んでいる。
【０２０１】
各項目は、リソース及び／若しくはエクスターナルに関連付けられ得る。項目構造体２７００により表現される項目がリソースの１つと関連している場合、項目構造体２７００のフィールド“ｒｅｓｏｕｒｃｅ”２７０２が、そのリソースを表現するリソース状態構造体を指定する。逆に、その項目がリソースと関連していない場合、フィールド“ｒｅｓｏｕｒｃｅ”２７０２は、そのことを示すべくＮＵＬＬにされる。項目構造体２７００により表現される項目がエクスターナルの１つと関連している場合、項目構造体２７００のフィールド“ｅｘｔｅｒｎａｌ”２７０４が、そのエクスターナルを表現するエクスターナル状態構造体を指定する。逆に、その項目がエクスターナルと関連していない場合、フィールド“ｅｘｔｅｒｎａｌ”２７０４は、そのことを示すべくＮＵＬＬにされる。
【０２０２】
項目構造体２７００のフィールド“ｖａｌｕｅ”２７０６は、項目構造体２７００によって表現される項目の実際の値を定めるデータを含んでいる。つまり、フィールド“ｖａｌｕｅ”２７０６に格納されたデータは、メモリ１０４（第１図）における、項目構造体２７００（第２７図）によって表現された項目によって指定された位置に格納された実際のデータを表現する。項目構造体２７００のフィールド“ｔｙｐｅ ｃｏｄｅ”２７１２は、その項目のメモリ位置に格納されたデータの型を指定する。ここに開示する実施例において支援されているデータの型には、ｌｏｎｇ、ｐｏｉｎｔｅｒ、及びｄｏｕｂｌｅがある。最近のＣ言語の実装においては、“ｌｏｎｇ”は３２ビットの符号付き整数、“ｐｏｉｎｔｅｒ”はメモリ１０４のようなメモリにおけるアドレスを指定する値、また、“ｄｏｕｂｌｅ”は６４ビットの浮動小数点である。フィールド“ｖａｌｕｅ”２７０６内には各データの型に対応するサブフィールドがある。使用されるのはただ１つのサブフィールドである。即ちフィールド“ｔｙｐｅ ｃｏｄｅ”２７１２で指定されたデータの型に対応するサブフィールドのみが使用される。
【０２０３】
項目構造体２７００のフィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４は、項目構造体２７００により表現されたその項目が初期化されているか否か、即ち項目構造体２７００によって表現される項目が既知の値を有するか否かを示す。項目構造体２７００のフィールド“ｉｎｖａｌｉｄ ｐｏｉｎｔｅｒ”２７２０は、項目構造体２７００によって表現される項目が無効ポインタであるか否かを示す。Ｃ言語においては、ポインタがメモリ１０４（第１図）における有効な位置を指定している場合、そのポインタは有効である。そうでない場合、そのポインタは無効である。ＮＵＬＬポインタは、Ｃ言語の多くの実装において０に選択される特定の無効ポインタである。一実施例においては、フィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４及び“ｉｎｖａｌｉｄ ｐｏｉｎｔｅｒ”２７２０は、それぞれ１つのビットよりなる。
【０２０４】
フィールド“ｆｉｒｓｔ ｉｎ ｂｕｎｃｈ”２７０８、“ｓｉｚｅ ｏｆ ｂｕｎｃｈ”２７１０、“ｈｅａｄ ｉｎ ｂｕｎｃｈ”２７１２、及び“ｋｎｏｗｎ ｂｕｎｃｈ ｓｉｚｅ”２７１８は、メモリの集群（ｂｕｎｃｈ）を解析するのに用いられる。メモリの集群については、後に詳しく説明する。
【０２０５】
ステップ２６０２（第２６図）において、ひとたびこのサブジェクト関数のエクスターナルが初期化されると、処理はステップ２６０４に進む。ステップ２６０４において、サブジェクト関数の各ステートメントが評価される。ステートメントの評価は、そのステートメントの実行をエミュレートすることによって行われる。ステートメントの評価により、エクスターナル及び／若しくはリソースに対して施した演算の結果が得られ、エクスターナル及び／若しくはリソースのそれぞれの状態の変化が生ずる。後に詳しく説明するが、各ステートメントの評価は論理流れ図２８００（第２８図）に従って個別に行われる。
【０２０６】
ひとたびサブジェクト関数の各ステートメントが評価されると、処理はステップ２６０４（第２６図）からステップ２６０６に進む。ステップ２６０６においてはサブジェクト関数の様々なリソースの状態のリーク（ｌｅａｋ）がチェックされる。ステップ２６０６の詳細は論理流れ図２６０６（第４１図）に示されており、これについては後に説明する。ステップ２６０６から処理はステップ２６０８に進み、ここでサブジェクト関数の各エクスターナルが更新される。エクスターナルの更新は、エクスターナルのＤＫ及びＣＰ状態、及びそのエクスターナルに関連付けられたリソースのＲＳ状態に基づいて、エクスターナルの複合ＤＫ、ＣＰ、及びＲＳ状態を更新することによって行われる。これらの状態はサブジェクト関数の現反復的解析（ｃｕｒｒｅｎｔ  ｉｔｅｒａｔｉｖｅ  ａｎａｌｙｓｉｓ）から得られる。１つのエクスターナルの更新は、論理流れ図４２００（第４２図）に示されており、後に完全に説明する。
【０２０７】
ステップ２６０８（第２６図）が終了すると、論理流れ図２６００に従った処理、即ちサブジェクト関数の反復的解析の１回分が終了する。
ステートメントの評価  上述のように、サブジェクト関数の各ステートメントは論理流れ図２８００（第２８図）に従って個別に評価される。処理はテストステップ２８０２から開始されるが、このステップでは実行エンジン８０２（第８図）が、そのステートメント、すなわちサブジェクトステートメントの構造体を表すステートメント構造体のフィールド“ｋｉｎｄ”２１０２（第２１図）を検索することによって、そのステートメントが式であるか否かを判定する。そのステートメントはサブジェクトステートメント構造体によって表されるサブジェクトステートメントである。即ち、その時点で論理流れ図２８００（第２８図）に従って評価されているステートメントをサブジェクトステートメントと称する。
【０２０８】
サブジェクトステートメントが式である場合、すなわちフィールド“ｋｉｎｄ”２１０２が、サブジェクトステートメントが式であることを示している場合には、処理はテストステップ２８０２（第２８図）からステップ２８０４に進み、そこで実行エンジン８０２（第８図）が式、すなわちサブジェクトステートメントの評価を行う。実行エンジン８０２は、その式に含まれる項目上の関数及び演算子の実行をエミュレートすることによって式の評価を行う。ステップ２８０４（第２８図）は論理流れ図２９００（第２９図）に従って実行されるが、これについては後に詳述する。
【０２０９】
後に詳しく述べるように、論理流れ図２９００に従う処理は、式の評価の結果得られた項目に対して演算を施し得る。ステップ２８０４の文脈に於いては、式の項目に対して施される演算は無い。テストステップ２８０２（第２８図）に於いて、サブジェクトステートメントが式でない場合は、処理はテストステップ２８０６に進む。
【０２１０】
テストステップ２８０６に於いては、実行エンジン８０２（第８図）がサブジェクトステートメント構造体のフィールド“ｋｉｎｄ”２１０２とそのサブジェクトステートメントが宣言であることを示すデータとを比較する。ｄｅｆｉｎｉｎｇ宣言は、項目を生成させるＣ言語に従ったステートメントである。ｄｅｃｌａｒｉｎｇ宣言は、その項目があたかも特定の型であるかのようにその項目を取り扱うようＣＰＵ１０２（第１図）に指示するＣ言語に従ったステートメントである。ここで述べたもの以外の場合には、宣言はｄｅｆｉｎｉｎｇ宣言となる。サブジェクトステートメントが宣言である場合、処理はテストステップ２８０６（第２８図）からステップ２８０８に進み、ここでその宣言が処理される。これについては後に詳しく述べる。逆に、サブジェクトステートメントが宣言でない場合は、処理はテストステップ２８０６からテストステップ２８１０に進む。
【０２１１】
テストステップ２８１０に於いては、実行エンジン８０２（第８図）が、サブジェクトステートメント構造体のフィールド“ｋｉｎｄ”２１０２（第２１図）と、サブジェクトステートメントが“ｉｆ”ステートメントであることを示すデータとを比較する。そのステートメントが“ｉｆ”ステートメントである場合は、処理はテストステップ２８１０（第２８図）からステップ２８１２に進み、ここでそのサブジェクトステートメントが処理される。ステップ２８１２は後に説明する論理流れ図２８１２（第３５図）により詳細に示されている。逆に、サブジェクトステートメントが“ｉｆ”ステートメントでない場合は、処理はテストステップ２８１０（第２８図）からテストステップ２８１４に進む。
【０２１２】
テストステップ２８１４に於いては、実行エンジン８０２（第８図）が、サブジェクトステートメント構造体のフィールド“ｋｉｎｄ”２１０２（第２１図）
と、そのサブジェクトステートメントが“ｒｅｔｕｒｎ”ステートメントであることを示すデータとを比較する。サブジェクトステートメントが“ｒｅｔｕｒｎ”ステートメントである場合は、処理はテストステップ２８１４（第２８図）からステップ２８１６に進み、ここでそのステートメントが処理される。ステップ２８１６は後に説明する論理流れ図２８１６（第３９図）により詳細に示されている。逆に、そのサブジェクトステートメントが“ｒｅｔｕｒｎ”ステートメントでない場合は、処理はテストステップ２８１４（第２８図）からテストステップ２８１８に進む。
【０２１３】
テストステップ２８１８に於いては、実行エンジン８０２（第８図）が、そのサブジェクトステートメントのフィールド“ｋｉｎｄ”２１０２（第２１図）と、そのサブジェクトステートメントがループ若しくはブロックステートメントであることを示すデータとを比較する。サブジェクトステートメントがループ若しくはブロックステートメントである場合には、処理はテストステップ２８１８（第２８図）からステップ２８２０に進み、そのステートメントが処理される。ステップ２８２０は後に説明する論理流れ図２８２０（第４０図）により詳細に示されている。逆に、そのサブジェクトステートメントはループステートメントでもブロックステートメントでもない場合には、処理はテストステップ２８１８（第２８図）からテストステップ２８２２に進む。
【０２１４】
テストステップ２８２２に於いては、実行エンジン８０２（第８図）が、サブジェクトステートメントのフィールド“ｋｉｎｄ”２１０２（第２１図）と、そのサブジェクトステートメントが“ｇｏｔｏ”ステートメントであることを示すデータとを比較する。そのサブジェクトステートメントが“ｇｏｔｏ”ステートメントである場合には、処理はテストステップ２８２２（第２８図）からステップ２８２４に進み、そこで実行エンジン８０２（第８図）が、後に詳述するように“ｒｅｔｕｒｎ”条件を示すデータを制御レコード内に格納する。この制御レコードは、後に詳述するようにそのサブジェクト関数の実行のエミュレーション時に適切な制御の流れを与えるために用いられる。“ｒｅｔｕｒｎ”条件は、サブジェクト関数の反復的解析を終了させる。
【０２１５】
サブジェクトステートメントが“ｇｏｔｏ”ステートメントでない場合には、処理は論理流れ図２８００に従って終了する。
【０２１６】
ステップ２８０４、２８０８、２８１２、２８１６、２８２０、または２８２４のいずれかが実行されれた後、処理は論理流れ図２８００に従って終了する。従って、実行エンジン８０２（第８図）によるステートメントの評価は、そのステートメントが式であるか、宣言であるか、“ｉｆ”ステートメントであるか、“ｒｅｔｕｒｎ”ステートメントであるか、ブロックステートメントであるか、ループステートメントであるか、若しくは“ｇｏｔｏ“ステートメントであるかによって、それぞれステップ２８０４（第２８図）、ステップ２８０８、２８１２、２８１６、２８２０、２８２４、若しくは２８２８において行われるのである。
【０２１７】
式の評価 
上述のように、式は論理流れ図２９００（第２９図）に従って評価されるが、この場合実行エンジン８０２（第８図）が、動的検査エンジン７０６の一部であるステートマシン８０４をして、実行エンジン８０２によって指定された演算がある場合にはその演算をその式の項目に施すようにする。上述のように、ステップ２８０４（第２８図）の文脈に於いては、実行エンジン８０２（第８図）はこのような演算の指定を行わない。ここに開示する本発明の実施例では、式を評価することで、式であるステートメント若しくは式を含むステートメントの実行によりその式のオペランドである項目に及ぼす効果を判断している。
【０２１８】
論理流れ図２９００（第２９図）に従う処理は、ステップ２９０２から開始されるが、ここでは式の評価を行うために、その式に於ける演算子によって指定された処理が実行される。上述のように、式は、動的検査エンジン７０６（第７図）内に於いて式構造体２２００（第２２図）のような式構造体によって表現される。式構造体２２００のフィールド“ｋｉｎｄ”２２０２はその式の演算子の種類を指定し、またフィールド“ｏｐｅｒａｎｄｓ”２２１０はその演算子の演算が施されるオペランドを含む。
【０２１９】
このサブジェクト関数の解析は、コンピュータプロセス内に於けるそのサブジェクト関数の実行の文脈内で行われるので、このサブジェクト関数のエクスターナルの初期値は未知である。従って、このサブジェクト関数に於ける式は、既知の値に評価しなくてもよい。従って、ステップ２９０２（第２９図）での実行エンジン８０２（第８図）による式の評価により、式の評価により既知の若しくは部分的に既知の値が生成される場合には項目が生成され、そうでない場合にはＮＵＬＬが生成される。後に詳述するように、項目は、「部分的に既知」の値を有し得る。例えば、項目が０でない値を有していることは知ることはできるが、項目の正確な値はまだ知ることができず、この場合その項目の値は「部分的に既知」であるという。ステップ２９０２は論理流れ図２９０２（第３３ａ図、第３３ｂ図、第３３ｃ図、第３３ｄ図、及び第３３ｅ図）に詳しく示されており、後に詳細に説明する。ステップ２９０２（第２９図）から、処理はテストステップ２９０４に進み、ここで実行エンジン８０２（第８図）が、式の評価によりＮＵＬＬでなく項目が生成されたか否か、及びステートマシン８０４によりその項目に演算が施されるか否かを判定する。その式の評価により項目が生成されない場合、若しくはその項目に演算が施されない場合には、処理はテストステップ２９０４（第２９図）から後に説明するステップ２９０８に進む。逆に、その式の評価により項目が生成されその項目に演算が施される場合には、処理はテストステップ２９０４からステップ２９０６に進み、そこでステートマシン８０４（第８図）がその項目に演算を施す。
【０２２０】
評価された式の項目に演算を施すために、ステートマシン８０４は、その項目にエクスターナル及びリソースがそれぞれ関連付けられている場合には、その項目に関連付けられたエクスターナル及びリソースに対して演算を施す。例えば、項目構造体２７００（第２７図）のフィールド“ｅｘｔｅｒｎａｌ”２７０４が、項目構造体によって表現された項目に関連付けられたエクスターナルを表現するエクスターナル状態構造体を指定する。同様に、項目構造体２７００のフィールド“ｒｅｓｏｕｒｃｅ“２７０２が、そのアイテムに関連付けられたリソースを表現するリソース状態構造体を指定する。
【０２２１】
エクスターナルに施される演算には、例えばエクスターナル状態構造体３０００のフィールド“ＤＫ”３００４（第３０図）及び“ＣＰ”３００８の更新がある。このエクスターナル状態構造体３０００は、そのエクスターナルを表現するエクスターナル状態構造体である。フィールド“ＤＫ”３００４の更新は、そのエクスターナルに施される演算に従って、また上述の状態図５００（第５ａ図）に従って行われる。例えば、フィールド“ＤＫ”３００４（第３０図）が状態Ｏを示しており、そのエクスターナルに演算ｍが施される場合、フィールド“ＤＫ”３００４は状態Ｑを示すように更新される。フィールド“ＣＰ”３００８の更新は、状態図４００（第４ａ図）に従って行われる。
【０２２２】
リソースに施される演算には、例えば、リソース状態構造体３１００のフィールド“ｓｔａｔｅ”３１０２（第３１図）及び“ｍｏｄｉｆｉｅｄ”３１０８の更新がある。このリソース状態構造体は、そのリソースを表現するリソース状態構造体である。フィールド“ｓｔａｔｅ”３１０２は、上述の状態図３００（第３Ａ図）に従って更新される。フィールド“ｍｏｄｉｆｉｅｄ”３１０８（第３１図）は、現在行を指定するデータをフィールド“ｍｏｄｉｆｉｅｄ”３１０８に格納することによって更新され、最後にリソースを修正したステートメントを示すようにされる。この現在行とは、コンピュータプログラム６１０（第６図）上のそのサブジェクトステートメントが存在する行を指す。リソースに関連するプログラミングエラーを知らせると共に、最後にリソースを修正したステートメントをユーザに対して示すことによって、サブジェクト関数の開発者がプログラミングエラーを除去する助けとなる。
【０２２３】
後に詳しく説明するが、エクスターナル状態構造体３０００のフィールド“ＤＫ”３００４（第３０図）若しくは“ＣＰ”３００８の更新、またはリソース状態構造体３１００のフィールド“ｓｔａｔｅ”３１０２（第３１図）の更新によって、状態図３００、４００、または５００（第３Ａ図、第４図、及び第５図）に基づくエラーが生じた場合には、このエラーはユーザに通知される。式の評価により生成された項目も、論理流れ図３２００（第３２図）に基づいて状態違反を調べられる。
【０２２４】
テストステップ３２０２（第３２図）においては、ステートマシン８０４（第７図）が項目構造体２７００のフィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４（第２７図）を調べて、項目構造体２７００によって表現された項目が初期化されたか否かを判定する。その項目が初期化されていない場合には、処理はテストステップ３２０２（第３２図）からステップ３２０４に進み、ここでエラーが報告される。論理流れ図３２００の各ステップの実行はステップ２９０６（第２９図）内においてのみ実行されることから、演算が施されるのは論理流れ図３２００（第３２図）における項目に対してである。従って、その項目が初期化される場合、演算の適用で示されるように、初期化される前にその項目が使用され、これがエラーとなる。
【０２２５】
その項目が初期化された場合には、処理はテストステップ３２０２からテストステップ３２０６に進む。テストステップ３２０６においては、ステートマシン８０４（第８図）が、項目構造体２７００のフィールド“ｉｎｖａｌｉｄ ｐｏｉｎｔｅｒ”２７２０（第２７図）を検査することによりその項目が無効ポインタであるか否かを判定するとともに、施される演算と、演算ｉ、即ち間接演算とを比較する。その項目が有効ポインタで、演算ｉが施される場合には、処理はステップ３２０８（第３２図）に進み、そこでエラーが通知される。逆に、その項目が有効ポインタでなく、若しくは演算ｉ以外の演算が施される場合には、処理はステップ３２０６からテストステップ３２１０に進む。
【０２２６】
テストステップ３２１０において、ステートマシン８０４（第７図）は、その項目が、テストステップ３２０６に関して上述したのと同様に無効ポインタであるか否かを判定し、施される演算と演算ｋとを比較する。Ｃ言語の文脈においては、無効ポインタを解放することは、ファイル及び動的に割振られるメモリを管理するのに使用するデータ構造をライブラリ関数が損なうことになり得るために、エラーとなる。ＮＵＬＬポインタを解放することは一般的にはエラーではないが、不手際なプログラム作成方法と一般に考えられ、エラーとして通知される。
【０２２７】
その項目が無効ポインタであり、演算ｋがその項目に施される場合には、処理はステップ３２１２に進み、そこでエラーの通知がなされる。逆にその項目が無効ポインタでないか、若しくは演算ｋ以外の演算が施される場合には、処理は論理流れ図３２００に従って終了する。また、ステップ３２０４、３２０８、及び３２１２の終了後も、処理は論理流れ図３２００に従って終了する。
【０２２８】
従って、ステップ２９０６（第２９図）において、項目及びそれに関連するリソースまたはエクスターナルに演算が施され、何らかのエラーが検出されてそれがユーザに通知される。ステップ２９０６から、処理はステップ２９０８に進む。また、式の評価により生成された項目が存在しない場合、若しくは上述のようにその式に対して施される演算が無い場合は、処理はテストステップ２９０４から直接ステップ２９０８に進む。ステップ２９０８においては、実行エンジン８０２は、式、即ち、サブジェクトステートメントを含んでおり、更に、項目が生成された場合にはその項目を、生成されなかった場合には数値がＮＵＬＬである項目を含んでいる。詳述すると、実行エンジン８０２はサブジェクトステートメントを表現する式構造体２２００のフィールド“ｉｔｅｍ”２２０６（第２２図）に、その項目を指定するポインタを格納する。従って、後に行われるその式の評価においては、単に、その項目がフィールド“ｉｔｅｍ”２２０６が指定する部位に戻されるだけとなり、これによって冗長な処理が回避される。テップ２９０８（第２９図）の後、処理は論理流れ図２９００に従って終了する。
定数
上述のように、論理流れ図２９０２（第３３Ａ図〜第３３Ｅ図）に詳細に示されているステップ２９０２（第２９図）においては、実行エンジン８０２（第８図）は、式における演算子によって規定されている通りに式を処理する。実行エンジン８０２は、演算の型に応じてその式を処理する。テストステップ３３０１（第３３Ａ図）においては、論理流れ図２９０２に従って処理が開始されるが、ここでは実行エンジン８０２（第８図）が、その式が演算子は含んでいないが、代わりに定数を含んでいるか否かを判定する。式構造体２２００（第２２図）がサブジェクトステートメントの式を表現している場合は、実行エンジン８０２（第８図）は、式構造体２２００のフィールド“ｋｉｎｄ”２２０２（第２２図）と、式が定数であることを示すデータとを比較することによってこの判定を行う。定数は、その値がコンピュータプロセスの実行中に変化しない項目である。例えば、式“１０”は、整数であり、その値が常に１０である定数である。
【０２２９】
その式が定数でない場合には、処理は後に述べるテストステップ３３０３（第３３Ａ図）に進む。逆に、式が定数である場合には、処理はテストステップ３３０１からステップ３３０２に進む。ステップ３３０２においては、実行エンジン８０２（第８図）が定数を表現する項目構造体を生成し、その項目構造体を、その定数の値を有するように初期化する。ステップ３３０２の終了後、処理は論理流れ図２９０２及びステップ２９０２（第２９図）に従って終了する。
【０２３０】
変数 
上述のように、その式が定数でない場合には、処理はテストステップ３３０１（第３３Ａ図）からテストステップ３３０３に進む。テストステップ３３０３においては、実行エンジン８０２（第８図）が、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、その式が変数であることを示すデータとを比較することによって、その式が変数であるか否かを判定する。変数である式は、その変数の項目の現項目値に評価される。例えば、サブジェクト関数の以前に処理されたステートメントが、識別子が“ｉ”、即ち型が“ｉｎｔ”、即ち整数である変数“ｉ”である変数を宣言する場合には、式“ｉ”は、変数“ｉ”の項目の現項目値に評価される。式が変数でない場合には、処理は後に説明するテストステップ３３０５（第３３Ａ図）に進む。逆に、その式が変数である場合には、処理はテストステップ３３０３からステップ３３０４に進む。
【０２３１】
ステップ３３０４においては、実行エンジン８０２（第８図）が変数ｉの項目を検索する。式構造体２３００（第２３図）がその式を表現する場合、即ち変数を表現する場合には、（ｉ）フィールド“ｎｕｍ ｏｐｅｒａｎｄｓ”２３０８が、１つのオペランドを指定する値１を有し、（ｉｉ）フィールド“ｏｐｅｒａｎｄｓ”２３１０が宣言構造体２３１０を指定する１つのポインタの配列となる。宣言構造体２３１６のフィールド“ｉｔｅｍ”２３２４は、式２３００の値として検索される。宣言構造体２３１６に関連付けられた項目が存在しない場合には、フィールド“ｉｔｅｍ”２３２４はＮＵＬＬとなる。従って、存在する項目構造体またはＮＵＬＬの何れかが、ステップ３３０４（第３３Ａ図）において取り出されるのである。ステップ３３０４の終了後、処理は論理流れ図２９０２即ちステップ２９０２（第２９図）に従って終了する。
【０２３２】
２項演算子 
上述のように、その式が宣言でない場合には、処理はテストステップ３３０３（第３３Ａ図）からテストステップ３３０５に進む。テストステップ３３０５において、実行エンジン８０２（第８図）は、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と２項演算子を示すデータとを比較することによって、その式の演算子が２項演算子であるか否かを判定する。２項演算子は２つのオペランドに対して演算を施す演算子であって、関係演算子ではない演算子である。例えば、式“ａ＋ｂ”には、加算を指定する２項演算子“＋”が含まれている。関係演算子については後に説明する。
【０２３３】
論理流れ図２９０２（第３３Ａ図）に従って処理される式の演算子が２項演算子でない場合には、処理はテストステップ３３０５からテストステップ３３０９に進む。逆に、式の演算子が２項演算子である場合には、処理はテストステップ３３０５からステップ３３０６に進む。ステップ３３０６においては、左側のオペランド、即ち“ｌｈｓ”が論理流れ図２９００（第２９図）に従って式として評価される。２つのオペランドを有し、式構造体２２００（第２２図）によって表現される式のｌｈｓは、フィールド“ｏｐｅｒａｎｄｓ”２２１０の第１の要素である式構造体よって表現される。このｌｈｓは、論理流れ図２９００（第２９図）に従って評価されるとともに、演算Ｃが施される。論理流れ図２９００に従って演算を施すことについては、前に説明した。従って、論理流れ図２９００に従った式の評価は反復的に行われる。つまり、論理流れ図２９００に従った式の評価により、論理流れ図２９００に従ったその式の部分式（ｓｕｂｅｘｐｒｅｓｓｉｏｎ）の評価も行われることになり得るのである。このような再帰的プログラミングは周知の技術である。
【０２３４】
２項演算子は、左側のオペランドと共に、右側のオペランド、即ち“ｒｈｓ”を有する。例えば、式“（ａ＋ｂ）＊ｃ”は、ｌｈｓ“（ａ＋ｂ）”と、ｒｈｓ“ｃ”とを有する。というのはこの式の中で最も優先順位の高いものは、演算子“＊”、即ち乗算演算子だからである。２つのオペランドを有し、式構造体２２００（第２２図）によって表現される式のｒｈｓは、フィールド“ｏｐｅｒａｎｄｓ”２２１０の第２要素の式構造体によって表現される。ステップ３３０６（第３３Ａ図）において式のｌｈｓが評価された後、処理はステップ３３０７に進み、ここで実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従ってこの式のｒｈｓの評価を行うとともに、演算ｃを施す。演算ｃは、式のｌｈｓ及びｒｈｓの双方に施されるが、これはそれぞれが計算において使用されるからである。このような計算において、式のｌｈｓ若しくはｒｈｓの何れかを不適切に使用している場合は、上述のように演算を施すことによってエラーメッセージが生成される。
【０２３５】
ステップ３３０７（第３３Ａ図）から、処理はステップ３３０８に進み、ここでその式の２項演算子を用いて式の評価が行われる。この式のｌｈｓ及びｒｈｓのデータの型は演算子によって呼び出される演算の型に影響する。Ｃ言語において、特定の演算子が特定の型のオペランドに対して実行する演算の型は、Ｃスタンダードのセクション６．３他に記載されており、周知である。
【０２３６】
式の演算子は、Ｃスタンダードに記載された所定の演算子の適用方法に従って式のオペランドに適用される。例えば、演算子が算術加算演算子（即ち“＋”）である場合には、演算子を２つのオペランドに適用した結果、２つのオペランドの算術和が得られる。第２の例として、演算子が、一方の値が他方より大きいことを表す関係演算子（即ち、“＞”）である場合には、この演算子は２つのオペランド、即ちｌｈｓとｒｈｓとに適用することにより、ｌｈｓの値がｒｈｓの値より大きい場合にはブール値“ｔｒｕｅ（真）”が得られ、逆の場合にはブール値“ｆａｌｓｅ（偽）”が得られる。
【０２３７】
コンピュータプログラム６１０におけるリソースの不適切な使用を検出するリソースチェッカ６０２（第６図）のために、実行エンジン８０２（第８図）によりＣ言語の全ての演算子が適切に適用される必要は必ずしもない。式が実行エンジン８０２（第８図）によって適用され得ない演算子を含む場合、この式はＮＵＬＬに評価され、その式の評価により値が未知の項目が生成されることが示される。しかし、実行エンジン８０２が、できる限り多くのＣ言語の演算子を適用して、リソースチェッカ６０２によって検出されたリソースの不適切な使用を正しく改善し得るのは好ましいことである。
【０２３８】
ステップ３３０８（第３３Ａ図）の後、処理は論理流れ図２９０２、即ちステップ２９０２（第２９図）に従って終了する。
【０２３９】
関係演算子 
上述のように、式の演算子が２項演算子でない場合には、処理はテストステップ３３０５（第３３Ａ図）からテストステップ３３０９に進む。テストステップ３３０９においては、実行エンジン８０２（第８図）が、その式の演算子が関係演算子であるか否かを判定する。関係演算子は２つのオペランド、即ちｌｈｓ及びｒｈｓに対して演算を行い、演算結果として２つのオペランドの値を比較したブール値に対応する数値を有する項目を生成する演算子である。ブール値は、“ｔｒｕｅ”若しくは“ｆａｌｓｅ”の何れかである。関係演算子の具体例には、“＝＝”（等しい）、“＞＝”（大きいか若しくは等しい）、“＜＝”（小さいか若しくは等しい）、及び“！＝”（等しくない）がある。
【０２４０】
この式の演算子が関係演算子でない場合は、処理はテストステップ３３０９（第３３Ａ図）から、後に説明するテストステップ３３１３に進む。逆に式の演算子が関係演算子である場合は、処理はテストステップ３３０９からステップ３３１０に進む。ステップ３３１０においては、実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従って式のｌｈｓを式として評価するとともに、演算ｐを適用する。ステップ３３１０（第３３Ａ図）から、処理はステップ３３１１へ進み、ここで実行エンジン８０２（第８図）が論理流れ図２９００（第２９図）に従って、式のｒｈｓの評価を行うとともに、演算ｐを適用する。演算ｐは式のｌｈｓ及びｒｈｓの双方に適用されるが、これはそれぞれが比較のために使用されるからである。このような比較処理において、式のｌｈｓ若しくはｒｈｓの何れかが不適切に使用されている場合には、上述のように演算が適用されることによりエラーメッセージが生成される。
【０２４１】
処理はステップ３３１１（第３３Ａ図）からステップ３３１２に進み、ここで式の関係演算子が用いられて式の評価が行われる。ステップ３３１２は、前に説明したステップ３３０２に類似している。ステップ３３１２の終了後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２４２】
単項演算子
上述のように、この式の演算子が関係演算子でない場合には、処理はテストステップ３３０９（第３３Ａ図）からテストステップ３３１３に進む。テストステップ３３１３においては、実行エンジン８０２（第８図）が、式の演算子が単項演算子であるか否かを、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、単項演算子を示すデータとを比較することによって判定する。単項演算子は、ただ１つのオペランドを有する演算を特定する演算子である。例えば、式“−ａ”は、ただ１つのオペランド“ａ”と、オペランド“ａ”に対して数値を負にする演算を特定する単項演算子“−”とを有する。式が１つのオペランドを有し、かつ式構造体２２００によって表現されている場合には、その式のただ１つのオペランドが、フィールド“ｏｐｅｒａｎｄｓ”２２１０の第１の要素である式構造体によって表現される。
【０２４３】
式の演算子が単項演算子でない場合には、処理はテストステップ３３１３（第３３Ｂ図）から、後に説明するテストステップ３３１３（第３３Ｂ図）に進む。逆に、式の演算子が単項演算子である場合には、処理はテストステップ３３１３（第３３Ｂ図）からステップ３３１４に進む。ステップ３３１４においては、実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従って式のオペランドを式として評価するとともに、演算ｃを適用する。演算ｃは、式のオペランドに適用されるが、これはこのオペランドが計算において使用されるからである。このような計算において式のオペランドが不適切に使用されている場合には、上述のように、演算を適用することによりエラーメッセージが生成される。
【０２４４】
処理はステップ３３１４（第３３Ｂ図）からステップ３３１５に進み、ここでは式の単項演算子が式の評価のために用いられる。ステップ３３１５は上述のステップ３３０８に類似している。ステップ３３１５の終了後、処理は論理流れ図２９０２、即ちステップ２９０２（第２９図）に従って終了する。
【０２４５】
特定の演算子による処理
上述のように、式の演算子が単項演算子でない場合には、処理はテストステップ３３１３（第３３Ｂ図）からテストステップ３３１７（第３３Ｂ図）に進む。更に上述したように、論理流れ図２９０２における上述のステップでは、式の演算子の型に従って式の処理が行われる。テストステップ３１７及びそれに続くステップにおいて、式の演算子の型がテストステップ３３０１（第３３Ａ図）、３３０３、３３０５、３３０９及び３３１３で判定される演算子の型の中に入っていない場合に、実行エンジン８０２（第８図）が、式の特定の演算子に従って式の処理を行う。
【０２４６】
インクリメント演算子またはデクリメント演算子
ステップ３３１７（第３３Ｂ図）においては、実行エンジン８０２（第８図）が、式の演算子とインクリメント演算子及びデクリメント演算子とを比較する。つまり、式構造体２２００（第２２図）がその式を表現している場合、実行エンジン８０２は、フィールド”ｋｉｎｄ”２２０２（第２２図）と、インクリメント演算子若しくはデクリメント演算子を指定するデータとを比較する。インクリメント演算子若しくはデクリメント演算子は、１つのオペランドに対してそのオペランドを１つずつ増減させる演算を施す。その式の演算子がインクリメント演算子でもデクリメント演算子でもない場合には、処理は、後に説明するテストステップ３３２０（第３３Ｂ図）に進む。逆に、式の演算子がインクリメント演算子またはデクリメント演算子である場合には、処理はテストステップ３３１７からステップ３３１８に進む。
【０２４７】
ステップ３３１８においては、実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従ってそのオペランドを評価し、演算ｃを適用する。演算ｃを適用するのは、このオペランドが計算において使用されるからである。上述のように、演算ｃをそのオペランドに対して適用することにより生じた何らかのエラーは検出され通知される。
【０２４８】
処理はステップ３３１８（第３３Ｂ図）からステップ３３１９に進み、ここでは式のインクリメント演算子またはデクリメント演算子が用いられて、その式の評価が行われる。ステップ３３１９は、上述のステップ３３０８（第３３Ａ図）に類似している。ステップ３３１９（第３３Ｂ図）の終了後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２４９】
“Ｎｏｔ”演算子 
上述のように、式の演算子がインクリメント演算子でもデクリメント演算子でもない場合には、処理はテストステップ３３１７（第３３Ｂ図）からテストステップ３３２０に進む。テストステップ３３２０においては、実行エンジン８０２（第８図）が、その式を表す式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と“Ｎｏｔ”演算子を指定するデータとを比較することによって、Ｃ言語の“Ｎｏｔ”演算子と式の演算子とを比較する。“Ｎｏｔ”演算子は、ただ１つのオペランドに対して演算を施し、そのオペランド自体をブール値項目として取り扱って、オペランドの論理的否定のブール値に対応する値を有する項目を生成する。ブール値項目は、真若しくは偽の何れかのブール値に対応する値を有する項目である。
【０２５０】
その式の演算子が“Ｎｏｔ”演算子でない場合は、処理はテストステップ３３２０（第３３Ｂ図）からテストステップ３３２３に進む。逆に式の演算子が“Ｎｏｔ”演算子である場合は、処理はテストステップ３３２０から３３２１に進む。ステップ３３２１においては、実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従ってオペランドの評価を行うとともに、演算ｐを施す。演算ｐを施すのは、このオペランドは真理値計算を行うのに使用されるからである。上述のように、オペランドに演算ｐを適用することによって生じたエラーは全て通知される。
【０２５１】
処理はステップ３３２１（第３３Ｂ図）からステップ３３２２に進み、ここで“Ｎｏｔ”演算子がその式を評価するのに用いられる。ステップ３３２２は、前に説明したステップ３３０８（第３３Ａ図）に類似している。ステップ３３２２（第３３Ｂ図）の終了後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２５２】
“Ａｎｄ”演算子及び“Ｏｒ”演算子 
上述のように、式の演算子が“ＮＯｔ”演算子でない場合には、処理はテストステップ３３２０（第３３Ｂ図）からテストステップ３３２３に進む。テストステップ３３２３において、実行エンジン８０２（第８図）は、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、“Ａｎｄ”演算子及び“Ｏｒ”演算子を指定するデータとを比較することによって、Ｃ言語の“Ａｎｄ”演算子及び“Ｏｒ”演算子と式の演算子との比較を行う。この“Ａｎｄ”演算子及び“Ｏｒ”演算子は２つのオペランド、即ちｌｈｓ及びｒｈｓに演算を施し、そのオペランドをブール値項目として取り扱ってそのブール値の論理積及び論理和のブール値を有する項目を生成する。
【０２５３】
式の演算子が“Ａｎｄ”演算子でも“Ｏｒ”演算子でもない場合には、処理はテストステップ３３２３（第３３Ｂ図）からテストステップ３３２７に進む。逆に、式の演算子が“Ａｎｄ”演算子または“Ｏｒ”演算子である場合には、処理はテストステップ３３２３からステップ３３２４に進む。
【０２５４】
ステップ３３２４においては、実行エンジン８０２（第８図）が論理流れ図２９００（第２９図）に従って、その式のｌｈｓをその式そのものとして評価するとともに、演算ｐを施す。ステップ３３２４（第３３Ｂ図）から、処理はステップ３３２５に進み、ここでは実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従って式のｒｈｓの評価を行うと共に、演算ｐを適用する。演算ｐは式のｌｈｓ及びｒｈｓの双方に施されるが、これはそれぞれが真理値計算に用いられるからである。このような真理値計算において式のｌｈｓまたはｒｈｓの何れかを不適切に用いた場合には、上述のように演算ｐを適用することによってエラーメッセージが生成される。
【０２５５】
処理はステップ３３２５（第３３Ｂ図）からステップ３３２６に進み、ここで式の“Ａｎｄ”演算子または“Ｏｒ”演算子が用いられて、式の評価が行われる。ステップ３３２６は、前述のステップ３３０８（第３３Ａ図）に類似している。ステップ３３２６（第３３Ｂ図）の終了後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２５６】
複合演算子 
上述のように、式の演算子が“Ａｎｄ”演算子でも“Ｏｒ”演算子でもない場合には、処理はテストステップ３３２３（第３３Ｂ図）からテストステップ３３２７に進む。テストステップ３３２７において、実行エンジン８０２（第８図）は、その式の演算子が複合演算子（ｃｏｍｐｏｕｎｄ  ｏｐｅｒａｔｏｒ）であるか否かを、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、複合演算子を指定するデータとを比較することによって判定する。Ｃ言語においては、複合演算子、即ちカンマ（“，”）は、２つのオペランド、即ち式のｌｈｓ及びｒｈｓに対して演算を施し、演算結果としてｒｈｓを評価した値を有する項目を生成する。つまり、２つのオペランドは個別に評価され、式のｒｈｓを評価した値が式の値になるのである。
【０２５７】
式の演算子が複合演算子でない場合には、処理はテストステップ３３２７（第３３Ｃ図）からテストステップ３３３０に進む。逆に、式の演算子が複合演算子である場合には、処理はテストステップ３３２７からステップ３３２８に進む。ステップ３３２８においては、実行エンジン８０２（第８図）が論理流れ図２００（第２９図）に従って式のｌｈｓをその式として評価し、また演算の適用は行わない。ステップ３３２８（第３３Ｃ図）から処理はステップ３３２９に進みここでは実行エンジン８０２（第８図）が論理流れ図２９００（第２９図）に従って式のｒｈｓを評価する。論理流れ図２９００に従って、複合演算子を含む式を評価する場合に施される演算は、ステップ３３２９（第３３Ｃ図）においてｒｈｓを評価するときにｒｈｓに施される演算と類似したものである。式のｒｈｓの評価によって生成される項目は、その式そのものの項目として戻される。
【０２５８】
ステップ３３２９（第３３Ｃ図）の終了後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２５９】
間接演算子
上述のように、式の演算子が複合演算子でない場合には、処理はテストステップ３３２７（第３３Ｃ図）からテストステップ３３３０に進む。テストステップ３３３０においては、実行エンジン８０２（第８図）がその式の演算子が間接演算子（ｉｎｄｉｒｅｃｔｉｏｎ  ｏｐｅｒａｔｏｒ）であるか否かを、その式を表す式構造体のフィールド”ｋｉｎｄ”２２０２（第２２図）と間接演算子を指定するデータとを比較することによって判定する。Ｃ言語においては、間接演算子（即ち“＊”）は１つのオペランドに対して演算を施し、演算結果としてメモリ、即ちメモリ１０４（第１図）内のそのオペランドによって指定されたアドレスに格納された値を有する項目を生成する。例えば、式“＊ａ”は、メモリ内のアドレス“ａ”に格納された値を有する項目に対して評価を行う。間接演算子は、配列の要素を参照するためにも使用され得る。例えば、宣言“ｉｎｔ ａｒｒａｙ［１０］”によって規定された配列の第２要素は、“ａｒｒａｙ［１］”または“＊（ａｒｒａｙ＋１）”の何れかによって特定され得る。後者の式はその配列の要素のサイズのアレイの始まる点を０としたときの相対位置（オフセット）１に格納された値、即ち配列の第２要素の値を参照するものである。
【０２６０】
その式の演算子が間接演算子でない場合には、処理はテストステップ３３３０（第３３Ｃ図）からテストステップ３３３５に進む。逆に、その式の演算子が間接演算子である場合には、処理はテストステップ３３３０からテストステップ３３３１に進む。
【０２６１】
テストステップ３３３１においては、実行エンジン８０２（第８図）がそのオペランドが配列であるか否かを判定する。式構造体２２２０（第２２図）がそのオペランドを表現している場合には、フィールド“ｔｙｐｅ”２２０４（第２２図）がそのオペランドの型を指定する型構造体を指定する。例えば、型構造体１６１２（第１７図）が式構造体２２２０のフィールド“ｔｙｐｅ”２２０４（第２２図）によって指定されている場合には、実行エンジン８０２（第８図）がそのオペランドが配列であるか否かを、フィールド“ｋｉｎｄ”１７０２（第１７図）と配列を指定するデータとを比較することによって判定する。
【０２６２】
そのオペランドが配列である場合には、処理はテストステップ３３３１（第３３Ｃ図）からステップ３３３２に進み、ここで実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従って、そのオペランドをその式として評価し、かつ演算は適用しないが、その演算子を、配列の間接アドレス指定手段として、即ち上述の“＊（ａｒｒａｙ＋１）”の型式の配列の１つの要素の参照要素として取り扱う。逆に、オペランドが配列でない場合には、処理はテストステップ３３３１（第３３Ｃ図）からステップ３３３３に進み、ここでは実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従ってその式のオペランドを評価するとともに、演算ｉを適用し、かつその演算子を間接アドレスを指定するポインタ、即ち上述の式“＊ａ”のためのものとして取り扱う。
【０２６３】
処理はステップ３３３２（第３３Ｃ図）またはステップ３３３３の何れかから、ステップ３３３４に進み、ここでは実行エンジン８０２（第８図）が、そのオペランドをデリファレンスする。オペランドのデリファレンスにおいて、その式の評価により、オペランドが指定する項目が生成される。オペランドが項目を指定していない場合には、式はＮＵＬＬに評価される。ステップ３３３４（第３３Ｃ図）の終了後、論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って処理は終了する。
【０２６４】
コンポーネント参照演算子
上述のように、式の演算子が間接演算子でない場合には、処理はテストステップ３３３０（第３３Ｃ図）からテストステップ３３３５に進む。テストステップ３３３５においては、実行エンジン８０２（第８図）が、その式の演算子がコンポーネント参照演算子であるか否かを、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、コンポーネント参照演算子を指定するデータとを比較することによって判定する。Ｃ言語においては、コンポーネント参照演算子（即ち、“．”または“−＞”）は、２つのオペランド、即ち式のｌｈｓ及びｒｈｓに対して演算を施し、演算結果としてｒｈｓによって特定されたｌｈｓのフィールド項目を生成する。例えば、宣言“ｓｔｒｕｃｔ｛ｉｎｔ  ａ；ｃｈａｒ  ＊ｂ｝ｃ，＊ｄ”が宣言しているのは、項目“ｃ”及び第２項目に対するポインタ“ｄ”であって、それぞれが、データの型“ｉｎｔ”、即ち整数の第１フィールド項目“ａ”及びデータの型が”ｃｈａｒ”、即ち文字であるデータを指定する第２フィールド項目“ｂ”を有することを表している。式“ｃ．ａ”は、項目“ｃ”の整数フィールド項目に評価される。同様に、式“ｄ−＞ａ”は、ポインタ“ｄ”が指定する項目の整数フィールド項目に評価される。
【０２６５】
式の演算子がコンポーネント参照演算子でない場合には、処理はテストステップ３３３５（第３３Ｃ図）からテストステップ３３３８（第３３Ｄ図）に進む。逆に式の演算子がコンポーネント参照演算子である場合には、処理はテストステップ３３３５（第３３Ｃ図）からステップ３３３６に進む。
【０２６６】
ステップ３３３６においては、実行エンジン８０２（第８図）が論理流れ図２９００（第２９図）に従って式のｌｈｓを評価し、また演算は施されない。ステップ３３３６（第３３Ｃ図）から、処理はステップ３３３７に進み、ここで実行エンジン８０２（第８図）が、式のｒｈｓによって指定されるフィールドを検索する。ステップ３３３７の終了後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２６７】
配列参照演算子
上述のように、式の演算子がコンポーネント演算子でない場合には、処理はテストステップ３３３５（第３３Ｃ図）からテストステップ３３３８（第３３Ｄ図）に進む。テストステップ３３３８においては、実行エンジン８０２（第８図）が式の演算子が配列参照演算子であるか否かを、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、配列参照演算子を指定するデータとの比較を行うことによって判定する。Ｃ言語においては、配列参照演算子（即ち、“  ［］  ”）は２つのオペランド、即ちその式のｌｈｓ及びｒｈｓに対して演算を施し、演算結果として、ｒｈｓにより特定されるｌｈｓの配列の要素を生成する。例えば、宣言“ｉｎｔ ａｒｒａｙ［１０］”が宣言するのは１０個の整数の配列である。式“ａｒｒａｙ［ｂ］”は、配列“ａｒｒａｙ”の、項目“ｂ”によって指定される位置に存在する整数の要素に評価される。項目“ｂ”、即ちｒｈｓは指標（ｉｎｄｅｘ）と称されることもある。
【０２６８】
Ｃ言語においては、配列参照演算子は、非配列ポインタからのオフセットを参照するためにも使用されうる。例えば、“ｄａｔｕｍ”が型“ｉｎｔ”である変数である場合、式“ｄａｔｕｍ［２］”は、メモリ１０４（第１図）の、変数“ｄａｔｕｍ”を表現する項目から２メモリ位置だけオフセットした位置に格納されたデータに評価される。２メモリ位置は、変数“ｄａｔｕｍ”の型、即ちデータの型“ｉｎｔ”の変数２つ分の長さに等しい。上述のように、Ｃ言語の文脈においては、“ａｒｒａｙ［ｉ］”及び“＊（ａｒｒａｙ＋ｉ）”は、等価な式である（Ｃスタンダードのセクション６．３、２．１参照）。
【０２６９】
その式の演算子が配列参照演算子でない場合は、処理はテストステップ３３３８（第３３Ｄ図）からテストステップ３３４４に進む。逆に、この式の演算子が配列参照演算子である場合には、処理はテストステップ３３３８からステップ３３３９に進む。
【０２７０】
ステップ３３３９において、実行エンジン（第８図）は、論理流れ図２９００（第２９図）に従ってその式の指標を評価し、また演算ｃを施す。演算ｃを施すのは、この指標は計算に使用されるからである。ステップ３３３９（第３３Ｄ図）から、処理はテストステップ３３４０に進み、ここで実行エンジン８０２（第８図）が、ｌｈｓが配列であるか否かを、テストステップ３３３１（第３３Ｃ図）に関連して前に説明した方法で判定する。ｌｈｓが配列である場合には、処理はテストステップ３３４０（第３３Ｄ図）からステップ３３４１に進み、ここで実行エンジン８０２（第８図）が、論理流れ図２９００（第２図）に従ってその式のｒｈｓを指標として評価する。このとき演算は施されない。逆に、ｌｈｓが配列でない場合には、処理はテストステップ３３４０（第３３Ｄ図）からステップ３３４２に進み、ここで実行エンジン８０２（第８図）が論理流れ図２９００（第２９図）に従ってその式のｒｈｓをポインタとして評価し、かつ演算ｉを施す。
【０２７１】
処理はステップ３３４１（第３３Ｄ図）若しくはステップ３３４２の何れかから、ステップ３３４３に進み、ここで実行エンジン８０２（第８図）が、ｌｈｓによって特定された配列の、ｒｈｓによって指定された要素を検索する。ステップ３３４３（第３３Ｄ図）の終了後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２７２】
アドレス演算子
上述のように、その式の演算子が配列演算子でない場合には、処理はテストステップ３３３８（第３３Ｄ図）からテストステップ３３４４に進む。テストステップ３３４４においては、実行エンジン８０２（第８図）が、その式の演算子がアドレス演算子であるか否かを、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２と、アドレス演算子を指定するデータとを比較することによって判定する。Ｃ言語においては、アドレス演算子（即ち“＆”）は、１つのオペランドに対して演算を施し、演算結果としてオペランドのアドレスがその値である項目を生成する。例えば、式“＆ａ”は、メモリ、即ちメモリ１０４内の、項目“ａ”が格納されているアドレスをその値とする項目に評価される。
【０２７３】
その式の演算子がアドレス演算子でない場合には、処理はテストステップ３３４４（第３３Ｄ図）からテストステップ３３４７に進む。逆に、その式の演算子がアドレス演算子である場合には、処理はテストステップ３３４４からステップ３３４５に進む。
【０２７４】
ステップ３３４５においては、実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従ってオペランドの評価を行い、このとき他の演算は施されない。ステップ３３４５（第３３Ｄ図）から、処理はテストステップ３３４６に進み、ここでこのアドレス演算子はその式を評価するのに使用される。つまり、オペランドのアドレスが決定されるのである。ステップ３３４６は、前に説明したステップ３３０８（第３３Ａ図）に類似している。ステップ３３４６（第３３Ｄ図）が終了した後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２７５】
関数の呼出し
上述のように、式の演算子がアドレス演算子でない場合には、処理はテストステップ３３４４（第３３Ｄ図）からテストステップ３３４７に進む。テストステップ３３４７においては、実行エンジン８０２（第８図）が、その式の演算子が関数の呼出しであるか否かを、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、関数の呼出しを指定するデータとを比較することによって判定する。Ｃ言語においては、関数演算子（即ち“  （）  ”）は、関数の呼出しを意味する。関数の呼出しは、その関数の戻り値項目（ｒｅｔｕｒｎｅｄ  ｉｔｅｍ）に評価される。例えば、式“ａｂｃ  （）  ”は、識別子が“ａｂｃ”である関数の実行の呼出しを行う。同様に、式“ｘｙｚ（ｄ，ｅ，ｆ）”は、その識別子が“ｘｙｚ”である、パラメータとして項目ｄ，ｅ，及びｆが与えられている関数を呼び出す。
【０２７６】
式の演算子が関数の呼出しでない場合には、処理はテストステップ３３４７（第３３Ｅ図）からテストステップ３３５３に進む。逆に、式の演算子が関数の呼出しである場合には、処理はテストステップ３３４７からループステップ３３４８に進む。ループステップ３３４８、ステップ３３４９、及びＮＥＸＴステップ３３５０は、各パラメータの評価が行われるループを形成する。ステップ３３４９において、実行エンジン８０２（第８図）は、論理流れ図２９００（第２９図）に従ってパラメータの評価を行い、また演算は施さない。式構造体２２００（第２２図）がその式を表現している場合、即ち関数の呼出しを表現している場合には、（ｉ）フィールド“ｎｕｍ ｏｐｅｒａｎｄｓ”２２０８が呼び出された関数のパラメータの数をオペランドの数として特定し、（ｉｉ）フィールド“ｏｐｅｒａｎｄｓ”２２１０は式構造体の配列であり、この式構造体の各要素は呼び出された関数のパラメータを表現する式構造体である。
【０２７７】
各パラメータの評価は、フィールド“ｏｐｅｒａｎｄｓ”２２１０の各要素を評価することによって行われる。呼び出された関数のパラメータを表現する項目の配列は、ループステップ３３４８、ステップ３３４９、及びＮＥＸＴステップ３３５０によって形成されたループにおいて構成され、後に（第４６図に関連して）詳しく説明するように、ステップ３３５２において呼び出された関数の実行をエミュレートするのに用いられる。
【０２７８】
ひとたび呼出される関数の各パラメータが評価されると、処理はループステップ３３４８（第３３Ｅ図）からステップ３３５１に進む。ステップ３３５１においては、実行エンジン８０２（第８図）が、呼び出される関数のエクスターナルにおける実行の効果を表現する関数モデル構造体を抽出する。関数モデル構造体は、第１１図〜第１３図に関連して以前に説明してある。ステップ３３５１（第３３Ｅ図）から、処理はステップ３３５２に進み、ここで実行エンジン８０２（第８図）が、呼び出される関数の実行のエミュレートについては後に詳しく説明する。ここで簡単に説明すると呼び出される関数のエミュレートは、上述の関数モデル（３）、（４）、及び（５）から形成される関数モデル構造体のような関数モデル構造体において特定された演算を適用することによって行われる。この呼び出された関数に対応する関数モデル構造体は、呼び出される関数のエクスターナルにおける実行の効果を表現する演算を特定する。ステップ３３５２（第３３Ｅ図）の終了後、処理は、論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２７９】
代入
上述のように、その式の演算子が関数の呼出しでない場合には、処理はテストステップ３３４７（第３３Ｅ図）からテストステップ３３５３に進む。テストステップ３３５３においては、実行エンジン８０２（第８図）が、その関数の演算子が代入演算子であるか否かをその式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、代入演算子を指定するデータとを比較することによって判定する。Ｃ言語においては、代入演算子（即ち“＝”）が、２つのオペランド、即ちｌｈｓ及びｒｈｓに対して演算を施し、ｒｈｓの値をｌｈｓに移す。代入は、移された値を有する項目に評価される。例えば、式“ａ＝ｂ”は、項目“ｂ”の値を項目“ａ”に移し、項目“ａ”の新たな値を有する項目に評価される。
【０２８０】
式の演算子が代入演算子でない場合には、処理は論理流れ図２９０２（第３３Ａ図〜第３３Ｅ図）に従って、即ちステップ２９０２（第２９図）に従って終了し、論理流れ図２９０２に従って処理された式はＮＵＬＬ値に評価される。ＮＵＬＬ値は、有効値を持たない状態を示すために用いられる。
【０２８１】
実行エンジン８０２（第８図）が、コンピュータプロセス内におけるサブジェクト関数の実行の文脈を欠いた式を適切に評価することができない場合には、式はＮＵＬＬ値に評価される。最も重要なことは、式の適切な評価ではなく、エクスターナル及びリソースのそれぞれの状態変化を追跡することである。この状態の正確な追跡を確実に行うために、式の評価はできる限り多く行われる。
【０２８２】
逆にテストステップ３３５３（第３３Ｅ図）において、式の演算子が代入演算子である場合には、処理はステップ３３５３に進む。ステップ３３５３においては、実行エンジン８０２（第８図）は、論理流れ図２９００（第２９図）に従って式のｌｈｓを式そのものとして評価し、また演算は施さない。ステップ３３５４（第３３Ｅ図）から、処理はステップ３３５５に進み、ここでは実行エンジン８０２（第８図）が論理流れ図２９００（第２９図）に従って式のｒｈｓの評価を行い、また演算は施さない。処理はステップ３３５５（第３３Ｅ図）からステップ３３５６に進み、ここでは実行エンジン８０２（第８図）が、式のｒｈｓの評価によって生成された項目の値を、式のｌｈｓの評価によって生成された項目に代入する。ステップ３３５６については、後に論理流れ図３３５６（第４５図）に関連して詳細に説明する。ステップ３３５６（第３３Ｅ図）の終了後、処理は論理流れ図２９０２に従って、即ちステップ２９０２（第２９図）に従って終了する。
【０２８３】
従って、ステップ２８０４（第２８図）においては、実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従って式の評価を行う。式の評価においては、実行エンジン８０２（第８図）が、前に詳しく説明したように、必要な場合にはエクスターナル及びリソースのそれぞれの状態に対して演算を施す。前に説明したように、式の評価に際しての演算の適用によって生ずる何らかの状態違反は、コンピュータプログラム６１０におけるエラーとしてユーザに通知される。
【０２８４】
宣言の処理 
上述のように、宣言ステートメントはステップ２８０８（第２８図）において処理されるが、このステップ２８０８は論理流れ図２８０８（第３４図）において詳細に示されている。宣言ステートメントは、そのフィールド“ｐｏｉｎｔｅｒｓ”が２つのポインタの配列であるステートメント構造体１４１６（第２１図）のようなステートメント構造体によって表現される。上述のように、宣言ステートメントを表現するステートメント構造体の第１ポインタは宣言構造体１５０６（第１６図）のような宣言構造体を指定し、第２ポインタは宣言された項目の初期値を定める式構造体を指定する。
【０２８５】
論理流れ図２８０８（第３４図）に従った処理は、ステップ３４０２から開始され、このステップでは、項目構造体２７００（第２７図）のような項目構造体が、宣言された項目に対して生成される。生成された項目構造体を指定するポインタは、宣言構造体１５０６のフィールド“ｉｔｅｍ”１６０８（第１６図）に格納される。フィールド“ｔｙｐｅ ｃｏｄｅ”２７１２（第２７図）は、宣言において指定されたデータの型に従って、即ち宣言構造体１５０６のフィールド“ｔｙｐｅ”１６０６（第１６図）に従って設定される。フィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４（第２７図）は、その項目が初期化されていないことを示すように設定される。
【０２８６】
処理はステップ３４０２（第３４図）からテストステップ３４０４に進み、ここでは実行エンジン８０２（第８図）が、その宣言ステートメントが、宣言された項目のための初期値を特定しているか否か、即ちその宣言ステートメントを表現するステートメント構造体の第２ポインタが、式構造体を指定しているか、若しくはＮＵＬＬ値であるか判定する。その宣言ステートメントが初期値を特定していない場合、即ち第２ポインタがＮＵＬＬである場合には、処理は論理流れ図２８０８（第３４図）に従って終了する。逆にその宣言ステートメントが初期値を特定する式を含んでいる場合、即ち第２ポインタが式ステートメントを指定している場合には、処理はテストステップ３４０４からステップ３４０６に進む。ステップ３４０６において、実行エンジン８０２（第８図）が、前に詳しく説明したように、論理流れ図２９００（第２９図）に従って式構造体によって表現された式を評価する。論理流れ図２９００に従って式を評価するときに、演算は施されない。処理はステップ３４０６（第３４図）からステップ３４０８に進み、そこでは式が評価される項目が宣言された項目に代入される。更に、宣言された項目を表現する項目構造体のフィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４（第２７図）が、その項目が初期化されたことを示すように設定される。
【０２８７】
ステップ３４０８（第３４図）の終了後、処理は論理流れ図２８０８に従って、ステップ２８０８（第２８図）に従って終了する。従ってステップ２８０８においては、新たな項目が生成され、初期値が指定される場合にはその新たな項目がその初期値を有するように初期化される。
【０２８８】
決定処理 
上述のように、実行エンジン８０２（第８図）は、ステップ２８１２（第２８図）において決定処理、即ち“ｉｆ”ステートメントの処理を行う。ここでステップ２８１２は論理流れ図２８１２（第３５図）に詳細に示されている。処理はステップ３５０２から開始されるが、ここでは実行エンジン８０２（第８図）が、論理流れ図２９００（第２９図）に従って“ｉｆ”ステートメントの述語である式の評価を行い、演算ｐを適用する。Ｃ言語においては、“ｉｆ”ステートメントは述語及び第２ステートメントを含む。
【０２８９】
この述語は、第２ステートメントが実行されるか否かを決定するブール値項目に評価される式である。例えば、ステートメント“ｉｆ（ａ＝＝ｂ）ｃｉ１；”は、述語、即ち式“ａ＝＝ｂ”が、その値が“ｔｒｕｅ”であるブール値項目に評価される場合、即ち項目“ａ”が項目“ｂ”と等しい場合にのみ、第２ステートメント、即ちステートメント“ｃｉ１”が実行されるという処理を特定する。項目“ａ”が項目“ｂ”と等しくない場合には、ステートメント“ｃｉ１”は実行されない。
【０２９０】
処理はステップ３５０２（第３５図）からテストステップ３５０４に進み、ここでは実行エンジン８０２（第８図）が、述語が既知の値を有する項目に評価されたか否かを判定する。実行エンジン８０２はこの判定を、述語の評価によって生成された項目とＮＵＬＬとを比較することによって行う。上述のように、実行エンジン８０２が式の評価を適切に行うことができない場合には、式はＮＵＬＬに評価される。述語が既知の値を有する項目に、即ちＮＵＬＬ以外の値に評価された場合には、処理はテストステップ３５０４（第３５図）からテストステップ３５０６に進む。
【０２９１】
テストステップ３５０６においては、実行エンジン８０２（第８図）が、述語の評価によって生成された項目の値とブール値“ｔｒｕｅ”とを比較する。述語が、“ｔｒｕｅ”のブール値を有するブール値項目に評価された場合には、処理はステップ３５０８（第３５図）に進み、そこで実行エンジン８０２（第８図）が、“ｉｆ”ステートメントの第２ステートメントを実行する。第２ステートメントは、前に詳しく説明したように論理流れ図２８００（第２８図）に従って処理される。従って、論理流れ図２８００は再帰的に実行される。
【０２９２】
一方、述語がブール値“ｆａｌｓｅ”に評価された場合には、処理はテストステップ３５０６（第２８図）からステップ３５１０に進み、そこで実行エンジン８０２（第８図）が、後に詳述する制御レコードに、“ｅｌｓｅ”条件を示すデータを格納する。制御レコードは、後に詳しく述べるように、サブジェクト関数の実行のエミュレーションにおいて適切な制御の流れを与えるために用いられる。ステップ３５０８（第３５図）またはステップ３５１０の何れかが終了した後、処理は論理流れ図２８１２に従って、即ちステップ２８１２（第２８図）に従って終了する。
【０２９３】
上述のように、実行エンジン８０２（第８図）は、テストステップ３５０４（第３５図）において、述語が既知の値に評価された否かを判定する。述語が既知の値に評価されない場合、即ちＮＵＬＬに評価されるか、未知の値を有する項目に評価された場合には、処理はテストステップ３５０４からステップ３５１２に進む。ステップ３５１２において、実行エンジン８０２（第８図）はその述語が評価されうるブール値をシミュレートする。一実施例においては、実行エンジン８１２（第８図）は、ブール値“ｔｒｕｅ”またはブール値“ｆａｌｓｅ”からランダムに選択を行う。ステップ３５１２（第３５図）から、処理はステップ３５１４に進む。
【０２９４】
ステップ３５１４において、実行エンジン８０２（第８図）は、ステップ３５１２（第３５図）において選択されたブール値から、できる限り多くの推測を行う。例えば、述語が式“ａ＆＆ｂ”（即ちａ  ＡＮＤ  ｂ）であり、述語がブール値“ｔｒｕｅ”を有するように選択された場合、実行エンジン８０２（第８図）は、項目“ａ”と項目“ｂ”の双方がブール値“ｔｒｕｅ”を有するものと推測する。ａ及びｂの双方が“ｔｒｕｅ”の場合にのみ式“ａ＆＆ｂ”が“ｔｒｕｅ”と評価されることから、この推測がなされ得るのである。ステップ３５１４（第３５図）は、論理流れ図３６００（第３６図）に従った述語の処理を含んでいる。論理流れ図３６００の各ステップにおいては、その式の評価により得られることが推定される推定ブール値から、式における値を推測する。
“Ｎｏｔ”演算子 
論理流れ図３６００に従った処理はテストステップ３６０２から開始されるが、このステップでは実行エンジン８０２（第８図）が、式の演算値と、“ＮＯｔ”演算子との比較を行う、即ちその式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、“Ｎｏｔ”演算子を特定するデータとの比較を行う。“Ｎｏｔ”演算子（即ち“！”）は、１つのオペランドに対して演算を施し、演算結果としてそのオペランドの値の論理的否定をその値とする項目を生成する。例えば、式“！ａ”は、オペランド、即ち式“ａ”の否定である。
【０２９５】
式の演算子が“Ｎｏｔ”演算子でない場合には、処理はテストステップ３６０２（第３６図）から、以下に説明するテストステップ３６０６に進む。逆に、式の演算子が“Ｎｏｔ”演算子である場合には、処理はテストステップ３６０２からステップ３６０６に進む。ステップ３６０６においては、実行エンジン８０２（第８図）が論理流れ図３６００（第３６図）に従ってオペランドを処理し、推定値の論理的否定を推定する。例えば、式“！（ａ＆＆ｂ）”、即ちＮＯＴ（ａ  ＡＮＤ  ｂ）が、“ｔｒｕｅ”と推定された場合には、式“ａ＆＆ｂ”が“ｆａｌｓｅ”と推定される。即ち、論理流れ図３６００に従った処理は再帰的に実行される。ステップ３６０４の終了後、処理は論理流れ図３６００に従って終了する。
【０２９６】
“Ａｎｄ”演算子または“Ｏｒ”演算子 
上述のように、式の演算子が“Ｎｏｔ”演算子でない場合には、処理はテストステップ３６０２（第３６図）からテストステップ３６０６に進む。テストステップ３６０６においては、実行エンジン８０２（第８図）が、式の演算子と“Ａｎｄ”演算子及び“Ｏｒ”演算子とを比較する。つまり、実行エンジン８０２は、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と“Ａｎｄ”演算子及び“Ｏｒ”演算子を指定するデータとの比較を行うのである。上述のように、“Ａｎｄ”演算子及び“Ｏｒ”演算子（即ち“＆＆”及び“｜｜”）は、２つのオペランド、即ちｌｈｓ及びｒｈｓに演算を施し、演算結果として２つのオペランドの値の論理積及び論理和をその値とする項目を生成する。式の演算子が“Ａｎｄ”演算子でも“Ｏｒ”演算子でもない場合には、処理はテストステップ３６０６（第３６図）から、後に説明するテストステップ３６１０に進む。逆に、式の演算子が“Ａｎｄ”演算子、若しくは“Ｏｒ”演算子の何れかである場合には、処理はテストステップ３６０６からステップ３６０８に進む。
【０２９７】
ステップ３６０８はテストステップ３７０２から処理が開始される論理流れ図３６０８（第３７図）に詳細に示されている。テストステップ３７０２においては、実行エンジン８０２（第８図）が、式の演算子と、“Ａｎｄ”演算子との比較を行い、更にその式が評価されたときに推定されるブール値、即ち推定値と、ブール値“ｔｒｕｅ”とを比較する。演算子が“Ａｎｄ”演算子でない場合、若しくは推定値が“ｔｒｕｅ”でない場合には、処理はテストステップ３７０２から、後に説明するテストステップ３７０６に進む。逆に演算子が“Ａｎｄ”演算子である場合、及び推定値が“ｔｒｕｅ”である場合には、処理はテストステップ３７０２からステップ３７０４に進む。
【０２９８】
ステップ３７０４においては、各オペランド、即ち式のｌｈｓ及びｒｈｓのそれぞれが、論理流れ図３６００（第３６図）に従って推定値“ｔｒｕｅ”と共に１つの式として処理される。このような、ｌｈｓ及びｒｈｓの双方が“ｔｒｕｅ”であるという推測は適切である。というのは、式“ａ＆＆ｂ”が“ｔｒｕｅ”である場合には、両オペランド、即ち式“ａ”及び“ｂ”が共に“ｔｒｕｅ”でなければならないからである。上述のように、Ｃ言語の演算子“＆＆”は論理積演算を意味する。ステップ３７０４（第３７図）の終了後、処理は論理流れ図３６０８に従って、即ちステップ３６０８（第３６図）に従って終了する。
【０２９９】
上述のように、演算子が“Ａｎｄ”演算子でなく、若しくは推定値が“ｔｒｕｅ”でない場合には、処理はテストステップ３７０２（第３７図）からテストステップ３７０６に進む。テストステップ３７０６においては、実行エンジン８０２（第８図）が、式の演算子と“Ｏｒ”演算子との比較を行い、かつ推定値とブール値“ｆａｌｓｅ”との比較を行う。式の演算子が“Ｏｒ”演算子でなく、若しくは推定値が“ｆａｌｓｅ”でない場合には、処理は論理流れ図３６０８に従って、即ちステップ３６０８（第３６図）に従って終了する。逆に、演算子が“Ｏｒ”演算子であり、推定値が“ｆａｌｓｅ”である場合には、処理はテストステップ３７０６（第３７図）からステップ３７０８に進む。
【０３００】
ステップ３７０８において、各オペランド、即ち式のｌｈｓ及びｒｈｓのそれぞれが、論理流れ図３６００（第３６図）に従って、推定値“ｆａｌｓｅ”と共に１つの式として処理される。このようなｌｈｓ及びｒｈｓが“ｆａｌｓｅ”であるという推測は適切である。というのは、表現“ａ｜｜ｂ”が“ｆａｌｓｅ”である場合には、両オペランド、即ち“ａ”及び“ｂ”が共に“ｆａｌｓｅ”でなければならないからである。上述のように、Ｃ言語の演算子“｜｜”は、論理和演算を意味する。ステップ３７０８（第３７図）の終了後、処理は論理流れ図３６０８に従って、即ちステップ３６０８（第３６図）に従って終了する。
ステップ３６０８の終了後、処理は論理流れ図３６００に従って終了する。
【０３０１】
関係演算子 
上述のように、式の演算子が“Ａｎｄ”演算子でも、“Ｏｒ”演算子でもない場合には、処理はテストステップ３６０６からテストステップ３６１０に進む。テストステップ３６１０においては、実行エンジン８０２（第８図）が式の演算子と、以下の関係演算子との比較を行う。その関係演算子とは即ち、より小さい（“＜”）、より小さいか若しくは等しい（“＜＝”）、より大きい（“＞”）、より大きいか若しくは等しい（“＞＝”）、等しい（“＝＝”）、及び等しくない（“！＝”）という関係を表す演算子である。詳述すると、実行エンジン８０２は、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、これらの関係演算子のそれぞれを指定するデータとの比較を行うのである。上述のように、関係演算子は、２つのオペランド、即ち式のｌｈｓ及びｒｈｓに演算を施し、演算結果として、ｌｈｓとｒｈｓとの関係に対応する値を有するブール値項目を生成する。式の演算子が関係演算子でない場合には、処理はテストステップ３６１０（第３６図）から、後に説明するテストステップ３６１４に進む。逆に式の演算子が関係演算子である場合には、処理はテストステップ３６１０からステップ３６１２に進む。
【０３０２】
ステップ３６１２においては、実行エンジン８０２（第８図）が、関係演算子の評価を行う。ステップ３６１２（第３６図）は、ステップ３８０２から処理が開始される論理流れ図３６１２（第３８図）に詳細が示されている。ステップ３８０２においては、実行エンジン８０２（第８図）が、ｌｈｓ及びｒｈｓの双方が既知であるか否か即ち既知の値を有する項目に評価されるか否かということ、及びｌｈｓ及びｒｈｓの双方が未知であるか否か、即ち未知の値を有する項目に評価されるか否かということを判定する。項目構造体２７００（第２７図）によって表現される項目が未知の値を有する場合には、フィールド“ｔｙｐｅ ｃｏｄｅ”２７１２が項目の型が未知であることを表す。式のｌｈｓ及びｒｈｓの双方が既知であるか、若しくはその双方が未知の場合には、論理流れ図３６１２（第３８図）に従って、即ちステップ３６１２（第３６図）に従って処理が終了するが、これは両オペランドが既知である場合には推測すべきものがなく、また両オペランドが共に未知の場合には推測し得るものがないからである。逆に、オペランドの一方が既知で他方が未知の場合には、処理はテストステップ３８０２（第３８図）からテストステップ３８０４に進む。
【０３０３】
テストステップ３８０４においては、実行エンジン８０２（第８図）が、何れかのオペランドが未定義であるか否かを判定する。オペランドが項目構造体によって表現される項目に評価されない場合、即ちオペランドがＮＵＬＬ値に評価される場合にはそのオペランドは未定義である。このような場合においては、推測値を代入すべき項目は存在しない。従って、一方のオペランドが未定義である場合には、処理は論理流れ図３６１２（第３８図）に従って、即ちステップ３６１２（第３６図）に従って終了する。逆に両オペランドが共に定義されている場合には、処理はテストステップ３８０４（第３８図）から、テストステップ３８０６に進む。
【０３０４】
テストステップ３８０６においては、実行エンジン８０２（第８図）が、式の演算子と“＝”演算子及び“ｎｏｔ ｅｑｕａｌ”演算子とを比較し、推定値とブール値“ｔｒｕｅ”及び“ｆａｌｓｅ”との比較を行う。（ｉ）式の演算子が“＝”演算子であり、推定値が“ｔｒｕｅ”であるという条件、及び（ｉｉ）式の演算子が“ｎｏｔ ｅｑｕａｌ”演算子であり、推定値が“ｆａｌｓｅ”であるという条件の双方が満たされていない場合には、処理はテストステップ３８０６（第３８図）から後に説明するテストステップ３８１４に進む。逆に、（ｉ）式の演算子が“＝”演算子であり、推定値が“ｔｒｕｅ”であるという条件、及び（ｉｉ）式の演算子が“ｎｏｔ ｅｑｕａｌ”演算子であり、推定値が“ｆａｌｓｅ”であるという条件の何れか一方が満たされている場合には、処理はテストステップ３８０６からテストステップ３８０８に進む。
【０３０５】
テストステップ３８０８において、１つのオペランドが既知の値であり、他方のオペランドは未知の値を有する。その値が既知であるオペランドは、“ｋｎｏｗｎ  ｉｔｅｍ”に評価される。その値が未知のオペランドは“ｕｎｋｎｏｗｎ  ｉｔｅｍ”に評価される。更に、テストステップ３８０８においては、２つのオペランドが等しい値を有することが推定される。テストステップ３８０８において、実行エンジン８０２（第８図）は、既知の項目がＮＵＬＬ値を有するか否かを判定する。（ｉ）項目の型が、フィールド“ｔｙｐｅ ｃｏｄｅ”で、即ち項目構造体２７００のフィールド“ｔｙｐｅ ｃｏｄｅ”２７１２（第２７図）で指定されているように、“ｌｏｎｇ”または“ｐｏｉｎｔｅｒ”の何れかであることを示しているという条件、及び（ｉｉ）項目の値が、フィールド“ｖａｌｕｅ”において、即ち項目構造体２７００のフィールド“ｖａｌｕｅ”２７０６において指定されているように、０であることを示しているという条件の双方が満たされている場合には、その項目はＮＵＬＬ値を有する。
【０３０６】
既知の項目がＮＵＬＬ値を有する場合、処理はテストステップ３８０８（第３８図）からステップ３８１０に進み、ここでは演算ｘを施すことにより、その末知の項目に関連するリソースに、無効という印付けがなされる。リソースが関連付けられた未知の項目の値が、その値がＮＵＬＬである既知の項目に等しいと推定されることから、即ちそのリソースに対するポインタがＮＵＬＬであると推定されることから、このリソースは無効である。
【０３０７】
処理はステップ３８１０からステップ３８１２に進む。更に、既知の項目がＮＵＬＬ値を有していない場合、処理はテストステップ３８０８から直接ステップ３８１２に進む。ステップ３８１２においては、既知の項目の値が、以下に詳しく説明する方法で未知の値に代入される。従って、既知の項目の値は、その既知の項目と未知の項目とが等しいと推定される場合には既知の項目の値から推測される。ステップ３８１２が終了した後、処理は論理流れ図３６１２に従って、即ちステップ３６１２（第３６図）に従って終了する。
【０３０８】
上述のように、（ｉ）式の演算子が、“＝”演算子であり、推定値が“ｔｒｕｅ”であるという条件、及び（ｉｉ）式の演算子が“ｎｏｔ ｅｑｕａｌ”演算子であり、推定値が“ｆａｌｓｅ”であるという条件の双方が満たされない場合には、処理はテストステップ３８０６（第３８図）からテストステップ３８１４に進む。テストステップ３８１４においては、実行エンジン８０２（第８図）が、（ｉ）式の演算子が“ｎｏｔ ｅｑｕａｌ”演算子であり、推定値が“ｔｒｕｅ”であるという条件を満たすか否か、または（ｉｉ）式の演算子が“＝”演算子であり、推定値が“ｆａｌｓｅ”であるという条件を満たすか否かということを判定する。条件（ｉ）も、条件（ｉｉ）も何れもが満たされない場合には、論理流れ図３６１２に従って、即ちステップ３６１２（第３６図）に従って処理が終了する。そうでない場合、即ち条件（ｉ）若しくは条件（ｉｉ）の何れかが満たされる場合には、処理はテストステップ３８１４（第３８図）からテストステップ３８１６に進む。
【０３０９】
テストステップ３８１６においては、実行エンジン８０２（第８図）が２つのオペランド、即ちｌｈｓ及びｒｈｓが互いに等しくないことを推測する。既知の項目がＮＵＬＬ値を有する場合は、未知の項目が非ＮＵＬＬ値を有するものと推測される。Ｃ言語の様々なインプリメンテーションの文脈においては、ＮＵＬＬは値ゼロである。従って、未知の項目は非ゼロ値を有するものと推測される。テストステップ３８１６（第３８図）においては、実行エンジン８０２（第８図）が、既知の項目の値とＮＵＬＬとを比較する。既知の項目の値がＮＵＬＬでない場合には、処理は論理流れ図３６１２（第３８図）に従って終了する。逆に、既知の項目の値がＮＵＬＬである場合は、処理はテストステップ３８１８に進む。
【０３１０】
テストステップ３８１８においては、実行エンジン８０２（第８図）が、状態Ｑにあるリソースが既知の項目に関連付けられているか否かを判定する。上述のように、リソースが割り当てられた状態、割り当てられていない状態、または無効状態の何れにあるかが未知である場合には、リソースは状態Ｑにある。未知の項目が状態Ｑにあるリソースと関連付けられている場合には、処理はステップ３８２０（第３８図）に進み、ここでは演算ａが、その未知の項目に関連付けられたリソースに対して施される。リソースが関連付けられている項目がＮＵＬＬと等しくないことが推定されていることから、そのリソースを明確に割り当てられた状態におくために演算ａが施されるのである。ステップ３８２０から、処理はステップ３８２２に進む。更に、未知の項目が状態Ｑにあるリソースに関連付けられていない場合には、処理はテストステップ３８１８から直接ステップ３８２２に進む。
【０３１１】
ステップ３８２２において、その未知の項目を表現する項目構造体のフィールド“ｔｙｐｅ ｃｏｄｅ”２７１２（第２７図）は、その項目が非ゼロであることを示すように設定され、その未知の項目を表現する項目構造体のフィールド“ｉｎｖａｌｉｄ ｐｏｉｎｔｅｒ”２７２０は、その未知の項目は無効ポインタ、即ちＮＵＬＬ値を有していないことを示すように設定される。ステップ３８２２の終了後、処理は論理流れ図３６１２に従って終了する。
【０３１２】
従って、論理流れ図３６１２に従って、即ちステップ３６１２（第３６図）に従って、その式のオペランドの１つが既知であり、他のオペランドが既知ではなくかつ両オペランドが等しいと推定されるとき、若しくは等しくないと推定されているときには推測がなされる。推測がなされるのは、式の両オペランドの値、及び式のオペランドに関連するリソースの状態の双方についてである。ステップ３６１２が終了した後、処理は論理流れ図３６００に従って終了する。
【０３１３】
複合演算子 
上述のように、式の演算子が関係演算子でない場合には、処理はテストステップ３６１０からテストステップ３６１４に進む。テストステップ３６１４において、実行エンジン８０２（第８図）は、式の演算子と複合演算子（“，”）とを比較する。つまり、実行エンジン８０２は、その式を表現する式構造体のフィールド“ｋｉｎｄ”２２０２（第２２図）と、複合演算子を指定するデータとの比較を行うのである。複合演算子は２つのオペランド、即ちｌｈｓ及びｒｈｓに対して演算を施す。ここでｌｈｓ及びｒｈｓの双方が評価され、式はｒｈｓに評価される。例えば、式“ａ，ｂ”の評価では、オペランド“ａ”とオペランド“ｂ”の双方の評価を行った上で、その式“ａ，ｂ”が“ｂ”に評価される。
【０３１４】
演算子が複合演算子である場合には、処理はステップ３６１６（第３６図）に進み、そこでは実行エンジン８０２（第８図）が論理流れ図３６００（第３６図）に従って処理を行い、推定値として、その式が評価されると推定されるブール値を与える。ｒｈｓの値はその式の推定値から推測されるが、これはその式がｒｈｓに評価されるからである。例えば、式“ａ＝＝ｂ，ｃ＝＝ｄ”が真であると推定される場合には、ｒｈＳ、即ち式“ｃ＝＝ｄ”が真であると推測される。従って、処理は論理流れ図３６００に従って、ステップ３６１６において、処理は論理流れ図３６００に従って再帰的に式のｒｈｓに施される。ステップ３６１６の終了後、処理は論理流れ図３６００に従って終了する。演算子が複合演算子でない場合には、処理は論理流れ図３６００に従って終了し、またステップ３６１６はスキップされる。
【０３１５】
従って、上述のように、論理流れ図３６００に従って、式及び部分式（ｓｕｂｅｘｐｒｅｓｓｉｏｎ）を再帰的に処理することによって、実行エンジン８０２（第８図）はステップ３５１４（第３５図）において実行し得る限り、式の推定値から式の項目及び式の項目に関連するリソースについての推測を行う。処理はステップ３５１４から前に説明したテストステップ３５０６に進む。
【０３１６】
従って、ステップ２８１２（第２８図）において、論理流れ図３８１２に従い、実行エンジン８０２（第８図）は“ｉｆ”ステートメントにおける決定処理を行うのである。
【０３１７】
戻り（ｒｅｔｕｒｎ）処理 
上述のように“ｒｅｔｕｒｎ”ステートメントはステップ２８１６において処理される。“ｒｅｔｕｒｎ”ステートメントは、関数の実行を終了し、戻り値項目が定義されている場合にはその関数の戻り値項目に値を代入する。ステップ２８１６は、処理がステップ３９０２から開始される論理流れ図２８１６（第３９図）に詳細に示されている。
【０３１８】
ステップ３９０２においては、実行エンジン８０２（第８図）が、“ｒｅｔｕｒｎ”ステートメントが戻り値項目を指定しているか否かを判定する。“ｒｅｔｕｒｎ”ステートメントは、それが式を含んでいる場合、戻り値項目を指定する。例えば、ステートメント構造体１４１６（第２１図）が“ｒｅｔｕｒｎ”ステートメントを表現している場合、フィールド“ｐｏｉｎｔｅｒｓ”２１１０は、式構造体を指定する１つのポインタであるか、若しくはＮＵＬＬである。“ｒｅｔｕｒｎ”ステートメントが戻り値項目を指定する場合、即ちフィールド“ｐｏｉｎｔｅｒｓ”２１１０が式構造体を指定している場合、処理はテストステップ３９０２（第３９図）からステップ３９０４に進み、ここで“ｒｅｔｕｒｎ”ステートメントの式が論理流れ図２９００（第２９図）に従って評価され、また、演算は施されない。ステップ３９０４（第３９図）において“ｒｅｔｕｒｎ”ステートメントの式の評価において演算は施されないが、前にステップ３３０６、３３０７、及び３３１４（第３３Ａ−Ｂ図）に関連して説明したように、式のオペランドに何らかの演算を施すことも可能である。ステップ３９０４（第３９図）から処理はステップ３９０６に進み、ここでは実行エンジン８０２（第８図）がステップ３９０４（第３９図）において式の評価を行うことにより生成された項目を、サブジェクト関数の戻り値項目を表現する項目構造体に代入する。１つの項目の値を他の項目に代入することに関しては、後に詳しく説明する。
【０３１９】
処理はステップ３９０６からステップ３９０８に進む。また、“ｒｅｔｕｒｎ”ステートメントが戻り値項目を指定していない場合、処理はテストステップ３９０２から、直接ステップ３９０８に進む。ステップ３９０８においては、実行エンジン８０２（第８図）が、後に詳述するように、サブジェクト関数の実行のエミュレーション時においてサブジェクト関数を通る制御の流れを与えるのに用いられる“ｒｅｔｕｒｎ”条件を示すデータを、制御レコード内に格納する。ステップ３９０８（第３９図）の後、処理は論理流れ図２８１６に従って、即ちステップ２８１６（第２８図）に従って終了する。
【０３２０】
ブロック処理 
多くの関数においては、ステートメントのブロックがその関数の挙動を規定する。Ｃ言語の文脈においては、ステートメントのブロックは、それ自体がブロックステートメントである始め括弧、即ち“｛”と、終わり括弧、即ち“｝”との間に囲まれている。Ｃ言語で規定される関数においては、一般的にステートメントの第１ブロックが、ステートメントの第２ブロックを含んでいる。例えば、ソースコードの抜粋（１）は、第９行から第３２行までのステートメントの第１ブロックの中に、第１６行から第２１行までのステートメントの第２ブロックを含んでいる。このとき、ステートメントの第１ブロックは、ステートメントの第２ブロックのスーパーブロックであり、ステートメントの第２ブロックはステートメントの第１ブロックのサブブロックである。
【０３２１】
（ｐ１１８ｂ）上述のように、ブロックステートメント構造体は、ステートメント構造体、即ちブロックの第１ステートメントを表現しているステートメント構造体１４１６（第２１図）を指定するポインタを含む。ステートメント構造体１４１６は上述のように、ブロックの各ステートメントを表現するステートメント構造体のシングルリンクトリスト（ｓｉｎｇｌｙ−ｌｉｎｋｅｄ  ｌｉｓｔ）を維持するために用いられるフィールド“ｎｅｘｔ”２１０６を含んでいる。上述のように、ブロックステートメントはステップ２８２０（第２８図）において処理され、このステップ２８２０については論理流れ図２８２０（第４０図）にその詳細が示されており、またこの論理流れ図は、ブロックのステートメントの実行のエミュレーションのためのステートメントのブロックのステートメント構造体の処理について説明している。
【０３２２】
ステップ４００２においては、実行エンジン８０２（第８図）が、ブロックの第１ステートメントを表現するステートメント構造体を検索する。上述のように、そのブロックの第１ステートメントを表現するステートメント構造体は、ブロックステートメント構造体によって指定されている。検索されたステートメント構造体は、現ステートメント構造体である。処理はステップ４００２（第４０図）からテストステップ４００４に進む。
【０３２３】
テストステップ４００４においては、実行エンジン８０２（第８図）が、現ステートメント構造体が“ｅｌｓｅ”ステートメントを表現し、制御レコードが“ｅｌｓｅ”条件を示しているか否かを判定する。Ｃ言語においては、“ｅｌｓｅ”ステートメントは周知のものであり、Ｃスタンダードのセクション６．６．４．１に記載されている。ステートメント構造体１４１６（第２１図）のようなステートメント構造体は、フィールド“ｋｉｎｄ”２１０２がそのように示されている場合には、“ｅｌｓｅ”ステートメントを表現する。制御レコードは、サブジェクト関数の実行のエミュレーション時に制御の流れを管理するために、実行エンジン８０２（第８図）内部に維持されている。ステップ３５１０（第３５図）に関連して上述したように、制御レコードは、“ｉｆ”ステートメントを処理するときに“ｅｌｓｅ”条件を示すように設定され、“ｉｆ”ステートメントの述語がブール値“ｆａｌｓｅ”に評価される。現ステートメント構造体が“ｅｌｓｅ”ステートメントを表現していないか、若しくは制御レコードが“ｅｌｓｅ”条件を示していない場合には、処理はテストステップ４００４（第４０図）からステップ４００６に進み、ここで現ステートメント構造体によって表現されたステートメントの実行が、上述のように、論理流れ図２８００（第２８図）に従ってエミュレートされる。逆に、現ステートメント構造体が“ｅｌｓｅ”ステートメントを表現し、かつ制御レコードが“ｅｌｓｅ”条件を示していない場合には、処理はテストステップ４００４（第４０図）から以下に説明するステップ４０１４に進み、ステップ４００６はバイパスされる。
【０３２４】
上述のように、ステートメントのブロックはサブブロックを含み得る。また、上述のように、ステップ４００６において、現ステートメント構造体は論理流れ図２８００（第２８図）に従って処理される。従って、ステップ４００６（第４０図）におけるブロックステートメントの実行により、ステップ２８２０（第２８図）が再帰的に実行され、従って論理流れ図２８２０（第４０図）の各ステップが再帰的に実行されて、サブブロックの実行のエミュレーションが行われる。ひとたびサブブロックのステートメントが論理流れ図２８２０に従って処理されると、ステップ４００６におけるブロックステートメントの処理は完了し、サブブロックのステートメントの論理流れ図２８２０に従った処理は続行される。処理はステップ４００６からテストステップ４００８に進む。
【０３２５】
テストステップ４００８においては、実行エンジン８０２（第８図）が、論理流れ図２８００（第２８図）に関連して上述したようにステートメントの実行のエミュレーションによって設定された制御レコードと、“ｒｅｔｕｒｎ”条件、“ｅｘｉｔ”条件、若しくは“ｌｏｎｇ  ｊｕｍｐ”条件を示すデータとの比較を行う。ステップ３９０８（第３９図）に関連して上述したように、ステップ４００６（第４０図）において、“ｒｅｔｕｒｎ”ステートメントの実行のエミュレーション時に、制御レコードは“ｒｅｔｕｒｎ”条件を示すように設定される。“ｅｘｉｔ”条件は、実行エンジン８０２（第８図）がライブラリ関数ｅｘｉｔ  （）  の呼出しを処理するときに生起する。このライブラリ関数ｅｘｉｔ  （）  については、Ｃスタンダードのセクション７．１０．４．３に記載されている。“ｌｏｎｇ  ｊｕｍｐ”条件は、実行エンジン８０２が、ライブラリ関数ｌｏｎｇｊｍｐ  （）  の呼出しを処理するときに生起する。このライブラリ関数ｌｏｎｇｊｍｐ  （）  についてもＣスタンダードのセクション７．６．２．１に記載されている。制御レコードが“ｒｅｔｕｒｎ”条件、“ｅｘｉｔ”条件、若しくは“ｌｏｎｇ  ｊｕｍｐ”条件を示している場合、処理は論理流れ図２８２０（第４０図）に従って終了する。逆に制御レコードが“ｒｅｔｕｒｎ”条件、“ｅｘｉｔ”条件、若しくは“ｌｏｎｇ  ｊｕｍｐ”条件の何れをも示していない場合には、処理はテストステップ４００８からテストステップ４０１０に進む。
【０３２６】
テストステップ４０１０においては、実行エンジン８０２（第８図）が制御レコードと、“ｂｒｅａｋ”条件若しくは“ｃｏｎｔｉｎｕｅ”条件を示すデータとを比較する。ステップ４００６においては、“ｂｒｅａｋ”ステートメント若しくは“ｃｏｎｔｉｎｕｅ”ステートメントの実行のエミュレーション時に、制御レコードが、“ｂｒｅａｋ”条件若しくは“ｃｏｎｔｉｎｕｅ”条件を示すように設定される。制御レコードが“ｂｒｅａｋ”条件若しくは“ｃｏｎｔｉｎｕｅ”条件の何れかを示すように設定されている場合、処理はステップ４０１０に進み、ここで制御レコードが“ｎｅｘｔ”条件を示すように設定され、処理は論理流れ図２８２０に従って終了する。
【０３２７】
“ｎｅｘｔ”条件は、ブロックの“ｎｅｘｔ”ステートメントの実行がエミュレートされる場合の一般的な処理条件である。従って、ステートメントの現ブロックが“ｂｒｅａｋ”ステートメントを実行する場合、現ブロックの処理は終了し、処理は現ブロックのスーパーブロック内における現ブロックのすぐ後に続くステートメントに進む。これに対して、“ｒｅｔｕｒｎ”条件は制御レコードをリセットしない。従って、ステップ４００６における“ｒｅｔｕｒｎ”ステートメントの実行のエミュレーションにより、上述のテストステップ４００８を通した現ブロックの処理が終了し、同様に現ブロックの任意のスーパーブロックの処理も終了する。
【０３２８】
一方、制御レコードが“ｂｒｅａｋ”条件も“ｃｏｎｔｉｎｕｅ”条件をも示していない場合には、処理はテストステップ４０１０からステップ４０１４に進む。更に、現ステートメント構造体が“ｅｌｓｅ”ステートメントを表現し、制御レコードが上述のように“ｅｌｓｅ”条件を示していない場合には、処理はテストステップ４００４から４０１４に進む。ステップ４０１４においては、実行エンジン８０２（第８図）が現ステートメント構造体のフィールド“ｎｅｘｔ”２１０６（第２１図）を検索し、検索されたステートメント構造体を現ステートメント構造体にして、前の現ステートメント構造体を置き換える。
【０３２９】
処理はステップ４０１４（第４０図）からテストステップ４０１６に進み、ここで実行エンジン８０２（第８図）が、現ステートメント構造体を指定するポインタとＮＵＬＬとを比較する。現ステートメント構造体を指定するポインタがＮＵＬＬである場合には、ステートメントのブロックの最終ステートメントが論理流れ図２８２０（第４０図）に従って処理され、処理は論理流れ図２８２０に従って終了する。逆に、現ステートメント構造体を指定するポインタがＮＵＬＬでない場合には、処理はテストステップ４０１６から、上述のテストステップ４００４に進む。
【０３３０】
従って、ステートメントのブロックの実行はエミュレートされ、ステートメントのブロックにおける制御の流れは、論理流れ図２８２０（第４０図）の通りに流れることになる。
【０３３１】
リークの処理 
上述のように、サブジェクト関数のステートメントの実行がひとたびエミュレートされると、ステップ２６０６（第２６図）においてリーク（ｌｅａｋ）が検出される。ステップ２６０６については論理流れ図２６０６（第４１図）にその詳細が示されている。処理は論理流れ図２６０６に従ってループステップ４１０２から開始される。ループステップ４１０２及びＮＥＸＴステップ４１０６はループを形成し、その中でサブジェクト関数の各エクスターナルがステップ４１０４に従って処理される。ステップ４１０４においては、実行エンジン８０２（第８図）が、エクスターナルが到達可能な全てのリソースに印付けを行う（ｍａｒｋ）。そのリソースがエクスターナル若しくはそのエクスターナルを含む集群（ｂｕｎｃｈ）における任意の項目に関連付けられている場合には、そのリソースはエクスターナルが到達可能なリソースである。集群については以下に詳しく説明する。説明のための例を用いると、集群型である配列の要素が関連付けられたリソースは、その配列の任意の要素から到達可能である。
【０３３２】
リソース、即ちリソース状態構造体３１００（第３１図）によって表現されたリソースは、リソース状態構造体３１００のフィールド“ｍａｒｋ”３１１４を、それを示すように設定することによって印付けされる。各エクスターナルによって到達可能な各リソースが、ループステップ４１０２（第４１図）及びＮＥＸＴステップ４１０６によって形成されたループの中でひとたび印付けされると、処理はループステップ４１０６からループステップ４１０８に進む。
【０３３３】
ループステップ４１０８及びＮＥＸＴステップ４１１４はループを形成し、その中で各リソースが処理される。リソース状態構造体は、シングルリンクトリストに保持されて、全てのリソース状態構造体の処理を容易にする。例えば、リソース状態構造体３１００（第３１図）は、シングルリンクトリストにおける次のリソース状態構造体を指定するフィールド“ｎｅｘｔ”３１１２を含む。メモリ１０４（第１図）内のリソース状態構造体によって表現される各リソースに対して、処理はループステップ４１０８（第４１図）からテストステップ４１１０に進む。
【０３３４】
テストステップ４１１０においては、実行エンジン８０２（第８図）がリソースが割り当てられているか否か、即ち状態Ａ若しくは状態Ｑにあるか否かということと、印付けされていないことを判定する。割り当てられ印付けされていないリソース、即ちどのエクスターナルからのも到達可能でないリソースはリークとなっている。そのリソースが割り当てられており、かつ印付けされていない場合には、処理はテストステップ４１１０（第４１図）からステップ４１１２進み、ここでそのリークがユーザに対して通知される。そのリソースが割り当てられていない、即ち状態Ａ若しくは状態Ｑにないか、若しくは印付けされている場合には、処理はテストステップ４１１０から直接ＮＥＸＴステップ４１１４に進む。
【０３３５】
更に、処理はステップ４１１２からＮＥＸＴステップ４１１４へ進む。処理はＮＥＸＴステップ４１１４からループステップ４１０８に進み、そこで次のリソースが上述のように処理されて、最終的に全てのリソースが処理される。ひとたび各リソースが、ループステップ４１０８及びＮＥＸＴステップ４１１４が形成するループにおいて処理されると、論理流れ図２６０６に従って、即ちステップ２６０６（第２６図）に従って処理は終了する。
【０３３６】
従って、リークは検出され、論理流れ図２６０６に従って、即ちステップ２６０６（第２６図）に従ってそれが通知される。
【０３３７】
エクスターナルの構築 
上述のように、ステップ２６０８において、各エクスターナルは論理流れ図４２００（第４２図）に従って構築される。論理流れ図４２００に従った処理はテストステップ４２０２から開始されるが、このステップでは実行エンジン８０２（第８図）が、リソースがそのエクスターナルに関連付けられているか否かを判定する。説明のための例を用いて、エクスターナルリスト構造体１４１４（第１５図）によって表現されたエクスターナルにリソースが関連付けられているか否かの判定について以下説明する。フィールド“ｆｉｒｓｔ ｄｅｃｌ”１５０２は宣言構造体１５０６を指定しこの宣言構造体はフィールド“ｉｔｅｍ”１６０８を含む。フィールド“ｉｔｅｍ”１６０８は項目構造体、即ち項目構造体２７００を指定する。項目構造体２７００のフィールド“ｒｅｓｏｕｒｃｅ”２７０２（第２７図）が、リソース状態構造体を指定している場合、エクスターナルリスト構造体１４１４（第１５図）によって表現されたエクスターナルに、リソースは関連付けられている。そのエクスターナルが、例えばリソース状態構造体３１００（第３１図）によって表現されたリソースに関連付けられている場合、処理はテストステップ４２０２（第４２図）からステップ４２０４に進み、ここでフィールド“ｓｔａｔｅ”３１０２（第３１図）が検索される。処理はステップ４２０４から後に説明するステップ４２１０に進む。
【０３３８】
そのエクスターナルに関連付けられたリソースが存在しない場合には、処理はテストステップ４２０２からテストステップ４２０６に進む。テストステップ４２０６においては、実行エンジン８０２（第８図）が、そのエクスターナルが無効ポインタであるか否かを判定する。エクスターナルの型は、そのエクスターナルに関連付けられた項目を表現する項目構造体のフィールド“ｔｙｐｅ ｃｏｄｅ”２７１２（第２７図）によって指定され、それがＶＡＬＵＥ ＴＹＰＥ ＮＯＮ ＺＥＲＯである場合には、そのエクスターナルは無効ポインタである。型ＶＡＬＵＥ ＴＹＰＥ ＮＯＮ ＺＥＲＯは、その項目がゼロ以外の値を有することを示す。そのエクスターナルに関連付けられた項目を表す項目構造体のフィールド“ｉｎｖａｌｉｄ ｐｏｉｎｔｅｒ”、即ちフィールド“ｉｎｖａｌｉｄ ｐｏｉｎｔｅｒ”２７２０がそれを示している場合、若しくはそのエクスターナルの値が０または−１である場合には、エクスターナルは無効ポインタである。
【０３３９】
そのエクスターナルが無効ポインタである場合には、処理はテストステップ４２０４（第４２図）からステップ４２０８に進み、そこでそのエクスナルのリソースの状態が状態Ｘに設定される。例えば、リソース状態構造体３１００（第３１図）によって表現されるリソースが、エクスターナル状態構造体３０００（第３０図）によって表現されたエクスターナルに関連付けられている場合には、状態Ｘを示すデータがフィールド“ｓｔａｔｅ”３１０２（第３１図）に格納される。ステップ４２０８（第４２図）から、処理はステップ４２１０に進む。更に、処理は、上述のようにステップ４２０４から、またエクスターナルが無効ポインタでない場合にはテストステップ４２０６からステップ４２１０に進む。
【０３４０】
ステップ４２１０において、エクスターナルの複合ＲＳ，ＤＫ及びＣＰ状態が更新される。状態の構成は、第３Ｂ図、第４Ｂ図、及び第５Ｂ図に関連して前に詳しく説明した。ステップ４２１０の終了後、処理は論理流れ図４２００に従って終了する。
【０３４１】
関数の出力モデル 
上述のように、モデルマシン８０８（第８図）は、ステップ２４１２（第２４図）においてサブジェクト関数のモデルを生成し、格納する。ステップ２４１２は、論理流れ図２４１２（第４３図）に詳細が示されている。処理はステップ４３０２から開始され、ここではモデルマシン８０８（第８図）が関数モデル構造体１１００（第１１図）のような関数モデル構造体の割り当て及び初期化を行う。関数モデル構造体１１００は、一実施例においては、フィールド“ｎａｍｅ”１１０２、フィールド“ｄｅｓｃｒｉｐｔｉｏｎ”１１０８、フィールド“ｆｉｌｅ”１１１０、フィールド“ｌｉｎｅ”１１１２、及びフィールド“ａｕｔｏｍａｔｅｄ”１１０６に、（ｉ）その挙動が関数モデル構造体１１００においてモデル化されている関数の識別子、（ｉｉ）その関数のテキスト形式の記述、（ｉｉｉ）ソースコードファイルの名称、（ｉｖ）その関数が定義されているソースコードファイル内の行、及び（ｖ）その関数が自動的にモデル化されたことを示すブール値を、それぞれ格納することによって初期化される。その関数のモデルがモデルマシン８０８（第８図）によって生成された場合、関数は自動的にモデル化される。逆に、その関数のモデルが、ユーザがコンピュータ１００（第１図）においてテキストエディタ（図示せず）を用いて生成した場合、その関数は手動でモデル化される。例えば、ライブラリ関数ｆｏｐｅｎ  （）  、ｍａｌｌｏｃ  （）  、及びｆｒｅｅ  （）  は、手動でモデル化される。関数モデル構造体のフィールド“ａｕｔｏｍａｔｅｄ”１１１６（第１１図）は、上述のようにステップ９０４（第９図）においてモデル記述ファイル６０４（第６図）から呼出しを行うが、これはその関数が手動でモデル化されるということを示すように設定される。
【０３４２】
ステップ４３０６（第４３図）から、処理はステップ４３０４に進み、そこでエクスターナルモデル構造体１２００（第１２図）のようなエクスターナルモデル構造体が、そのサブジェクト関数の各エクスターナルに対して生成され、対応する関数モデル構造体におけるエクスターナルモデル構造体のシングルリンクトリストに挿入される。例えば、フィールド“ｆｉｒｓｔ  ｅｘｔｅｒｎａｌ”１１０４（第１１図）及びフィールド“ｌａｓｔ  ｅｘｔｅｒｎａｌ”１１０６は、上述のように、関数モデル構造体１１００をエクスターナルモデル構造体のシングルリンクトリストに関連付けるために用いられる。１つのエクスターナルの処理は、ステップ４３０４（第４３図）に従って行われるが、この処理は論理流れ図４４００（第４４図）に示されている。
【０３４３】
論理流れ図４４００に従って処理はステップ４４０２から開始されるが、ここではモデルマシン８０８（第８図）がエクスターナルの型、即ちそのエクスターナルがパラメータであるか、戻り値項目であるか、若しくは項目（即ち、グローバルに定義された項目またはスタティックな項目）であるかを判定する。そのエクスターナルがパラメータである場合は、モデルマシン８０８（第８図）はサブジェクト関数の定義におけるパラメータの位置を判定する。第１パラメータはパラメータ番号ゼロであって、最終パラメータの番号は、サブジェクト関数に対して定義されたパラメータ番号より１小さい。そのエクスターナルが項目である場合には、モデルマシン８０８（第８図）がその項目の識別子を判定する。そのエクスターナルの型は、上述のように、エクスターナルモデル構造体１２００（第１２図）のフィールド“ｔｙｐｅ”１２０４に格納される。同様に、パラメータ番号が求められた場合には、そのパラメータ番号はフィールド“ｐａｒａｍｅｔｅｒ  ｎｕｍｂｅｒ”１２０６に格納され、項目が求められた場合には、その項目の識別子がフィールド“ｎａｍｅ”１２０８に格納される。
【０３４４】
処理はステップ４４０２からステップ４４０４に進み、そこではモデルマシン８０８（第８図）が演算の数を判定し、サブジェクト関数の実行のエミュレーション時に、エクスターナルに施される特定の演算を判定する。ステップ４４０４においては、演算及び施される演算の数が、そのエクスターナルの複合ＤＫ状態に従って判定される。次の表Ｎはエクスターナルの複合ＤＫ状態から導かれる演算及び演算の数の概要を示したものである。
【０３４５】
【表１３】
2006252583.tif 000024
【０３４６】
従って、例えば、エクスターナルの複合ＤＫ状態が状態Ａである場合には、サブジェクト関数の実行のエミュレーションにおいて、演算ａがそのエクスターナルに施される。また、エクスターナルの複合ＤＫ状態が状態ＫＱである場合には、サブジェクト関数の実行のエミュレーションにおいて、演算ｋが、次いで演算ｍがそのエクスターナルに施される。上述のように、エクスターナルの複合状態は、サブジェクト関数の実行の多重エミュレーションの包括的な効果を特定する。従って、エクスターナルの複合状態から導かれた演算は、そのエクスターナル上でのサブジェクト関数の実行の累積的な効果のエッセンス（ｄｉｓｔｉｌｌａｔｉｏｎ）を表現する。
【０３４７】
処理は、ステップ４４０４からテストステップ４４０６に進み、このステップではモデルマシン８０８（第８図）がそのエクスターナルに施される演算の数とゼロとの比較を行う。そのエクスターナルに施される演算の数がゼロに等しい場合には、処理はステップ４４０８（第４４図）に進み、そこでモデルマシン８０８（第８図）が演算の数を判定し、かつそのエクスターナルの複合ＣＰ状態に従ったサブジェクト関数のエミュレーション時にそのエクスターナルに施される特定の演算を求める。以下の表Ｏは、エクスターナルの複合ＣＰ状態から導かれる演算及び演算の数の概要を示したものである。
【０３４８】
【表１４】
2006252583.tif 000025
【０３４９】
従って、エクスターナルの複合ＤＫ状態による、そのエクスターナル上でサブジェクトルーチンの実行の累積的効果に関する情報の供給が不十分である場合には、そのエクスターナルの複合ＣＰ状態が、サブジェクト関数の実行の累積的効果を判定するために用いられる。説明のための例を用いると、エクスターナルの複合ＣＰ状態が状態ｉである場合、サブジェクト関数のエミュレーションにより、そのエクスターナルに演算ｉが施される。ステップ４４０４（第４４図）またはステップ４４０８の何れかにおいて、そのエクスターナルに施される演算及び演算の数は、エクスターナルモデル構造体１２０のフィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４（第１２図）及び“ｎｕｍｂｅｒ ｏｆ ｏｐｅｒａｔｉｏｎｓ”１２１２にそれぞれ格納される。処理はステップ４４０８（第４４図）からステップ４４１０に進む。更に、モデルマシン８０８（第８図）が、テストステップ４４０６（第４４図）において、ステップ４４０４において判定されたようにそのエクスターナルに施される演算の数がゼロであると判定された場合、処理はテストステップ４４０６から直接ステップ４４１０に進む。
【０３５０】
ステップ４４１０において、モデルマシン８０８（第８図）は、エクスターナルの複合ＲＳ状態から、そのエクスターナルに関連付けられたリソースの初期状態を判定する。つまり、そのエクスターナルの複合ＲＳ状態はエクスターナルモデル構造体１２００のフィールド“ｉｎｉｔｉａｌ ｓｔａｔｅ”１２２０（第１２図）に格納される。エクスターナルの複合ＲＳ状態は、そのエクスターナルに関連するリソースに対するサブジェクト関数の実行の累積的効果を反映する。処理はステップ４４１０（第４４図）からテストステップ４４１２に進み、そこではモデルマシン８０８（第８図）が、そのエクスターナルの複合ＲＳ状態と、そのエクスターナルに関連付けられたリソースが存在しないことを示す状態ＮＯＮＥとを比較する。そのエクスターナルに関連付けられたリソースが存在しない場合、処理はテストステップ４４１２（第４４図）からステップ４４１４に進み、そこではブール値“ｆａｌｓｅ”が、エクスターナルモデル構造体１２００のフィールド“ｎｅｗ ｒｅｓｏｕｒｃｅ”１２１８（第１２図）に格納される。逆に、リソースがそのエクスターナルに関連付けられている場合、即ちそのエクスターナルの複合ＲＳ状態がＮＯＮＥ以外である場合には、処理はテストステップ４４１２（第４４図）からステップ４４１６に進む。ステップ４４１６においては、モデルマシン８０８（第８図）がエクスターナルモデル構造体１２００のフィールド“ｎｅｗ ｒｅｓｏｕｒｃｅ”１２１８（第１２図）にブール値“ｔｒｕｅ”を格納し、サブジェクト関数のエミュレーションにより、そのエクスターナルに関連付けられた新たなリソースが生成されることを示すようにする。
【０３５１】
処理はステップ４４１４（第４４図）、若しくはステップ４４１６の何れかからステップ４４１８に進み、そこでモデルマシン８０８（第８図）がエクスターナルモデル構造体１２００（第１２図）を、関数モデル構造体１１００（第１１図）のエクスターナルモデル構造体のシングルリンクトリストに挿入する。ステップ４４１８（第４４図）の終了後、処理は論理流れ図４４００に従って終了する。
【０３５２】
サブジェクト関数の各エクスターナルが、ステップ４３０４（第４３図）において論理流れ図４４００に従って処理された後、処理はステップ４３０６に進み、そこでサブジェクト関数を表現する関数モデル構造体１１００（第１１図）が、全ての関数モデル構造体を含むデータ構造体に格納される。ステップ４３０６の終了後、処理は論理流れ図２４１２に従って、即ちステップ２４１２（第２４図）に従って終了する。次いで、格納された関数モデル構造体によって表現される関数モデルが、後に詳しく説明するようにサブジェクト関数の呼出しを行う他の関数の解析を行うときに、そのサブジェクト関数の実行をエミュレートするために用いられ得る。
【０３５３】
１つの項目の値の他の項目への代入 
上述のように、ステップ３３５６（第３３Ｃ図）において、一方の項目、即ちｒｈｓの値が、他の項目、即ちｌｈｓに代入される。ステップ３３５６は、論理流れ図３３５６（第４５図）に詳細に示されており、ここでは、処理がテストステップ４５０２から開始される。テストステップ４５０２においては、実行エンジン８０２（第８図）が、ｌｈｓ及びｒｈｓが項目によって表現されるか否かを判定する。上述のように、ｌｈｓ若しくはｒｈｓ等の式は、実行エンジン８０２がその式を評価するための十分な情報を有している場合には１つの項目に評価され、他の場合にはＮＵＬＬ値に評価される。式が１つの項目に評価される場合には、その式はその項目によって表現される。ｌｈｓ若しくはｒｈｓの何れかが１つの項目によって表現されない場合には、処理はテストステップ４５０２（第４５図）から、以下に説明するテストステップ４５１０に進む。逆にｌｈｓ及びｒｈｓの双方が１つの項目によって表現される場合には、処理はテストステップ４５０２からステップ４５０４に進む。
【０３５４】
ステップ４５０４においては、ｌｈｓを表現する項目、即ちｌｈｓ項目のフィールドが、それに対応するｒｈｓを表現する項目、即ちｒｈｓ項目と等しく形成される。詳述すると、項目構造体２７００フィールド“ｒｅｓｏｕｒｃｅ”２７０２（第２７図）、“ｅｘｔｅｒｎａｌ”２７０４、“ｖａｌｕｅ”２７０６、“ｔｙｐｅ ｃｏｄｅ”２７１２、“ｉｎｉｔｉａｌｉｚｅｄ”２７１４、及び“ｉｎｖａｌｉｄ ｐｏｉｎｔｅｒ”２７２０のそれぞれに対応するｒｈｓ項目のフィールドに、データが格納される。処理はステップ４５０４（第４５図）からテストステップ４５０に進み、そこでは実行エンジン８０２（第８図）がｒｈｓが初期化されたか否かを判定する。実行エンジン８０２は、項目構造体２７０のフィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４（第２７図）に対応するｒｈｓ項目のフィールドと、ブール値“ｆａｌｓｅ”とを比較することによってこのような判定を行う。
【０３５５】
ｒｈｓが初期化されている場合、即ち項目構造体２７００のフィールド”ｉｎｉｔｉａｌｉｚｅｄ”２７１４（第２７図）に対応するｒｈｓ項目のフィールドが、ブール値“ｔｒｕｅ”を有している場合には、処理は論理流れ図３３５６に従って、即ちステップ３３５６（第３３Ｅ図）に従って終了する。逆に、ｒｈｓが初期化されていない場合、即ち項目構造体２７００のフィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４（第２７図）に対応するｒｈｓ項目のフィールドがブール値“ｆａｌｓｅ”を有している場合には、処理はテストステップ４５０６（第４５図）からステップ４５０８に進む。ステップ４５０８においては、上述のようにエラーメッセージがエラーログファイル及び／若しくはビデオモニタ１１８上のディスプレイに対して送られて、初期化されていないデータが使用されていることを警告する。フィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４（第２７図）に対応するｒｈｓ項目のフィールドが、上述のようにステップ４５０４において、ｌｈｓ項目における対応するフィールドにコピーされることから、ｌｈｓ項目も初期化されていない旨の印付けがなされる。ステップ４５０８（第４５図）が終了した後、論理流れ図３３５６に従って、即ちステップ３３５６（第３３Ｃ図）に従って処理を終了する。
【０３５６】
上述のように、ｌｈｓ若しくはｒｈｓの何れかが項目によって表現されない場合、処理はテストステップ４５０２（第４５図）からテストステップ４５１０に進む。テストステップ４５１０において、実行エンジン８０２（第８図）が、ｒｈｓ及びｌｈｓが個別に項目によって表現されるか否かを判定する。ｌｈｓが項目によって表現され、ｒｈｓが項目によって表現されない場合には、処理はテストステップ４５１０（第４５図）からステップ４５１２に進む。そうでない場合には、処理は論理流れ図３３５６に従って、即ちステップ３３５６（第３３Ｅ図）に従って終了する。
【０３５７】
ステップ４５１２（第４５図）においては、実行エンジン８０２（第８図）がｌｈｓ項目に未知なものとしての印付けを行う。例えば、項目構造体２７００（第２７図）がｌｈｓ項目を表現する場合、実行エンジン８０２（第８図）が、（ｉ）未知のデータの型を示すデータをフィールド“ｔｙｐｅ ｃｏｄｅ”２７１２（第２７図）に格納し、（ｉｉ）ｌｈｓ項目が初期化されていないことを示すデータをフィールド“ｉｎｉｔｉａｌｉｚｅｄ”２７１４に格納し、（ｉｉｉ）ｌｈｓがエクスターナル若しくはリソースと関連付けられていないことを示すべくフィールド“ｒｅｓｏｕｒｃｅ”２７０２及び“ｅｘｔｅｒｎａｌ”２７０４にＮＵＬＬを格納することによって、ｌｈｓが既知でないという印付けを行う。  ステップ４５１２（第４５図）の終了後、処理は論理流れ図３３５６に従って、即ちステップ３３５６（第３３Ｅ図）に従って終了する。
【０３５８】
従って、ステップ３３５６において、ｒｈｓを表現する項目の値はｌｈｓを表現する項目に代入される。上述のように、実行エンジン８０２（第８図）が、ステップ３４０８（第３４図）において式の評価によって得られた項目の値を、宣言された項目に代入する。ステップ３４０８におけるこの代入は、論理流れ図３３５６（第４５図）に関連して上述したｒｈｓ項目のｌｈｓ項目への代入に類似したものである。ステップ３８１２（第３８図）に関して上述したように、実行エンジン８０２（第８図）は、既知の項目の値を未知の項目に代入する。ステップ３８１２（第３８図）における既知の項目の未知の項目への代入は、論理流れ図３３５６に関連して上述したｒｈｓ項目のｌｈｓ項目への代入に類似したものである。上述のように、実行エンジン８０２（第８図）は、ステップ３９０６（第３９図）において、式の評価によって得られた項目の値を戻り値項目に代入する。ステップ３９０６におけるこの代入処理は、論理流れ図３３５６（第４５図）に関連して上述したｒｈｓ項目のｌｈｓ項目への代入に類似したものである。
【０３５９】
関数のエミュレーション
上述のように、実行エンジン８０２（第８図）は、ステップ３３５２（第３３Ｅ図）において、関数の実行をエミュレートすることにより関数の呼出しを評価する。ステップ３３５２は論理流れ図３３５２（第４６図）に詳細に示されており、ここでは処理がステップ４６０２から始まる。関数の呼出しの実行は、呼び出される関数の挙動を表現する関数モデル構造体に従ってエミュレートされる。テストステップ４６０２において、実行エンジン８０２（第８図）は、呼び出される関数の挙動を表現する関数モデル構造体が、メモリ１０４（第１図）に格納されているか否かを判定する。上述のように、関数モデル構造体１１００（第１１図）は、関数モデル構造体１１００によってその挙動が表現される関数の識別子を表現するデータを含んでいるフィールド“ｎａｍｅ”１１０２を有する。各関数の挙動を表現する様々な関数モデル構造体の対応するフィールドは、サブジェクト関数がその関数を呼び出すのに用いる識別子と比較されるが、これは全ての関数モデル構造体がチェックされるまでか、若しくはそのフィールド“ｎａｍｅ”が識別子と一致する関数モデル構造体が見つけられるまで続けて行われる。
【０３６０】
その識別子と一致するフィールド“ｎａｍｅ”を有する関数モデル構造体が見つけられない場合は、処理はテストステップ４６０２（第４６図）からステップ４６０４に進み、ここで呼び出される関数の実行のエミュレーションを評価することによって得られる項目としてＮＵＬＬが生成される。上述のように、実行エンジン８０２（第８図）がその式を適切に評価するための十分な情報を有していないときには、式はＮＵＬＬに評価される。ステップ４６０４（第４６図）の実行の後、処理は論理流れ図３３５２に従って、即ちステップ３３５２（第３３Ｅ図）に従って終了する。
【０３６１】
一方、そのフィールド“ｎａｍｅ”が、サブジェクト関数が関数の呼出しに用いる識別子と一致するような関数モデル構造体、即ち呼び出される関数の挙動を表現する関数モデル構造体が見つけられた場合には、処理はテストステップ４６０２（第４６図）からループステップ４６０６に進む。ループステップ４６０６及びＮＥＸＴステップ４６３０はループを形成し、このループの中で呼び出される関数の関数モデル構造体内のエクスターナルモデル構造体によって表現される各エクスターナルが処理される。第１３図に関連して以前に説明したように、関数モデル構造体１１００Ａのような関数モデル構造体は、エクスターナルモデル構造体のシングルリンクトリストにおける第１エクスターナルモデル構造体を指定するフィールド“ｆｉｒｓｔ ｅｘｔｅｒｎａｌ”１１０４Ａを含む。呼び出される関数の関数モデル構造体のエクスターナルモデル構造体のシングルリンクトリストの各エクスターナルに対して、処理はループステップ４６０６（第４６図）からテストステップ４６０８に進む。呼び出される関数の関数モデル構造体のエクスターナルモデル構造体のシングルリンクトリストの各エクスターナルが処理された後、処理はループステップ４６０６から以下に詳細に説明するステップ４６３２に進む。
【０３６２】
以下のステップ４６０８〜４６２８の説明の文脈においては、ループステップ４６０６及びＮＥＸＴステップ４６３０により形成されるループに従って処理されるエクスターナルモデル構造体には、エクスターナルモデル構造体の処理の説明のための例として、エクスターナルモデル構造体１２００（第１２図）を用いるものとする。テストステップ４６０８（第４６図）において、実行エンジン８０２（第８図）が、エクスターナルモデル構造体１２００（第１２図）がパラメータを表現しているか否かを、フィールド“ｔｙｐｅ”１２０４とパラメータを示すデータとを比較することによって判定する。エクスターナルモデル構造体１２００がパラメータを表現していない場合には、処理はテストステップ４６０８（第４６図）から以下に詳細に説明するテストステップ４６１２に進む。逆に、エクスターナルモデル構造体１２００（第１２図）がパラメータを表現している場合には、処理はテストステップ４６０８（第４６図）からステップ４６１０に進む。
【０３６３】
ステップ４６１０においては、実行エンジン８０２（第８図）がそのパラメータを表現する項目を検索する。ループステップ３３４８（第３３Ｅ図）、ステップ３３４９、及びＮＥＸＴステップ３３５０に関連して以前に説明したように、実行エンジン８０２（第８図）は、呼び出される関数のパラメータを表現する項目の配列を含む。エクスターナルモデル構造体１２００（第１２図）によって表現される特定のパラメータは、フィールド“ｐａｒａｍｅｔｅｒ ｎｕｍｂｅｒ”１２０６において指定される。処理はステップ４６１０（第４６図）から、後に詳述するテストステップ４６１６に進む。
【０３６４】
上述のように、エクスターナルモデル構造体１２００（第１２図）がパラメータを表現していない場合、処理はテストステップ４６０８からテストステップ４６１２に進む。テストステップ４６１２（第４６図）において、実行エンジン８０２（第８図）が、エクスターナルモデル構造体１２００（第１２図）が変数を表現しているか否かを、フィールド“ｔｙｐｅ”１２０４内に格納されたデータと変数が表現されていることを示すデータとを比較することによって判定する。エクスターナルモデル構造体１２００（第１２図）が変数を表現していない場合には、処理はテストステップ４６１２（第４６図）から後に詳述するテストステップ４６１６に進む。逆に、エクスターナルモデル構造体１２００（第１２図）が変数を表現している場合には、処理はテストステップ４６１２からステップ４６１４に進む。
【０３６５】
ステップ４６１４において、実行エンジン８０２（第８図）は、エクスターナルモデル構造体１２００（第１２図）によって表現される変数の評価を行う。実行エンジン８０２（第８図）は、その変数の項目を検索することによってその変数を評価する。サブジェクト関数を表現する関数構造体内において宣言構造体、即ち宣言構造体１５０６（第１６図）が、エクスターナルモデル構造体１２００（第１２図）によって表現される変数を表現する。エクスターナルモデル構造体１２００はその変数の識別子をフィールド“ｎａｍｅ”１２０８に格納することによって、表現された特定の変数を識別する。エクスターナルモデル構造体１２００及び宣言構造体１５０６（第１６図）が同じ変数を表現している場合には、フィールド“ｎａｍｅ”１６０４に格納された識別子はフィールド“ｎａｍｅ”１２０（第１２図）に格納された識別子と同じものである。宣言構造体１５０６の“ｉｔｅｍ”１６０８が指定する項目構造体２７００を検索することによってその変数の評価が行われる。処理はステップ４６１４（第４６図）からテストステップ４６１６に進む。
【０３６６】
上述のように、エクスターナルモデル構造体１２００（第１２図）がパラメータ及びも変数の何れも表現していない場合、即ちエクスターナルモデル構造体１２００が呼び出される関数の戻り値項目を表現している場合には、処理はテストステップ４６１６からテストステップ４６１２に進む。また、処理はステップ４６１６（第４６図）の他ステップ４６１４からもテストステップ４６１６に進み得る。テストステップ４６１６において、実行エンジン８０２（第８図）は、エクスターナルモデル構造体１２００（第１２図）によって表現されるエクスターナルを表現する項目が定義されているか否かを判定する。項目が定義されているのは、（ｉ）ステップ４６１０においてエクスターナルモデル構造体１２００によって表現されるパラメータの値が定義され、既知の値に評価されて、かつ処理がステップ４６１６（第４６図）を通って進む場合、または（ｉｉ）ステップ４６１４においてエクスターナルモデル構造体１２００（第１２図）によって表現される変数が初期化され、処理がステップ４６１４（第４６図）を通って進む場合である。
【０３６７】
エクスターナルモデル構造体１２００（第１２図）よって表現されるエクスターナルを表現する項目が定義されない場合には、処理はテストステップ４６１６（第４６図）から後に説明するテストステップ４６２４に進む。逆に、このようなアイテムが定義される場合には、処理はテストステップ４６１６からループステップ４６１８に進む。
【０３６８】
ループステップ４６１８及びＮＥＸＴステップ４６２２はループを形成し、このループの中でエクスターナルモデル構造体１２００のフィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４（第１２図）に格納された各演算が処理される。上述のように、フィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４に格納された演算の数は、フィールド“ｎｕｍ ｏｐｅｒａｔｉｏｎｓ”１２１２に記録される。フィールド”ｏｐｅｒａｔｉｏｎｓ”１２１４に格納された各演算に対して処理はループステップ４６１８（第４６図）からステップ４６２０に進み、ここでステップ２９０６（第２９図）に関連して上述したのと同じ方法で、エクスターナルモデル構造体１２００（第１２図）によって表現されるエクスターナルに演算が施される。エクスターナルに演算を施すことによって何らかのエラーが検出されたときには、それが上述の方法と同様にプログラミングエラーとしてユーザに通知される。ステップ４６２０（第４６図）から、処理はＮＥＸＴステップ４６２２を通してループステップ４６１８に進み、ここでフィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４（第１２図）に格納された次の演算があれば、それが処理される。フィールド“ｏｐｅｒａｔｉｏｎｓ”１２１４に格納された全ての演算がループステップ４６１８（第４６図）及びＮＥＸＴステップ４６２２によって定義されたループに従ってひとたび処理されると、処理はテストステップ４６２４に進む。
【０３６９】
テストステップ４６２４において、実行エンジン８０２（第８図）は、エクスターナルモデル構造体１２００（第１２図）が、エクスターナルモデル構造体１２００によって表現されるエクスターナルの代わりに新たなリソースが生成されることを指定するか否かを判定する。実行エンジン８０２（第８図）は、フィールド“ｎｅｗ ｒｅｓｏｕｒｃｅｓ”１２１８（第１２図）とブール値“ｔｒｕｅ”とを比較することによってこの判定を行う。フィールド“ｎｅｗ ｒｅｓｏｕｒｃｅｓ”１２１８が“ｆａｌｓｅ”である場合には、処理はテストステップ４６２４（第４６図）からＮＥＸＴステップ４６３０を通って、ループステップ４６０６に進み、ここで次のエクスターナルが、上述のようにループステップ４６０６及びＮＥＸＴステップ４６３０により定義されるループに従って処理される。逆に、フィールド“ｎｅｗ ｒｅｓｏｕｒｃｅｓ”１２１８（第１２図）が“ｔｒｕｅ”である場合には、処理はテストステップ４６２４（第４６図）からステップ４６２６に進む。
【０３７０】
ステップ４６２６において、実行エンジン８０２（第８図）は、（ｉ）項目構造体、即ち項目構造体２７００（第２７図）及びリソース状態構造体、即ちリソース状態構造体３１００（第３１図）を生成してメモリ１０４（第１図）に格納し、（ｉｉ）リソース状態構造体３１００（第３１図）を指定するポインタをフィールド“ｒｅｓｏｕｒｃｅ”２７０２に格納して、リソース状態構造体３１００と項目構造体２７００（第２７図）とを関連付けることによって、新たなリソースを生成する。処理はステップ４６２６（第４６図）からステップ４６２８に進み、ここで実行エンジン８０２（第８図）が、新たな項目と、エクスターナルモデル構造体１２００（第１２図）によって表現されるエクスターナルとを連係させる。エクスターナルリスト構造体１４１４（第１５図）がそのエクスターナルを表現している場合には、フィールド“ｆｉｒｓｔ ｄｅｃｌ”１５０２（第１５図）が指定する宣言構造体１５０６のフィールド“ｉｔｅｍ”１６０８（第１６図）に、項目構造体２７００（第２７図）を指定するポインタを格納することによって、その項目がそのエクスターナルに関連付けられる。
【０３７１】
エクスターナルが呼び出される関数の戻り値項目である場合には、論理流れ図３３５２（第４６図）の始めにＮＵＬＬに設定されていた結果レコードが新たな項目に設定される。エクスターナルモデル構造体１２００のフィールド“ｔｙｐｅ”１２０４（第１２図）がそれを示している場合には、そのエクスターナルは、呼び出される関数の戻り値項目である。エクスターナルが呼び出される関数の戻り値項目でない場合には、そのエクスターナルを表現する宣言構造体１５０６のフィールド“ｉｔｅｍ”１６０８（第１６図）に新たな項目が形成される。
【０３７２】
ステップ４６２８（第４６図）から、処理はＮＥＸＴステップ４６３０を通ってループステップ４６０６に進み、ここで上述のように次のエクスターナルが処理される。呼び出される関数を表現する関数モデル構造体１１００のフィールド“ｆｉｒｓｔ ｅｘｔｅｒｎａｌ”１１０４（第１１図）及び“ｌａｓｔ ｅｘｔｅｒｎａｌ”１１０６によって指定されるエクスターナル構造体のシングルリンクトリストにおけるエクスターナル構造体によって表現されるエクスターナルの全てがひとたび処理されると、処理はループステップ４６０６（第４６図）からステップ４６３２に進む。ステップ４６３２において、実行エンジン８０２（第８図）は、呼び出される関数の実行のエミュレーションにより評価して得られた項目として、結果レコードを生成する。ステップ４６２８（第４６図）に関連して上述したように、この結果レコードはＮＵＬＬ値に初期化され、戻り値項目の代わりに新たなリソースが生成された場合には、戻り値項目の値に設定される。
【０３７３】
ステップ４６３２の終了後、処理は論理流れ図３３５２に従って、即ちステップ３３５２（第３３Ｅ図）に従って終了する。従って、呼び出される関数の挙動を表現するモデルを用いることによって、サブジェクト関数内に呼び出される関数に対する呼出しを評価して、呼び出される関数の実行のリソース及びエクスターナルに対する評価を解析することができる。
【０３７４】
メモリの集群
Ｃ言語に特有なことの１つは、あるメモリを、連続して割り当てられた配列として取り扱うことができるという点である。Ｃ言語においては、以下の型のメモリは、そのメモリが連続したブロックとして割り当てられたメモリであるかのようにアクセスすることができる。そのようなメモリの型とは、
（ｉ）命令“ｓｔｒｕｃｔ”若しくは“ａｒｒａｙ”を用いて定義された変数若しくはパラメータの何れかのデータ、即ち複合データ構造体若しくは配列、
（ｉｉ）関数にパラメータとして渡される任意のポインタ、
（ｉｉｉ）Ｃ言語において定義されている関数ｃａｌｌｏｃ  （）  若しくは関数ｍａｌｌｏｃ  （）  の実行により割り当てられるメモリである。
【０３７５】
本発明のここに開示する実施例では、連続して割り当てられるメモリをモデル化するためにメモリの集群（ｂｕｎｃｈ）を用いている。
【０３７６】
項目構造体は集群、即ち項目構造体の連続的な配列に割り当てられる。１つの整数、若しくは浮動小数点型変数の宣言を表現する項目構造体の場合についてのみ述べると、この集群は１つの項目構造体を含む。複合型の変数、即ち“ｓｔｒｕｃｔ”型及び配列の変数を表現する項目構造体の集群は、多重項目構造体によって表現され、その項目構造体のそれぞれは、４バイトの配列若しくは複合データの変数である。
【０３７７】
連続して割り当てられた項目構造体を有する連続して割り当てられたメモリを表現することにより、いくつかのイリーガルな配列参照の検出が可能となる。例えば、連続して割り当てられた項目構造体の集群の範囲内の項目構造体に対する参照は、その集群によって表現される配列のイリーガルな指標（ｉｎｄｅｘ）に対応する。更に、項目構造体を集群に形成することにより、上述のようなメモリのリークの検出も単純化される。例えば、集群とされた何らかの項目構造体が関数のエクスターナルによって到達可能な場合は、集群における各項目構造体にも、その関数のエクスターナルが到達可能である。
【０３７８】
上述のように、項目構造体２７００（第２７図）は、フィールド“ｆｉｒｓｔ ｉｎ ｂｕｎｃｈ”２７０８、フィールド“ｓｉｚｅ ｏｆ ｂｕｎｃｈ”２７１０、フィールド“ｈｅａｄ ｉｎ ｂｕｎｃｈ”２７１６、及びフィールド“ｋｎｏｗｎ ｂｕｎｃｈ ｓｉｚｅ”２７１８を含む。フィールド“ｆｉｒｓｔ ｉｎ ｂｕｎｃｈ”２７０８は、項目構造体２７００を含む項目構造体の集群における第１の項目構造体を指定するポインタである。項目構造体２７００が１つの集群における第１の項目構造体である場合には、フィールド“ｆｉｒｓｔ ｉｎ ｂｕｎｃｈ”２７０８が項目構造体２７００を指定する。フィールド“ｓｉｚｅ ｏｆ ｂｕｎｃｈ”２７１０は、項目構造体２７００を含む集群における項目構造体の数を示す。一実施例においては、フィールド”ｓｉｚｅ ｏｆ ｂｕｎｃｈ”２７１０が、所与の集群における第１の項目構造体においてのみ、そのように定義されている。
【０３７９】
フィールド“ｈｅａｄ ｉｎ ｂｕｎｃｈ”２７１６は、項目構造体２７００が、その項目構造体２７００を含む集群における第１項目構造体であるか否かを示すフラグである。フィールド“ｋｎｏｗｎ ｂｕｎｃｈ ｓｉｚｅ”２７１８は、項目構造体２７００を含む集群が既知のサイズを有するか否かを示すフラグである。集群が未知のサイズを有するのは、例えば、（ｉ）その集群が動的に割り当てられる、即ち関数ｍａｌｌｏｃ  （）  を呼び出すことによって割り当てられ、かつ実行エンジン８０２（第８図）が、要求されるメモリの量を計算するのに十分な情報を有していないとき、（ｉｉ）その集群がサブジェクト関数に引き渡される場合、若しくは（ｉｉｉ）その集群がその集群の各項目の追跡が実際には無理であるようなサイズを有する場合である。フィールド“ｋｎｏｗｎ ｂｕｎｃｈ ｓｉｚｅ”２７１８によって示されることにより集群が未知のサイズを有している場合には、実行エンジン８０２（第８図）は、その集群の範囲を逸脱する違反のチェックは行わない。
【０３８０】
付録Ａ（Ａｐｐｅｎｄｉｘ  Ａ）のコンピュータプログラムは、一実施例として、米国カリフォルニア州マウンテンビュー（ｍｏｕｎｔａｉｎ  ｖｉｅｗ）のサンマイクロシステムズ社（Ｓｕｎ  Ｍｉｃｒｏｓｙｓｔｅｍｓ）から入手可能なＳｕｎ  Ｓｐａｒｃｓｔａｔｉｏｎ（登録商標）コンピュータシステムのようなワークステーションに備えられている、ＵＮＩＸオペレーティングシステムＳｕｎＯＳ４．１．３、コンパイラ、及びリンカーを用いてコンパイルされ、リンクされた。第２実施例では、付録Ａのコンピュータプログラムは、マイクロソフト社のＶｉｓｕａｌ  Ｃ＋＋１．５コンパイラを用いてコンパイルされ、同社のＶｉｓｕａｌ  Ｃ＋＋リンカーを用いてリンクされた。これらのコンパイラ及びリンカーは、米国ワシントン州レッドモンド（Ｒｅｄｍｏｎｄ）のマイクロソフト社から発売されており、同様に同社から発売されているＭＳ  ＤＯＳ６．２オペレーティングシステム、Ｍｉｃｒｏｓｏｆｔ  Ｗｉｎｄｏｗｓ（登録商標）３．１を用いているパーソナルコンピュータ上で用いられる。使用できるパーソナルコンピュータには、米国カリフォルニア州サンフランシスコのＡｔｍａｎ社製のＡｒｔ４０００Ｓなどがある。付録Ａのコンピュータプログラムが適合する特定のコンピュータ言語や、付録Ａのコンピュータプログラムにより定義されたコンピュータプロセスが実行されるコンピュータシステムは、本発明における重要な側面ではない。当業者は、本明細書の記載内容を参照することにより、異なるコンピュータ言語及び／若しくは異なるコンピュータシステムを用いて本発明を実現できよう。
【０３８１】
付録Ａには複数のソースコードファイルが含まれており、これには本発明の別の実施例に基づき複数の関数及びデータ構造を定義するソースコードファイル“ｒｅａｄｉｎ．ｃ”の２つの別の実施例が含まれている。ソースコードファイル“ｒｅａｄｉｎ．ｃ”の第１実施例は、付録Ａのフレーム６４〜７４に現れており、ソースコードファイル“ｒｅａｄｉｎ．ｃ”の第２実施例は、付録Ａのフレーム７７〜８７に現れている。ソースコードファイルの実施例の一方のみが付録Ａの残りの部分とリンクされて、本発明の原理に基づくリソースチェッカを形成するということは理解されよう。
【０３８２】
以上の記述は本発明を説明するためのものであり、本発明をこれに限定するものではない。例えば、ここに開示した実施例はＣ言語における関数を分析しているが、本発明の原理は、以上の記述の内容に限定されることなく、他のコンピュータ命令プロトコルにも適用され得る。更に、本発明を実現したコンピュータプログラムを何らかの媒体に格納して提供することも可能である。本発明の範囲は、請求の範囲によってのみ限定される。
【０３８３】
2006252583.tif 000026
【０３８４】
2006252583.tif 000027
【０３８５】
2006252583.tif 000028
【０３８６】
2006252583.tif 000029
【０３８７】
2006252583.tif 000030
【０３８８】
2006252583.tif 000031
【０３８９】
2006252583.tif 000032
【０３９０】
2006252583.tif 000033
【０３９１】
2006252583.tif 000034
【０３９２】
2006252583.tif 000035
【０３９３】
2006252583.tif 000036
【０３９４】
2006252583.tif 000037
【０３９５】
2006252583.tif 000038
【０３９６】
2006252583.tif 000039
【０３９７】
2006252583.tif 000040
【０３９８】
2006252583.tif 000041
【０３９９】
2006252583.tif 000042
【０４００】
2006252583.tif 000043
【０４０１】
2006252583.tif 000044
【０４０２】
2006252583.tif 000045
【０４０３】
2006252583.tif 000046
【０４０４】
2006252583.tif 000047
【０４０５】
2006252583.tif 000048
【０４０６】
2006252583.tif 000049
【０４０７】
2006252583.tif 000050
【０４０８】
2006252583.tif 000051
【０４０９】
2006252583.tif 000052
【０４１０】
2006252583.tif 000053
【０４１１】
2006252583.tif 000054
【０４１２】
2006252583.tif 000055
【０４１３】
2006252583.tif 000056
【０４１４】
2006252583.tif 000057
【０４１５】
2006252583.tif 000058
【０４１６】
2006252583.tif 000059
【０４１７】
2006252583.tif 000060
【０４１８】
2006252583.tif 000061
【０４１９】
2006252583.tif 000062
【０４２０】
2006252583.tif 000063
【０４２１】
2006252583.tif 000064
【０４２２】
2006252583.tif 000065
【０４２３】
2006252583.tif 000066
【０４２４】
2006252583.tif 000067
【０４２５】
2006252583.tif 000068
【０４２６】
2006252583.tif 000069
【０４２７】
2006252583.tif 000070
【０４２８】
2006252583.tif 000071
【０４２９】
2006252583.tif 000072
【０４３０】
2006252583.tif 000073
【０４３１】
2006252583.tif 000074
【０４３２】
2006252583.tif 000075
【０４３３】
2006252583.tif 000076
【０４３４】
2006252583.tif 000077
【０４３５】
2006252583.tif 000078
【０４３６】
2006252583.tif 000079
【０４３７】
2006252583.tif 000080
【０４３８】
2006252583.tif 000081
【０４３９】
2006252583.tif 000082
【０４４０】
2006252583.tif 000083
【０４４１】
2006252583.tif 000084
【０４４２】
2006252583.tif 000085
【０４４３】
2006252583.tif 000086
【０４４４】
2006252583.tif 000087
【０４４５】
2006252583.tif 000088
【０４４６】
2006252583.tif 000089
【０４４７】
2006252583.tif 000090
【０４４８】
2006252583.tif 000091
【０４４９】
2006252583.tif 000092
【０４５０】
2006252583.tif 000093
【０４５１】
2006252583.tif 000094
【０４５２】
2006252583.tif 000095
【０４５３】
2006252583.tif 000096
【０４５４】
2006252583.tif 000097
【０４５５】
2006252583.tif 000098
【０４５６】
2006252583.tif 000099
【０４５７】
2006252583.tif 000100
【０４５８】
2006252583.tif 000101
【０４５９】
2006252583.tif 000102
【０４６０】
2006252583.tif 000103
【０４６１】
2006252583.tif 000104
【０４６２】
2006252583.tif 000105
【０４６３】
2006252583.tif 000106
【０４６４】
2006252583.tif 000107
【０４６５】
2006252583.tif 000108
【０４６６】
2006252583.tif 000109
【０４６７】
2006252583.tif 000110
【０４６８】
2006252583.tif 000111
【０４６９】
2006252583.tif 000112
【０４７０】
2006252583.tif 000113
【０４７１】
2006252583.tif 000114
【０４７２】
2006252583.tif 000115
【０４７３】
2006252583.tif 000116
【０４７４】
2006252583.tif 000117
【０４７５】
2006252583.tif 000118
【０４７６】
2006252583.tif 000119
【０４７７】
2006252583.tif 000120
【０４７８】
2006252583.tif 000121
【０４７９】
2006252583.tif 000122
【０４８０】
2006252583.tif 000123
【０４８１】
2006252583.tif 000124
【０４８２】
2006252583.tif 000125
【０４８３】
2006252583.tif 000126
【０４８４】
2006252583.tif 000127
【０４８５】
2006252583.tif 000128
【０４８６】
2006252583.tif 000129
【０４８７】
2006252583.tif 000130
【０４８８】
2006252583.tif 000131
【０４８９】
2006252583.tif 000132
【０４９０】
2006252583.tif 000133
【０４９１】
2006252583.tif 000134
【０４９２】
2006252583.tif 000135
【０４９３】
2006252583.tif 000136
【０４９４】
2006252583.tif 000137
【０４９５】
2006252583.tif 000138
【０４９６】
2006252583.tif 000139
【０４９７】
2006252583.tif 000140
【０４９８】
2006252583.tif 000141
【０４９９】
2006252583.tif 000142
【０５００】
2006252583.tif 000143
【０５０１】
2006252583.tif 000144
【０５０２】
2006252583.tif 000145
【０５０３】
2006252583.tif 000146
【０５０４】
2006252583.tif 000147
【０５０５】
2006252583.tif 000148
【０５０６】
2006252583.tif 000149
【０５０７】
2006252583.tif 000150
【０５０８】
2006252583.tif 000151
【０５０９】
2006252583.tif 000152
【０５１０】
2006252583.tif 000153
【０５１１】
2006252583.tif 000154
【０５１２】
2006252583.tif 000155
【０５１３】
2006252583.tif 000156
【０５１４】
2006252583.tif 000157
【０５１５】
2006252583.tif 000158
【０５１６】
2006252583.tif 000159
【０５１７】
2006252583.tif 000160
【０５１８】
2006252583.tif 000161
【０５１９】
2006252583.tif 000162
【０５２０】
2006252583.tif 000163
【０５２１】
2006252583.tif 000164
【０５２２】
2006252583.tif 000165
【０５２３】
2006252583.tif 000166
【０５２４】
2006252583.tif 000167
【０５２５】
2006252583.tif 000168
【０５２６】
2006252583.tif 000169
【０５２７】
2006252583.tif 000170
【０５２８】
2006252583.tif 000171
【０５２９】
2006252583.tif 000172
【０５３０】
2006252583.tif 000173
【０５３１】
2006252583.tif 000174
【０５３２】
2006252583.tif 000175
【０５３３】
2006252583.tif 000176
【０５３４】
2006252583.tif 000177
【０５３５】
2006252583.tif 000178
【０５３６】
2006252583.tif 000179
【０５３７】
2006252583.tif 000180
【０５３８】
2006252583.tif 000181
【０５３９】
2006252583.tif 000182
【０５４０】
2006252583.tif 000183
【０５４１】
2006252583.tif 000184
【０５４２】
2006252583.tif 000185
【０５４３】
2006252583.tif 000186
【０５４４】
2006252583.tif 000187
【０５４５】
2006252583.tif 000188
【０５４６】
2006252583.tif 000189
【０５４７】
2006252583.tif 000190
【０５４８】
2006252583.tif 000191
【０５４９】
2006252583.tif 000192
【０５５０】
2006252583.tif 000193
【０５５１】
2006252583.tif 000194
【０５５２】
2006252583.tif 000195
【０５５３】
2006252583.tif 000196
【０５５４】
2006252583.tif 000197
【０５５５】
2006252583.tif 000198
【０５５６】
2006252583.tif 000199
【０５５７】
2006252583.tif 000200
【０５５８】
2006252583.tif 000201
【０５５９】
2006252583.tif 000202
【０５６０】
2006252583.tif 000203
【０５６１】
2006252583.tif 000204
【０５６２】
2006252583.tif 000205
【０５６３】
2006252583.tif 000206
【０５６４】
2006252583.tif 000207
【０５６５】
2006252583.tif 000208
【０５６６】
2006252583.tif 000209
【０５６７】
2006252583.tif 000210
【０５６８】
2006252583.tif 000211
【０５６９】
2006252583.tif 000212
【０５７０】
2006252583.tif 000213
【０５７１】
2006252583.tif 000214
【０５７２】
2006252583.tif 000215
【０５７３】
2006252583.tif 000216
【０５７４】
2006252583.tif 000217
【０５７５】
2006252583.tif 000218
【０５７６】
2006252583.tif 000219
【０５７７】
2006252583.tif 000220
【０５７８】
2006252583.tif 000221
【０５７９】
2006252583.tif 000222
【０５８０】
2006252583.tif 000223
【０５８１】
2006252583.tif 000224
【図面の簡単な説明】
【０５８２】
【図１】第１図はコンピュータのブロック図である。
【図２】第２図は、コンピュータプロセスコンポーネント、そのコンポーネントのリソース、及び他のコンポーネントのブロック図である。
【図３Ａ】第３Ａ図は、本発明の一実施例に基づくリソースのモデル化を表した状態図である。
【図３Ｂ】第３Ｂ図は、本発明の一実施例に基づくリソースのモデル化を表した状態図である。
【図４Ａ】第４Ａ図は、本発明の一実施例に基づくエクスターナルのモデル化を表した状態図である。
【図４Ｂ】第４Ｂ図は本発明の一実施例に基づくエクスターナルのモデル化を表した状態図である。
【図５Ａ】第５Ａ図は本発明の一実施例に基づくエクスターナルのモデル化を表した状態図である。
【図５Ｂ】第５Ｂ図は本発明の一実施例に基づくエクスターナルのモデル化を表した状態図である。
【図６】第６図は本発明に基づくリソースチェッカ（resource checker）のブロック図である。
【図７】第７図は本発明に基づくリソースチェッカ（resource checker）のブロック図である。
【図８】第８図は、本発明に基づく動的検査エンジンのブロック図である。
【図９】第９図は、本発明に基づくコンピュータプログラムの解析の論理流れ図である。
【図１０】第１０図は、第９図の論理流れ図におけるモデルの初期化の論理流れ図である。
【図１１】第１１図は、本発明の実施例に基づく関数モデル構造体（function model structure）のブロック図である。
【図１２】第１２図は、本発明の実施例に基づくエクスターナルモデル構造体（external model structure）のブロック図である。
【図１３】第１３図は、関数モデル構造体及びその関数モデル構造体に関連付けられた２つのエクスターナルモデル構造体のブロック図である。
【図１４】第１４図は、本発明の実施例に基づく関数構造体（function structure）のブロック図である。
【図１５】第１５図は、本発明の実施例に基づくエクスターナルリスト構造体（external list structure）のブロック図である。
【図１６】第１６図は、本発明の実施例に基づく宣言構造体（declaration structure）のブロック図である。
【図１７】第１７図は、本発明の実施例に基づく型構造体（type structure）のブロック図である。
【図１８】第１８図は、本発明の実施例に基づくフィールド構造体（field structure）のブロック図である。
【図１９】第１９図は、２フィールドのデータオブジェクトのブロック図である。
【図２０】第２０図は、型構造体及び第１９図のデータオブジェクトを表す２つのフィールド構造体のブロック図である。
【図２１】第２１図は、本発明の実施例に基づくステートメント構造体（statement structure）のブロック図である。
【図２２】第２２図は、本発明の実施例に基づく式構造体（expression structure）のブロック図である。
【図２３】第２３図は、本発明の実施例に基づく式構造体、関連付けられた宣言構造体及び関連付けられた項目構造体（item structure）のブロック図である。
【図２４】第２４図は、本発明の実施例に基づく個々のコンピュータプログラムコンポーネントの解析の論理流れ図である。
【図２５】第２５図は、第２４図の論理流れ図中の一過程の論理流れ図である。
【図２６】第２６図は、第２４図の論理流れ図に基づくコンピュータプログラムコンポーネントの繰返し評価の一回分の論理流れ図である。
【図２７】第２７図は、本発明の実施例に基づく項目構造体（item structure）のブロック図である。
【図２８】第２８図は、本発明の実施例に基づくステートメントの解析の論理流れ図である。
【図２９】第２９図は、本発明の実施例に基づく式の評価の論理流れ図である。
【図３０】第３０図は、本発明の実施例に基づくエクスターナル構造体のブロック図である。
【図３１】第３１図は、本発明の実施例に基づくリソース構造体（resource structure）のブロック図である。
【図３２】第３２図は、本発明の実施例に基づく項目への演算の適用の論理流れ図である。
【図３３】分図の構成を示す構成図である。
【図３３Ａ】第３３Ａ図は、本発明の実施例に基づく演算子の処理の論理流れ図である。
【図３３Ｂ】第３３Ｂ図は、本発明の実施例に基づく演算子の処理の論理流れ図である。
【図３３Ｃ】第３３Ｃ図は、本発明の実施例に基づく演算子の処理の論理流れ図である。
【図３３Ｄ】第３３Ｄ図は、本発明の実施例に基づく演算子の処理の論理流れ図である。
【図３３Ｅ】第３３Ｅ図は、本発明の実施例に基づく演算子の処理の論理流れ図である。
【図３４】第３４図は、本発明の実施例に基づく宣言の処理の論理流れ図である。
【図３５】第３５図は、本発明の実施例に基づく“ｉｆ”ステートメントの処理の論理流れ図である。
【図３６】第３６図は、本発明に基づく論理演算子の処理の論理流れ図である。
【図３７】第３７図は、第３６図の論理流れ図の一過程の処理の論理流れ図である。
【図３８】第３８図は、第３６図の論理流れ図の別の過程の処理の論理流れ図である。
【図３９】第３９図は、本発明の実施例に基づく“ｒｅｔｕｒｎ”ステートメントの処理の論理流れ図である。
【図４０】第４０図は、本発明の実施例に基づく“ｂｌｏｃｋ”ステートメントの処理の論理流れ図である。
【図４１】第４１図は、本発明の一実施例に基づくリソースリークの検出の論理流れ図である。
【図４２】第４２図は、本発明の実施例に基づくエクスターナルの複合状態の合成の論理流れ図である。
【図４３】第４３図は、本発明の実施例に基づく関数の解析からの関数モデルの生成の論理流れ図である。
【図４４】第４４図は、第４３図の論理流れ図の一過程の処理の論理流れ図である。
【図４５】第４５図は、本発明の実施例に基づくある項目の値の別の項目への代入の論理流れ図である。
【図４６】第４６図は、本発明の一実施例に基づく被呼び出しルーチンのエミュレーションの論理流れ図である。
【図１】
2006252583.tif 000225
【図２】
2006252583.tif 000226
【図３Ａ】
2006252583.tif 000227
【図３Ｂ】
2006252583.tif 000228
【図４Ａ】
2006252583.tif 000229
【図４Ｂ】
2006252583.tif 000230
【図５Ａ】
2006252583.tif 000231
【図５Ｂ】
2006252583.tif 000232
【図６】
2006252583.tif 000233
【図７】
2006252583.tif 000234
【図８】
2006252583.tif 000235
【図９】
2006252583.tif 000236
【図１０】
2006252583.tif 000237
【図１１】
2006252583.tif 000238
【図１２】
2006252583.tif 000239
【図１３】
2006252583.tif 000240
【図１４】
2006252583.tif 000241
【図１５】
2006252583.tif 000242
【図１６】
2006252583.tif 000243
【図１７】
2006252583.tif 000244
【図１８】
2006252583.tif 000245
【図１９】
2006252583.tif 000246
【図２０】
2006252583.tif 000247
【図２１】
2006252583.tif 000248
【図２２】
2006252583.tif 000249
【図２３】
2006252583.tif 000250
【図２４】
2006252583.tif 000251
【図２５】
2006252583.tif 000252
【図２６】
2006252583.tif 000253
【図２７】
2006252583.tif 000254
【図２８】
2006252583.tif 000255
【図２９】
2006252583.tif 000256
【図３０】
2006252583.tif 000257
【図３１】
2006252583.tif 000258
【図３２】
2006252583.tif 000259
【図３３】
2006252583.tif 000260
【図３３Ａ】
2006252583.tif 000261
【図３３Ｂ】
2006252583.tif 000262
【図３３Ｃ】
2006252583.tif 000263
【図３３Ｄ】
2006252583.tif 000264
【図３３Ｅ】
2006252583.tif 000265
【図３４】
2006252583.tif 000266
【図３５】
2006252583.tif 000267
【図３６】
2006252583.tif 000268
【図３７】
2006252583.tif 000269
【図３８】
2006252583.tif 000270
【図３９】
2006252583.tif 000271
【図４０】
2006252583.tif 000272
【図４１】
2006252583.tif 000273
【図４２】
2006252583.tif 000274
【図４３】
2006252583.tif 000275
【図４４】
2006252583.tif 000276
【図４５】
2006252583.tif 000277
【図４６】
2006252583.tif 000278