JP5342508B2 - 情報処理装置及び情報処理方法及びプログラム - Google Patents
情報処理装置及び情報処理方法及びプログラム Download PDFInfo
- Publication number
- JP5342508B2 JP5342508B2 JP2010130320A JP2010130320A JP5342508B2 JP 5342508 B2 JP5342508 B2 JP 5342508B2 JP 2010130320 A JP2010130320 A JP 2010130320A JP 2010130320 A JP2010130320 A JP 2010130320A JP 5342508 B2 JP5342508 B2 JP 5342508B2
- Authority
- JP
- Japan
- Prior art keywords
- analysis
- variable
- unit
- argument
- code
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Expired - Fee Related
Links
Images
Description
特許文献2では、変数間の関係をグラフで表現しており、ポインタ型変数が直接指す変数だけでなく、ポインタ型変数が間接的に変数を指す場合も解析する。
比較的規模の大きなプログラムでは、機能の共通化等を目的として、大域変数名等を関数定義の中に直接記述せず、引数で与えられたアドレスに対する参照や代入を行う場合がある。
このような記述をしているソースコードの場合、上述した従来技術では、アドレスが代入された引数を対象とした解析ができないため、割り込み禁止の検査については検出漏れが発生し、自動並列化については該当箇所が並列化対象から外れてしまい並列度が上がらないなど、結果としてそれぞれの目的を達成できないという課題がある。
しかし、特許文献2ではポインタ解析の手順を開示しているのみであり、解析結果の出力形式については開示されていいないため、大域変数へのアクセス箇所を網羅的に特定することは困難である。
また、本発明は、上述の解析結果を用いて、大域変数とそのアドレスが格納された変数との関係を視覚的に表示することを主な目的とする。
大域変数及び局所変数が含まれるプログラムコードを解析対象プログラムコードとして指定するコード指定部と、
前記コード指定部により指定された解析対象プログラムコードに対する解析を行い、大域変数のアドレスの局所変数への代入と、いずれかのアドレスを格納する引数の局所変数への代入と、大域変数のアドレスを格納する局所変数の他の局所変数への代入と、いずれかのアドレスを格納する引数を格納する局所変数の他の局所変数への代入の少なくともいずれかと、いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出するコード解析抽出部と、
前記コード解析抽出部の抽出結果を記憶する抽出結果記憶部とを有することを特徴とする。
この実施の形態では、大域変数の参照、代入について、詳細な情報の提供を可能としたソースコード解析装置について説明する。
<A>大域変数の参照
<B>大域変数への代入
<C>いずれかのアドレスを格納した引数の参照
<D>局所変数への
(1)大域変数のアドレスの代入
(2)いずれかのアドレスを格納した関数の引数の代入
(3)大域変数のアドレスが格納されている局所変数の代入
(4)いずれかのアドレスを格納した関数の引数が格納されている局所変数の代入
<E>
(1)大域変数のアドレスが格納されている局所変数の参照
(2)いずれかのアドレスを格納する引数が格納されている局所変数の参照
<F>上記<D>の局所変数を介した、大域変数もしくは局所変数の参照
<G>上記<D>の局所変数を介した、大域変数もしくは局所変数への代入
<H>いずれかのアドレスを格納する関数の引数を介した、大域変数もしくは局所変数の参照
<I>いずれかのアドレスを格納する関数の引数を介した、大域変数もしくは局所変数への代入
<J>いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数
なお、図24のソースコード例は、C言語で記述されたものである。
本実施の形態では、ソースコード解析装置は、ソースコードの構文木と記号表を生成し、構文木と記号表を用いてソースコードを解析して上記の<A>〜<J>を抽出し、抽出結果を記憶する。
なお、構文木と記号表の生成は必須ではなく、構文木と記号表を用いずにソースコードを解析するようにしてもよい。
また、ソースコード解析装置は、呼び出し対象の関数が含まれているソースコードを識別し、当該ソースコードを新たな解析対象ソースコードとして指定するとともに、それまで解析を行っていた解析対象ソースコードに対する解析を中断し、新たな解析対象ソースコードに対する解析を開始し、新たな解析対象ソースコードに対する解析が終了した際に、新たな解析対象ソースコードの前に解析を行っていた解析対象ソースコードに対する解析を再開する。
そして、検査リストに追加した変数の組のXに相当する変数の参照と、Xへの代入(代入文においてXが左辺)と、Xを介した他の変数への代入(代入文において他の変数が左辺)と、他の変数へのXの代入(代入文において他の変数が左辺、Xが右辺)の少なくともいずれかが解析対象ソースコードに含まれているか否かを検査して抽出処理を行う。Xへの代入(代入文においてXが左辺)については、検査リストに格納した変数の組Xに対応するYの情報を代入文に基づき更新する。
また、ソースコード解析装置は、ある変数ZへXが代入されている場合(代入文におい変数Zが左辺、Xが右辺)に、当該変数Zがアドレスを格納する変数であるか否かを判断し、当該変数Zがアドレスを格納する変数である場合は、新しい変数の組(X’、Y’)を作成し、X’には当該変数Zを、Y’にはXに対応するYを設定して、検査リストに追加する。ただし、X’が検査リストに格納されている場合は、追加を行わず、Y’をYで更新する。
なお、提示方法はリスト形式以外でもよく、リストを加工して作成できるものであれば任意の形式でよい。
ソースコード解析装置1は、大域変数の参照・代入について詳細な解析結果を提供することを可能とした装置であり、動作の詳細は後述する。
記憶装置2は、例えばHDD(Hard Disk Drive)等の不揮発性記憶装置である。
記憶装置2は、ソースコード解析装置1への入力となるデータ、およびソースコード解析装置1からの出力を蓄積する。
また、関数呼び出しの記述がある場合は、記述された関数に対する解析を先に実行し、解析結果22に出力する。
解析結果165は、ソースコード解析装置1がソースコードを解析中の中間段階の解析結果である。
解析部14は、解析結果22に反映させる上記の<A>〜<J>を抽出する度に、逐次解析結果165に抽出結果を蓄積し、解析結果165を記憶装置2に移して解析結果22とするが、説明が煩雑になるのを避けるため、以下では、解析部14は解析結果22に抽出結果を蓄積するものとして説明する。
一時記憶部16は、抽出結果記憶部の例である。また、一時記憶部16による解析結果165の記憶処理が抽出結果記憶ステップとなる。
また、上記の説明では、表示部15及び解析結果加工部18をソースコード解析装置1の中に含むとしているが、ソースコード解析装置1とは別の装置(例えば「表示装置」)であっても構わない。
図2は構文木160を構成するノード1600の構造を示す図である。ノード1600はノード種別1601、構文規則番号1602、行番号1603、値種別1604、ノード値1605を備える。
ノード種別1601は、構文規則を構成する終端記号(ソースコード上に出現する識別子、演算子、特殊記号等)、もしくは非終端記号(ソースコードには出現せず、特定の終端記号の集合を表すもの)を識別するための情報である。
構文規則番号1602は、非終端記号に関する構文規則を一意に特定するための番号である。例えばある非終端記号が親ノードとなる木構造に対応する構文規則が2つ存在するとした場合、構文規則番号に1、2のいずれかを格納することで、該当する構文規則を特定できる。
行番号1603は、それぞれの終端記号について、ソースコード上の出現位置を意味する番号である。
値種別1604は、ノード値1605の種類を識別するための情報である。
ノード値1605は、ノード種別1601が非終端記号に属する場合は、子ノードの個数と各子ノードへの接続情報である。また、ノード種別1601が記号表161に格納される識別子の場合、ノード値1605は記号表の該当する識別子情報への接続情報である。また、ノード種別1601が識別子以外の終端記号の場合は、ノード値1605はソースコードに出現する予約語、特殊文字等の文字列である。
図3は記号表161の構造を示す図である。
記号表161には、識別子の数だけ識別子名1610、識別子種別1611、型指定子情報1612、宣言子情報1613、初期化子情報1614が存在する。すなわち、記号表161は、1つ以上の識別子名1610、識別子種別1611、型指定子情報1612、宣言子情報1613、初期化子情報1614から構成される組を備える。
識別子名1610は、ソースコード21に出現した識別子の名前である。
識別子種別1611は、識別子の種類を表す情報である。識別子種別1611に格納する値は、例えば、大域変数、静的変数、引数、局所変数等を意味する値である。
型指定子情報1612は、識別子名1610の型指定子に関する情報である。具体的には、型指定子という名前の非終端記号に対応するノードをルートとする構文木160の部分木に出現する終端記号、すなわち変数宣言の場合は変数名、関数宣言の場合は関数名と引数リスト等の記述となる。
宣言子情報1613は、識別子名1610の宣言子に関する情報である。具体的には、宣言子という名前の非終端記号に対応するノードをルートとする構文木160の部分木に出現する終端記号、すなわち変数宣言の場合は変数名、関数宣言の場合は関数名と引数リスト、等の記述となる。
初期化子情報1614は、識別子名1610の初期化子に関する情報である。具体的には、初期化子という名前の非終端記号に対応するノードをルートとする構文木160の部分木に出現する終端記号、すなわち代入する値の記述となる。図3では、大域変数gValのみに対して「20」と記述されており、大域変数gValが宣言と同時に20という値で初期化されることを意味する。
なお、説明のため、図3では記号表161の型指定子情報1612、宣言子情報1613、初期化子情報1614に型名、もしくは初期化値等を直接記述したが、構文木160の該当するノード1600への接続情報を格納してもよい。
図4は引数情報162の構造を示す図である。
引数情報162には、引数の数だけ実引数1620、仮引数1621、参照先識別子1622が存在する。すなわち、引数情報162は、0個以上の実引数1620、仮引数1621、参照先識別子1622から構成される組を備える。なお、引数のない関数呼び出しの場合は、実引数1620、仮引数1621、参照先識別子1622から構成される組の数が0個となる。
実引数1620は、ソースコード21に記述された関数呼び出しにある引数である。
仮引数1621は、ソースコード21に記述された関数定義、もしくは関数プロトタイプ宣言に記述されている引数である。
参照先識別子1622は、実引数1620が指している識別子である。具体的には、実引数1620がポインタ型の場合は実引数1620に格納されたアドレスにある識別子である。
図4では参照先識別子1622に「gVal」と記述されており、これはポインタ型の実引数1620(x)にはgValのアドレスが格納されていることを意味する。
さらに、仮引数1621(p)にgValのアドレスが格納されていることも意味する。
なお、実引数1620が非ポインタ型の場合、もしくは実引数1620がポインタ型でありかつ参照先が不明の場合、参照先識別子1622にはそれらの旨を意味する値を格納する。
階層値163は、ソースコード解析装置1による解析における、解析を開始する関数から、現在解析している関数に到達するまでの関数呼び出しの回数を示す値である。
図5は検査リスト164の構造を示す図である。
検査リスト164には、参照元識別子1640、逆参照演算子数1641、参照先識別子1642が存在する。すなわち、検査リスト164には、0個以上の参照元識別子1640、逆参照演算子数1641、参照先識別子1642から構成される組を備える。検査リスト164における、参照元識別子1640、逆参照演算子数1641、参照先識別子1642から構成される組の個数は、ソースコード解析装置における解析の実行中に増減する。
参照元識別子1640は、ソースコード21に記述された大域変数、引数、局所変数、関数等の識別子である。
逆参照演算子数1641は、ソースコード21における参照元識別子1640の左側に記述されている逆参照演算子「*」の個数である。ただし、ソースコード21における記述数より1だけ小さい値を設定し、最小値は0とする。
参照先識別子1642は、ソースコード21に記述された大域変数、引数、局所変数、関数等の識別子であり、参照元識別子1640がポインタ型の場合、当該参照元識別子に格納されたアドレスが指す領域に存在する識別子である。図5では、参照元識別子1640(x)がポインタ型変数とすると、「x」が「gVal」のアドレスを格納していることを表現している。すなわち、ソースコードには「x=&gVal」のような代入文があることを意味する。なお、参照元識別子1640が非ポインタ型の場合、もしくは参照元識別子1640がポインタ型でありかつ参照先が不明の場合、参照先識別子1642には参照元識別子1640と同じ内容を設定する。
以降の説明では、参照元識別子1640、逆参照演算子数1641、参照先識別子1642から構成される組を検査項目と記述する。
図6は関数定義ファイルリスト20の構造を示す図である。関数定義ファイルリスト20には、ソースコード解析装置1による解析に用いる1つ以上のソースコード21で定義されている関数の数だけ、関数名200、ソースファイル名201が存在する。すなわち、関数定義ファイルリストは、1つ以上の関数名200、ソースファイル名201から構成される組を備える。
関数名200は、ソースコード21に記述された関数定義における関数の名前である。
ソースファイル名201は、関数名200の関数定義が記述されているファイルの名前である。
図7はこの実施の形態の説明に用いるソースコード21を示す図である。
ソースコード21はC言語で記述されたプログラムである。
図7には、3つのソースコード21a、ソースコード21b、ソースコード21cが示されており、ファイル名はそれぞれ/src/funcA.c、/src/funcB.c、/src/funcC.cである。
ソースコード21aには、大域変数gValの宣言と関数f1の定義が記述されている。
ソースコード21bには、関数f2の定義が記述されている。
ソースコード21cには、関数f3の定義が記述されている。
なお、図7には示していないが、関数f1における関数f2の呼び出し、及び、関数f2における関数f3の呼び出しが可能なように、それぞれのソースコードには関数プロトタイプ宣言が記述されているものとする。
なお。この実施の形態ではC言語で記述されたソースコードを例として説明するが、他の言語を対象とすることも可能である。
図8は解析結果22の構造を示す図である。
解析結果22には、解析対象となる識別子に対する操作の回数だけ、識別子220、ソースファイル名221、行番号222、呼出階層223、操作種別224、設定値225、参照先識別子226が存在する。すなわち、解析結果22は、1つ以上の識別子220、ソースファイル名221、行番号222、呼出階層223、操作種別224、設定値225、参照先識別子226から構成される組を備える。
識別子220は操作された変数または関数である。識別子220には、逆参照演算子も含めて設定する。例えば、図8の末尾にある識別子220「*t」は、図7のソースコード21cの4行目にある「*t=100」の「t」を対象とした解析結果である。
ソースファイル名221は、識別子220への操作が記述されたファイルの名前である。
行番号222は、ソースファイル名221のファイルにおける、識別子220への操作の記述位置を示す番号である。
呼出階層223は、関数呼び出しの深さを示す情報である。図8では、解析を開始した関数f1に対しては0、関数f1が呼び出す関数f2に対しては1、関数f2が呼び出す関数f3に対しては2を出力している。
操作種別224は、識別子220への操作の種類を示す情報であり、「Read(参照)」「Set(アドレスの設定)」「Write(値の代入)」「Function(関数呼び出し)」を意味する値のいずれかが設定されている。なお、ソースコード解析装置1が代入を検出した場合、アドレスを代入する場合はSet、アドレス以外を代入する場合はWriteを操作種別224に出力する。
設定値225は、識別子220、もしくは識別子220が指す識別子に対して代入された値である。代入の発生しない操作の場合、ソースコード解析装置1は設定値225に何も設定しない。図8では、何も設定しない箇所に「―」を記述している。
参照先識別子226は、識別子220がポインタ型の場合(アドレスを格納する変数の場合)、当該識別子220に格納されたアドレスが指す領域に存在する識別子である。
換言すると、参照先識別子226は、アドレスを格納する変数が指す領域に相当する変数の識別子、つまり、いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数の識別子である。
このように、ソースコード解析装置1は、ソースコードを解析して、いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数を抽出する。
なお、識別子220が非ポインタ型の場合、もしくは識別子220がポインタ型でありかつ参照先が不明の場合、参照先識別子226には識別子220と同じ内容を設定する。
図9は、この実施の形態における、解析システムの使用者から入力を受けた入力部10の動作を示すフローチャートである。
(S101):入力部10は階層値163に0を設定する。この動作は階層値163の初期化に相当する。
(S102):入力部10は、解析結果22を開く。
(S103):入力部10は、S100にて取得した関数名と、空の引数情報をソースファイル特定部11に渡す。空の引数情報とは、実引数1620、仮引数1621、参照先識別子1622の組を1つも持たない引数情報162であることを意味する。
(S104):入力部10は、初期化処理を完了する。
図10は、この実施の形態における、ソースファイル特定部11の動作を示すフローチャートである。
(S111):ソースファイル特定部11は、関数定義ファイルリスト20を読み込む。この実施の形態では、関数定義ファイルリスト20は解析システムを用いた解析の実行前に予め準備されており、図6に示す内容が記録されているとする。
(S112):ソースファイル特定部11は、関数定義ファイルリスト20の関数名200に、入力部10もしくは解析部14から渡された関数名が存在するか判定する。存在すると判定した場合(S112でYes)は、S113に進む。一方、存在しないと判定した場合(S112でNo)は、S114に進む。
(S113):ソースファイル特定部11は、関数定義ファイルリストから該当する関数名200、及びソースファイル名201を取り出し、ソースコード展開部12に渡す。
(S114):ソースファイル特定部11は、処理を完了する。
図11は、この実施の形態における、ソースコード展開部12の動作、及び検査リスト操作部17の動作の一部を示すフローチャートである。
なお、以降はソースファイル名201に対応するソースコード21は記憶装置2に存在するものとして説明する。
(S121):ソースコード展開部12は、ソースコード21を読み込み、構文木160を作成する。構文木160の作成方法について概要を述べる。まず、ソースコード21に対して字句解析を行って終端記号を取り出し、ノード1600を作成し、スタックに蓄積する。次に、ノードの並びが構文規則と一致した場合、前記一致した1つ以上のノードをスタックから取り出し、さらに、取り出した1つ以上のノードを子ノードとする非終端記号を表すノードを作成し、作成したノードをスタックに蓄積する。これらの処理をソースコード21の終端まで繰り返すことで、構文木160を作成する。
(S122):ソースコード展開部12は、ソースコード21を読み込み、記号表161を作成する。記号表161の作成方法について概要を述べる。ソースコード21から宣言もしくは定義を読み取り、構文規則に基づき、識別子名1610から初期化子情報1614までの5つの情報を取り出し、記号表161に追加する。識別子種別1611の判定は、宣言もしくは定義が記述されているソースコード21内の位置に基づき行う。例えば、図3の「gVal」は、図7のソースコード21aにおいて関数定義の外部に記述されているため、識別子種別1611に「大域変数」を設定する。
(S123):ソースコード展開部12は、検査リスト操作部17に検査リスト164の作成を指示する。検査リスト操作部17は、検査リスト164を作成する。作成された検査リストは、検査項目をまったく持たない。なお、検査リスト164は、解析する関数毎に作成する。
(S124):ソースコード展開部12は、検査リスト操作部17に検査項目の追加を依頼する。追加対象となる識別子は、記号表161にある大域変数、関数である。検査リスト操作部17は、ソースコード展開部12から渡された識別子に基づき、参照元識別子1640及び参照先識別子1642には前記渡された識別子、逆参照演算子数1641には0を設定した検査項目を作成し、検査リスト164に追加する。なお、記号表161に大域変数、関数が存在しない場合、検査リスト164には何も追加しない。
(S125):ソースコード展開部12は処理を完了する。
図12は、この実施の形態における、引数情報設定部13の動作、及び検査リスト操作部17の動作の一部を示すフローチャートである。
(S131):引数情報設定部13は、ソースファイル特定部11に渡された引数情報162に格納された、実引数1620、仮引数1621、参照先識別子1622の組の数を判定する。0個より多い場合(S131でYes)は、S132に進む。一方、0個の場合(S131でNo)は、S137に進む。
(S132):引数情報設定部13は、記号表161から仮引数1621に対応する識別子名1610を探索し、前記識別子名1610に対応する型指定子情報1612、及び宣言子情報1613を取り出す。前記型指定子情報1612、及び宣言子情報1613から、仮引数1621がアドレスを格納する型であると判定した場合(S132でYes)は、S133に進む。一方、仮引数1621がアドレスを格納する型ではないと判定した場合(S132でNo)は、S135に進む。
(S133):引数情報設定部13は、仮引数1621、及び参照先識別子1622を検査リスト操作部17に渡し、検査リスト164への追加を指示する。検査リスト操作部17は、参照元識別子1640に仮引数1621、逆参照演算子数1641に0、参照先識別子1642に参照先識別子1622を設定した検査項目を作成し、検査リスト164に追加するとともに、引数情報設定部13に、前記作成した検査項目の参照先識別子1642を渡す。
(S134):引数情報設定部13は、記号表161から仮引数1621に対応する宣言子情報1613を探す。続いて、識別子220に仮引数1621、ソースファイル名221にソースコード展開部12に渡されたソースファイル名201、行番号222に前記宣言子情報1613に対応する構文木160のノード1600の行番号1603、呼出階層223に階層値163、操作種別224にアドレスの設定を意味する値、設定値225に実引数1620、参照先識別子226に検査リスト操作部17から渡された参照先識別子1642を格納する組を、解析結果22に記録する。
(S135):引数情報設定部13は、引数情報162における、S132に実行対象を次に進める。
(S136):引数情報設定部13は、引数情報162全体に対して、S132が実行されたか判定する。実行されたと判定した場合(S136でYes)は、S137に進む。一方、実行されていないと判定した場合(S136でNo)は、S132に進む。
(S137):引数情報設定部13は、処理を完了する。
図13は、この実施の形態における解析部14の動作、及び検査リスト操作部17の動作の一部を示すフローチャートである。なお、解析部14の動作は図13、図14、図15の3つに分けているが、図14、図15は個々の宣言もしくは代入文に対する解析処理を示したものであり、図13は図14、図15に示した解析処理の前後に行う処理を示したものである。
(S141):解析部14は、構文木160にて、ソースファイル特定部11が指定した関数名200の関数定義に対応するノードに移動する。以降は、移動対象のノードの子ノードを用いて解析を行う。
(S142):解析部14は、構文木160における1つの宣言、もしくは1つの代入文に相当する部分木を、ノード種別1601、構文規則番号1602、値種別1604、及びノード値1605を用いて決定し、前記決定した部分木が宣言に相当するか、代入文に相当するかを判定する。宣言と判定した場合(S142で「宣言」)は、S143に進む。一方、代入文と判定した場合はS144に進む。
(S143):解析部14は、S142で決定した部分木を用いて宣言に対する解析を行う。詳細な動作は後述する。
(S144):解析部14は、S142で決定した部分木を用いて代入文に対する解析を行う。詳細な動作は後述する。
(S145):解析部14は、S142で決定した宣言、もしくは代入文の次に位置づけられる宣言、もしくは代入文を、S142と同様の方法で決定する。さらに、次の宣言、もしくは代入文を決定する処理にてブロック文の末尾に到達した場合、解析部14は、検査リスト操作部17に対して、有効範囲から外れた局所変数を参照元識別子1640格納した検査項目を検査リスト164から削除するように指示する。検査リスト操作部17は、検査リスト164に格納されたそれぞれの検査項目の参照元識別子1640に対して、構文木160、および記号表161を用いて宣言箇所を特定し、現在解析しているブロックの中で宣言されている場合は当該検査項目を削除する。
(S146):解析部14は、関数定義の末尾に到達しているか判定する。到達していると判定した場合(S146でYes)は、S147に進む。一方、到達していないと判定した場合(S146でNo)は、S142に進む。なお、S142およびS145では、宣言もしくは代入文のいずれでもない部分は読み飛ばす。
(S147):解析部14は、検査リスト164を破棄する。また、構文木160及び記号表161も破棄する。
(S148):解析部14は、処理を完了する。
図14は、この実施の形態における解析部14の宣言解析の動作、及び検査リスト操作部17の動作の一部を示すフローチャートであり、図13のS143に相当する。
(S151):解析部14は、宣言に対応する構文木160の部分木を用いて、宣言された識別子が初期化されているかを判定する。初期化されていると判定した場合(S151でYes)は、S152に進む。一方、初期化されていないと判定した場合(S151でNo)は、S157に進む。
(S152):解析部14は、宣言に対応する構文木160の部分木のうち初期化式に対応する部分を用いて、初期化式に対する代入文解析を実行する。詳細な動作は後述する。
(S153):解析部14は、宣言に対応する構文木160の部分木を用いて、宣言された識別子の型を特定し、アドレスを格納する型か否かを判定する。アドレスを格納する型であると判定した場合(S153でYes)は、S154に進む。一方、アドレスを格納する型ではないと判定した場合(S154でNo)は、S157に進む。
(S154):解析部14は、宣言に対応する構文木160の部分木を用いて、S152で解析した初期化式に検査リスト164に格納されている識別子が含まれているか否かの判定を、検査リスト操作部17に指示する。検査リスト操作部17は、解析部14から初期化式を受け取り、前期初期化式に、検査リスト164の検査項目の参照元識別子1640に一致し、かつ逆参照識別子の個数(1個以下の場合は0、2個以上の場合は個数から1減じた値)が検査項目の逆参照演算子数1641に一致する識別子が出現しているかを判定する。出現していると判定した場合(S154でYes)は、S155に進む。一方、出現していないと判定した場合(S154でNo)は、S157に進む。
(S155):検査リスト操作部17は、参照元識別子1640に当該宣言された識別子、逆参照演算子数1641に0、参照先識別子1642にS154にて一致した検査リスト164の格納要素の参照先識別子1642を設定した検査項目を作成し、検査リスト164に追加するとともに、解析部14に、前記作成した検査項目の参照先識別子1642を渡す。
(S156):解析部14は、記号表161から宣言された識別子に対応する宣言子情報1613を探索する。続いて、識別子220に宣言された識別子、ソースファイル名221にソースコード展開部12に渡されたソースファイル名201、行番号222に前記宣言子情報1613に対応する構文木160のノード1600の行番号1603、呼出階層223に階層値163、操作種別224にアドレスの設定を意味する値、設定値225に初期化式全体、参照先識別子226に検査リスト操作部17から渡された参照先識別子1642を格納する組を、解析結果22に記録する。
(S157):解析部14は、宣言に対する解析を終了する。
図15は、この実施の形態における解析部14の代入文解析の動作、及び検査リスト操作部17の動作の一部を示すフローチャートであり、図13のS144に相当する。
(S161):解析部14は、代入文に対応する構文木160の部分木を用いて、関数呼び出しがあるか判定する。関数呼び出しがあると判定した場合(S161でYes)は、S162に進む。一方、関数呼び出しがないと判定した場合(S161でNo)は、S164に進む。
(S162):解析部14は、関数呼出解析を行う。動作の詳細は後述する。
(S163):解析部14は、代入文に対応する構文木160の部分木を用いて、次の関数呼び出しを探索する。
(S164):解析部14は、代入文に対応する構文木160の部分木から、参照されている識別子を抽出し、検査リスト操作部17に対して、参照元識別子1640が前記識別子に一致する検査項目が検査リスト164に格納されているか検索するよう指示する。検査リスト操作部17は、検査リスト164に格納されているそれぞれの検査項目に対して、参照元識別子1640が前記識別子と一致し、かつ、逆参照演算子数1641が0に一致するかを判定する。一致する検査項目が存在する場合(S164でYes)は、検査リスト操作部17は前記一致する検索項目の参照先識別子1642を解析部14に渡し、S165に進む。一方、一致する検査項目が存在しない場合(S164でNo)は、S166に進む。
(S165):解析部14は、記号表161から参照されている識別子に対応する宣言子情報1613を探索する。続いて、解析部14は、識別子220に前記参照されている識別子、ソースファイル名221にソースファイル名221にソースコード展開部12に渡されたソースファイル名201、行番号222に前記宣言子情報1613に対応する構文木160のノード1600の行番号1603、呼出階層223に階層値163、操作種別224に参照を意味する値、設定値225に設定値なしを意味する値、参照先識別子226に検査リスト操作部17から渡された参照先識別子1642を格納する組を、解析結果22に記録する。
(S166):解析部14は、代入文に対応する構文木160の部分木及び記号表161から、ポインタ型識別子を介した代入が行われているか否かを判定し、行われている場合は前記ポインタ型識別子及びそのポインタ型識別子に対する逆参照演算子の個数を抽出し、検査リスト操作部17に対して前記識別子及び逆参照演算子の個数に一致する検査項目が検査リスト164に格納されているか検索するよう指示する。検査リスト操作部17は、検査リスト164に格納されているそれぞれの検査項目に対して、参照元識別子1640が前記識別子と一致し、かつ、逆参照演算子数1641が前記逆参照演算子の個数(1個以下の場合は0、2個以上の場合は個数から1減じた値)に一致するかを判定する。一致する検査項目が存在する場合(S166でYes)は、検査リスト操作部17は前記一致する検索項目の参照先識別子1642を解析部14に渡し、S167に進む。一方、一致する検査項目が存在しない場合(S166でNo)は、S169に進む。
(S167):解析部14は、代入文の左辺に対応する構文木160の部分木、及び記号表161を用いて、左辺の型を特定する。
(S168):解析部14は、記号表161から左辺の識別子に対応する宣言子情報1613を探索する。続いて、解析部14は、識別子220に前記識別子及び前記識別子に対する逆参照演算子、ソースファイル名221にソースファイル名221にソースコード展開部12に渡されたソースファイル名201、行番号222に前記宣言子情報1613に対応する構文木160のノード1600の行番号1603、呼出階層223に階層値163、操作種別224にS167で特定した型に基づきアドレスの設定もしくは値の代入を意味する値、設定値225に右辺全体、参照先識別子226に検査リスト操作部17から渡された参照先識別子1642を格納する組を、解析結果22に記録する。
(S169):解析部14は、代入文に対応する構文木160の部分木から、代入対象の識別子を抽出し、検査リスト操作部17に対して前記識別子に一致する検査項目が検査リスト164に格納されているか検索するよう指示する。検査リスト操作部17は、検査リスト164に格納されているそれぞれの検査項目に対して、参照元識別子1640が前記識別子と一致し、かつ、逆参照演算子数1641が0に一致するかを判定する。一致する検査項目が存在する場合(S166でYes)は、検査リスト操作部17は前記一致する検索項目の参照先識別子1642を解析部14に渡し、S167に進む。一方、一致する検査項目が存在しない場合(S166でNo)は、S170に進む。
(S170):解析部14は、代入文に対応する構文木160の部分木から、代入されている(代入文の右辺にある)識別子及びその識別子に対する逆参照演算子の個数を抽出し、検査リスト操作部17に対して前記識別子及び逆参照演算子の個数に一致する検査項目が検査リスト164に格納されているか検索するよう指示する。検査リスト操作部17は、検査リスト164に格納されているそれぞれの検査項目に対して、参照元識別子1640が前記識別子と一致し、かつ、逆参照演算子数1641が前記逆参照演算子の個数(1個以下の場合は0、2個以上の場合は個数から1減じた値)に一致するかを判定する。一致する検査項目が存在する場合(S170でYes)は、検査リスト操作部17は前記一致する検索項目の参照先識別子1642を解析部14に渡し、S171に進む。一方、一致する検査項目が存在しない場合(S170でNo)は、S176に進む。
(S171):解析部14は、代入文の左辺に対応する構文木160の部分木、及び記号表161を用いて、左辺の型を特定する。左辺の型がアドレスを格納する型であると判定した場合(S171でYes)は、S172に進む。一方、左辺の型がアドレスを格納する型でない場合(S171でNo)は、S176に進む。
(S172):解析部14は、代入文に対応する構文木160の部分木から、代入対象の識別子、及びその識別子に対する逆参照演算子の個数を抽出し、検査リスト操作部17に対して前記識別子及び逆参照演算子の個数に一致する検査項目が検査リスト164に格納されているか検索するよう指示する。検査リスト操作部17は、検査リスト164に格納されているそれぞれの検査項目に対して、参照元識別子1640が前記識別子と一致し、かつ、逆参照演算子数1641が前記逆参照演算子の個数(1個以下の場合は0、2個以上の場合は個数から1減じた値)に一致するかを判定する。一致する検査項目が存在する場合(S172でYes)は、検査リスト操作部17は前記一致する検査項目を解析部14に渡し、S174に進む。一方、一致する検査項目が存在しない場合(S172でNo)は、S173に進む。
(S173):解析部14は、S172における代入対象の識別子、その識別子に対する逆参照演算子の個数、S170における検査リスト操作部17から渡された参照先識別子1642を検査リスト操作部17に渡し、検査リスト164に対する検査項目の追加を指示する。検査リスト操作部17は、参照元識別子1640に前記代入対象の識別子、逆参照演算子数1641に前記逆参照演算子の個数(1個以下の場合は0、2個以上の場合は個数から1減じた値)、参照先識別子1642に前記S170で得た参照先識別子1642を設定した検査項目を作成し、検査リスト164に追加する。また、検査リスト操作部17は、前記追加した検査項目の参照先識別子1642を解析部14に渡す。
(S174):解析部14は、S172における検査リスト操作部17から渡された検査項目、及びS170における検査リスト操作部17から渡された参照先識別子1642を検査リスト操作部17に渡し、検査リスト164の更新を指示する。検査リスト操作部17は、前記検査項目と一致する検査項目を検査リスト164から特定し、特定した検査項目の参照先識別子1642を前記参照先識別子1642に書き換える。また、検査リスト操作部17は、前記更新した検査項目の参照先識別子1642を解析部14に渡す。
(S175):解析部14は、記号表161から左辺の識別子に対応する宣言子情報1613を探索する。続いて、解析部14は、識別子220に前記識別子及び前記識別子に対する逆参照演算子、ソースファイル名221にソースファイル名221にソースコード展開部12に渡されたソースファイル名201、行番号222に前記宣言子情報1613に対応する構文木160のノード1600の行番号1603、呼出階層223に階層値163、操作種別224にS167で特定した型に基づきアドレスの設定もしくは値の代入を意味する値、設定値225に右辺全体、参照先識別子226に検査リスト操作部17から渡された参照先識別子1642を格納する組を、解析結果22に記録する。
(S176):解析部14は、代入文に対する解析を終了する。
図16は、この実施の形態における解析部14の関数呼出解析の動作、及び検査リスト操作部17の動作の一部を示すフローチャートであり、図15のS162に相当する。
(S181):解析部14は、空の引数情報162Nを作成する(現在解析中の関数に対応した引数情報162と区別するため引数情報162Nとする)。
(S182):解析部14は、関数呼び出しに対応する構文木160の部分木を用いて、引数の個数を数える。
(S183):解析部14は、S182で数え上げた引数の個数分、引数情報162に実引数1620、仮引数1621、参照先識別子1622の組を追加したかを判定する。追加したと判定した場合(S183でYes)は、S190に進む。一方、追加していないと判定した場合(S183でNo)は、S184に進む。
(S184):解析部14は、関数呼び出しに対応する構文木160の部分木を用いて、引数が関数呼び出しか否かを判定する。引数が関数呼び出しであると判定した場合(S184でYes)は、S185に進む。一方、引数が関数呼び出しでないと判定した場合(S184でNo)は、S186に進む。
(S185):解析部14は、引数にある関数を対象とした関数呼出解析を実行する。すなわち、S180から開始する処理を再帰的に実行する。
(S186):解析部14は、関数呼び出しに対応する構文木160の部分木、及び記号表161を用いて、引数の型がアドレスを格納する型であるか否かを判定する(条件ア)。次に、解析部14は、関数呼び出しに対応する構文木160の部分木(引数に相当する部分)を用いて、検査リスト操作部17に対して検索を指示する。検査リスト操作部17は、前記部分木から引数に相当する識別子、及び逆参照演算子の個数を特定し、検査リスト164に、参照元識別子1640が前記引数に相当する識別子に一致し、かつ逆参照演算子数が前記逆参照演算子の個数(1個以下の場合は0、2個以上の場合は個数から1減じた値)に一致するする検査項目があるか判定する(条件イ)。条件アが真であり、かつ条件イが偽の場合(S186でYes)は、S187に進む。一方、条件アが真、かつ条件イが偽を満たさない場合(S186でNo)は、S188に進む。
(S187):解析部14は、S186で特定した引数に相当する識別子、及び逆参照演算子の個数を用いて、検査リスト操作部17に検査項目の追加を指示する。検査リスト操作部17は、参照元識別子1640に前記識別子、逆参照演算子数1641に前記逆参照演算子の個数(1個以下の場合は0、2個以上の場合は個数から1減じた値)、参照先識別子1642に前記識別子を設定した検査項目を作成し、検査リスト164に追加する。また、検査リスト操作部17は、前記追加した検査項目の参照先識別子1642を解析部14に渡す。
(S188):解析部14は、解析結果22を用いて、実引数1620にS186で特定した引数に相当する識別子、仮引数1621に呼び出されている関数のプロトタイプ宣言もしくは定義に記述されている仮引数に相当する識別子、参照先識別子1622にS187において検査リスト操作部17から渡された参照先識別子1642を格納した、実引数1620、仮引数1621、参照先識別子1622の組を作成し、引数情報162Nに追加する。
(S189):解析部14は、次の引数に対する処理に移る。
(S190):解析部14は、階層値163を1増加させる。
(S191):解析部14は、関数名には関数呼び出しに記述されている関数の名前、引数情報には引数情報162N、もしくは空の引数情報を設定して、ソースファイル特定部11を実行する。
(S192):解析部14は、階層値163を1減少させる。
(S193):解析部14は、引数情報162Nを破棄する。
(S194):解析部14は、関数呼出解析を終了する。
最後に、入力部10に渡された関数について、解析部14による解析が完了すると、解析部14は、解析結果22を閉じる(図示せず)。
(ソースファイル特定部11[f1]):関数定義ファイルリスト120を読み込み(S111)、関数f1の存在を判定し(S112)、関数名200(f1)、及びソースファイル名(/src/funcA.c)をソースコード展開部12に渡す(S113)。
(ソースコード展開部12[f1]):/src/funcA.cを読み込み、構文木160a、及び記号表161aを作成する(S121、S122)。続いて、空の、すなわち検査項目を持たない検査リスト164aを作成し(S123)、参照元識別子1640に「gVal」、逆参照識別子数1641に0、参照先識別子1642に「gVal」を設定した検査項目と、参照元識別子1640に「f1」、逆参照識別子数1641に0、参照先識別子1642に「f1」を設定した検査項目を、検査リスト164aに追加する(S124)。
(引数情報設定部13[f1]):引数情報162aは空であるため(S131でNo)、S137に到達する。
(解析部14[f1:行番号7]):「gVal=0」に対する代入文解析を実行する(S144)。逆参照演算子数が0のgValは検査リスト164aに格納されているため、gVal=0に対する代入文解析の流れは、S161でNo、S164でNo、S166でNo、S169でYes、S170でNoであるため、左辺の型がアドレスを格納する型ではないため、gValに対する値の代入を解析結果22に記録し(S167、S168)、代入文解析を終了する(S176)。
(解析部14[f1:行番号8]):「x=&gVal」に対する代入文解析を実行する(S144)。逆参照演算子数が0のgValは検査リスト164aに格納されており、逆参照演算子数が0のxは検査リスト164aに格納されていない。また、xの型はアドレスを格納する型である。したがって、x=&gValに対する代入文解析の流れは、S161でNo、S164でYes、S166でNo、S169でNo、S170でYes、S171でYes、S172でNoであるため、アドレスを格納する変数xが指す領域に相当する変数(アドレスを通じて指し示している他の変数)であるgValの参照を解析結果22に記録し(S165)、参照元識別子1640に「x」、逆参照識別子数1641に0、参照先識別子1642に「gVal」を格納した検査項目を、検査リスト164aに追加し、xに対するアドレスの設定を解析結果22に記録し(S173、S175)、代入文解析を終了する(S176)。
(解析部14[f1:行番号9]):「y=f2(x)」に対する代入文解析を実行する(S144)。代入文解析の流れは、まず、S161でYesとなるため、関数呼出解析を実行する(S162)。関数呼出解析では、引数情報162bを作成し(S181)、引数xに対応した実引数1620(x)、仮引数1621(p)、参照先識別子1622(gVal)の組を引数情報162bに追加し(S184〜S189)、関数名「f2」、及び引数情報162bをソースファイル特定部11に渡す(S191)。
(ソースファイル特定部11[f2]):関数定義ファイルリスト120を読み込み(S111)、関数f2の存在を判定し(S112)、関数名200(f2)、及びソースファイル名(/src/funcB.c)をソースコード展開部12に渡す(S113)。
(引数情報設定部13[f2]):引数情報162bは空ではなく(S131でYes)、仮引数pの型がアドレスを格納する型であるため(S132でYes)、参照元識別子1640に「p」、逆参照識別子数1641に0、参照先識別子1642に「gVal」を設定した検査項目を作成し、検査リスト164bに追加し(S133)、pに対するアドレスの設定を解析結果22に記録し(S134)、引数情報設定処理を終了する(S137)。
(解析部14[f2:行番号3]):「int *q=p」に対する宣言解析を実行する(S143)。この宣言は、初期化を行っているため(S151でYes)、初期化式、すなわちpに対する代入文解析を実行する(S152)。逆参照演算子数が0のpは検査リスト164bに格納されているため、pに対する代入文解析の流れは、S161でNo、S164でYes、S166でNo、S169でNo、S170でNoであるため、pの参照を解析結果22に記録し(S165)、代入文解析を終了する(S176)。続いて、局所変数qはアドレスを格納する型であり(S153でYes)、逆参照識別子数が0のpは検査リスト164bに格納されているため(S154でYes)、参照元識別子1640に「q」、逆参照識別子数1641に0、参照先識別子1642に「gVal」を設定した検査項目を作成し、検査リスト164bに追加し(S155)、qに対するアドレスの設定を解析結果22に記録し(S156)、宣言解析処理を終了する(S157)。
(解析部14[f2:行番号4]):「int *r=q」に対する宣言解析を実行する(S143)。この宣言は、初期化を行っているため(S151でYes)、初期化式、すなわちqに対する代入文解析を実行する(S152)。逆参照演算子数が0のqは検査リスト164bに格納されているため、qに対する代入文解析の流れは、S161でNo、S164でYes、S166でNo、S169でNo、S170でNoであるため、qの参照を解析結果22に記録し(S165)、代入文解析を終了する(S176)。続いて、局所変数rはアドレスを格納する型であり(S153でYes)、逆参照識別子数が0のqは検査リスト164bに格納されているため(S154でYes)、参照元識別子1640に「r」、逆参照識別子数1641に0、参照先識別子1642に「gVal」を設定した検査項目を作成し、検査リスト164bに追加し(S155)、rに対するアドレスの設定を解析結果22に記録し(S156)、宣言解析処理を終了する(S157)。
(解析部14[f2:行番号5]):「int *s=r」に対する宣言解析を実行する(S143)。この宣言は、初期化を行っているため(S151でYes)、初期化式、すなわちrに対する代入文解析を実行する(S152)。逆参照演算子数が0のrは検査リスト164bに格納されているため、rに対する代入文解析の流れは、S161でNo、S164でYes、S166でNo、S169でNo、S170でNoであるため、rの参照を解析結果22に記録し(S165)、代入文解析を終了する(S176)。続いて、局所変数sはアドレスを格納する型であり(S153でYes)、逆参照識別子数が0のrは検査リスト164bに格納されているため(S154でYes)、参照元識別子1640に「s」、逆参照識別子数1641に0、参照先識別子1642に「gVal」を設定した検査項目を作成し、検査リスト164bに追加し(S155)、sに対するアドレスの設定を解析結果22に記録し(S156)、宣言解析処理を終了する(S157)。
(解析部14[f2:行番号6]):「int b=*r」に対する宣言解析を実行する(S143)。この宣言は、初期化を行っているため(S151でYes)、初期化式、すなわち*rに対する代入文解析を実行する(S152)。逆参照演算子数が0のrは検査リスト164bに格納されているため、*rに対する代入文解析の流れは、S161でNo、S164でYes、S166でNo、S169でNo、S170でNoであるため、rの参照を解析結果22に記録し(S165)、代入文解析を終了する(S176)。続いて、局所変数bはアドレスを格納する型ではないため(S153でNo)、宣言解析を終了する(S157)。
(解析部14[f2:行番号8]):「*s=0」に対する代入文解析を実行する(S144)。逆参照演算子数が0(コード上は1個だが1個の場合は0として扱う)のsは検査リスト164bに格納されている。また、*sの型はアドレスを格納する型ではない。したがって、*s=0に対する代入文解析の流れは、S161でNo、S164でNo、S166でYes、S170でNoであるため、*sに対する値の代入を解析結果22に記録(S167、S168)し、代入文解析を終了する(S176)。
(解析部14[f2:行番号9]):「b=f3(q)」に対する代入文解析を実行する(S144)。代入文解析の流れは、まず、S161でYesとなるため、関数呼出解析を実行する(S162)。関数呼出解析では、引数情報162cを作成し(S181)、引数qに対応した実引数1620(q)、仮引数1621(t)、参照先識別子1622(gVal)の組を引数情報162cに追加し(S184〜189)、関数名「f3」、及び引数情報162cをソースファイル特定部11に渡す(S191)。
(ソースファイル特定部11[f3]):関数定義ファイルリスト120を読み込み(S111)、関数f3の存在を判定し(S112)、関数名200(f3)、及びソースファイル名201(/src/funcC.c)をソースコード展開部12に渡す(S113)。
(引数情報設定部13[f3]):引数情報162cは空ではなく(S131でYes)、仮引数tの型がアドレスを格納する型であるため(S132でYes)、参照元識別子1640に「t」、逆参照識別子数1641に0、参照先識別子1642に「gVal」を設定した検査項目を作成し、検査リスト164cに追加し(S133)、tに対するアドレスの設定を解析結果22に記録し(S134)、引数情報設定処理を終了する(S137)。
(解析部14[f3:行番号3]):「int z=*t」に対する宣言解析を実行する(S143)。この宣言は、初期化を行っているため(S151でYes)、初期化式、すなわち*tに対する代入文解析を実行する(S152)。逆参照演算子数が0のtは検査リスト164cに格納されているため、*tに対する代入文解析の流れは、S161でNo、S164でYes、S166でNo,S169でNo、S170でNoであるため、tの参照を解析結果22に記録し(S165)、代入文解析を終了する(S176)。続いて、局所変数zはアドレスを格納する型ではないため(S153でNo)、宣言解析を終了する(S157)。
(解析部14[f3:行番号4]):「*t=100」に対する代入文解析を実行する(S144)。逆参照演算子数が0(コード上は1個だが1個の場合は0として扱う)のtは検査リスト164cに格納されている。また、*tの型はアドレスを格納する型ではない。したがって、*t=100に対する代入文解析の流れは、S161でNo、S164でNo、S166でYes、S170でNoであるため、*tに対する値の代入を解析結果22に記録(S167、S168)し、代入文解析を終了する(S176)。
(解析部14[f3:行番号5]:「z」に対する代入文解析を実行する(S144)。代入文解析の流れは、S161でNo、S164でNo、S166でNo、S169でNo、S170でNoであるため、代入文解析を終了する(S189)。
(解析部14[f3の末尾]):関数f3の末尾まで解析すると(S146でYes)、関数f3に対する解析部14の処理が終了し(S148)、関数f2の解析に戻る。
(解析部14[f2:行番号9]):階層値163を1減らし(S192)、引数情報162cを破棄して、関数f3に対する関数呼出解析を終了する(S194)。「b = f3(q)」には関数呼び出しが1つ記述されているため、関数f3に対する関数呼出解析(S162)を実行した後の処理の流れは、S161でNo、S164でNo、S166でNo、S169でNo、S170でNoであるため、代入文解析を終了する(S189)。
(解析部14[f2:行番号10]):「b」に対する代入文解析を実行する(S144)。代入文解析の流れは、S161でNo、S164でNo、S166でNo、S169でNo、S170でNoであるため、代入文解析を終了する(S189)。
(解析部14[f2の末尾]):関数f2の末尾まで解析すると(S146でYes)、関数f2に対する解析部14の処理が終了し(S148)、関数f1の解析に戻る。
(解析部14[f1:行番号9]):階層値163を1減らし(S192)、引数情報162bを破棄して、関数f2に対する関数呼出解析を終了する(S194)。「y = f2(x)」には関数呼び出しが1つ記述されているため、関数f2に対する関数呼出解析(S162)を実行した後の処理の流れは、S161でNo、S164でNo、S166でNo、S169でNo、S170でNoであるため、代入文解析を終了する(S189)。
(解析部14[f1の末尾]):関数f1の末尾まで解析すると(S146でYes)、関数f1に対する解析部14の処理が終了する(S148)。すなわち、ソースコード解析装置1による解析処理が完了する。
図17は、表示部15、及び解析結果加工部18の動作を示すフローチャートである。
(S201):表示部15は、入力部10から表示形式を取得する。
(S202):表示部15は、解析結果22を読み込む。
(S203):表示部15は、S201で取得した表示形式、及びS202で読み込んだ解析結果22を用いた解析結果の加工を、解析結果加工部18に指示する。解析結果加工部18は、前記表示形式に基づき、解析結果22を表示用に加工する。
(S204):表示部15は、S203で加工された解析結果22を表示する。
(S205):表示部15は、処理を完了する。
例えば、表示形式が「参照先識別子単位のアクセス回数集計」の場合、図18のような表示となる。
図18は、図7の解析結果22を参照先識別子226と操作種別224で集計した結果である。参照先識別子300は参照先識別子226から抽出した識別子であり、Read回数301、Write回数302、Set回数303、Function回数304は、解析結果22から、操作種別224がそれぞれ「Read」、「Write」、「Set」、「Function」となっている行の個数を、参照先識別子300毎に数え上げた値である。
例えば、表示形式が「参照先識別子単位のアクセス箇所リスト」の場合、図19のような表示となる。
図19は、図7の解析結果22を参照先識別子226ごとに並べ替えて、ソースファイル221が同じ値の行数を数え上げた結果である。参照先識別子311、及びソースファイル名311は、それぞれ解析結果22の参照先識別子226、及びソースファイル名221にある値の1つであり、アクセス回数312は、解析結果22から参照先識別子226が参照先識別子310に一致し、かつソースファイル名221がソースファイル名311に一致する行の個数を数え上げた値である。なお、図19に対して「行番号」を追加することで、より詳細なリストとして加工することも可能である。
具体的には、図7のソースコードを解析する場合、大域変数の名前のみに基づく解析では、/src/funcC.cの代入文「*r=100;」にて大域変数gValへの代入が発生していることが分からない。
しかし、本実施の形態によれば、/src/funcA.cの「x=&gVal;」によるアドレス代入、「y=f2(x);」による関数の引数を介したアドレスの伝播、/src/funcB.cの「int *q=p;」によるアドレスの代入、「b=f3(q);」による関数の引数を介したアドレスの伝播、/src/funcC.cの「*r=100;」によるポインタ型変数を介した大域変数への代入、に基づき検査リスト164を構築し、検査リスト164を用いて解析結果22を出力することにより、/src/funcC.cの代入文「*r=100;」にて大域変数gValへの代入が発生していると解析結果22の参照先識別子226に出力できる。
このようにすることで、1ファイルに多数の関数定義が記述されている場合は静的大域変数を検査リストに入れる、等のように、解析範囲に柔軟性を持たせることができ、かつ、静的大域変数を検査リストに格納しない場合は、解析の高速化が期待できる。
このようにすることで、再帰呼び出しを行う関数に対する解析が可能となる。
このようにすることで、ソースコード展開部12の実行回数の削減が期待でき、結果として構文木160および記号表161を展開する記憶領域の削減、および解析の高速化が期待できる。
また、上記説明では、int型の変数のみ用いているが、他の型であっても本実施の形態は適用可能である。
さらに、構造体および共用体のメンバについても、構文木160および記号表161を用いることで型の特定が可能であるため、変数と同様に解析できる。
このとき、解析結果22の変数名220にはメンバ名も含めて格納してもよい。ユーザ定義の型名(C言語の場合、typedefを使用)についても、同様に解析可能である。
したがって、前記必要な引数のみを引数情報162に格納するようにしてもよい。
このとき、各組が何番目であるか特定するための序数を、実引数1620、仮引数1621、参照先識別子1622から成る組に追加する(図示せず)。
(S103[変更後]):入力部10は、S100にて取得した関数名と、入力された引数情報162をソースファイル特定部11に渡す。
このようにすることで、入力部10に入力した関数の引数についても解析結果22に出力することが可能となり、より詳細な解析結果が得られるといった利点がある。
このようにすることで、解析結果22とソースコード21の対応関係が分かりやすくなるといった利点がある。
このようにすることで、着目する箇所について、段階的に詳細を表示することが可能となるといった利点がある。
このようにすることで、解析結果22の可読性が上がるといった利点がある。
また、表示部15は、入力部10の指示に基づき、記憶装置2に蓄積された複数の解析結果22を同時に表示しても構わない。
このようにすることで、例えば複数のタスクにおける特定の大域変数への参照、代入を簡単に把握できるといった利点がある。
実施の形態1では、解析結果22の作成に必要なソースコード21をすべてその場で解析しており、なおかつ関数定義ファイルリスト20を事前に準備する必要があった。
これに対して、実施の形態2では、予め解析に必要と思われるソースコード21のそれぞれに対してソースコード展開部12により作成される構文木160と記号表161を記憶装置2に保存するとともに関数定義ファイルリスト20に関数とソースコードの対応関係を記録することで、解析の高速化を図る。
実施の形態1との相違点は、記憶装置2に展開済データ23が追加されている点と、入力部10からソースコード展開部12への矢印が追加された点である。
展開済データ23は、一時記憶部16にある構文木160と記号表161を持つ(図示せず)。
入力部10は、解析システムの使用者からの入力として、ソースコード21のファイル名を受け取ると、受け取ったファイル名をソースコード展開部12に渡す。
図21は、実施の形態2における関数定義ファイルリスト20の構造を示す図である。
関数定義ファイルリスト20には、ソースコード解析装置1による解析に用いる1つ以上のソースコード21で定義されている関数の数だけ、関数名200、ソースファイル名201、展開済データ名202が存在する。
すなわち、関数定義ファイルリスト20は、1つ以上の関数名200、ソースファイル名201、展開済データ名202から構成される組を備える。
図22は、実施の形態2におけるソースコード展開部12による展開済データ23作成の動作を示すフローチャートである。
(S124):ソースコード展開部12は、構文木160、および記号表161を用いて、展開済データ23を作成する。展開済データ23は、ソースコード21と同じディレクトリに格納し、ファイル名はソースコードの拡張子を「.dat」に変更したものとする。
(S127):ソースコード展開部12は、構文木160、および記号表161を用いて、関数定義ファイルリスト20に記録する。このとき、関数名200は構文木160、および記号表161から取り出した関数定義の関数名であり、関数定義ごとに変更する。また、ソースファイル名201は、入力部10から与えられたファイル名を用いる。展開済データ名202はS126にて記載のものを用いる。
(S125):ソースコード展開部12は、処理を完了する。同時に、ソースコード解析装置1の第1の動作も完了する。
入力部10は、解析システムの使用者からの入力として、ソースコード21のファイル名を受け取ると、受け取ったファイル名をソースコード展開部12に渡す。
(S120):図11と同様のため説明を省略する。
(S128):ソースコード展開部12は、関数定義ファイルリスト20から、ソースコード21のファイル名に対応する展開済データ名202を取得し、該当する展開済データ23を読み込んで、構文木160と記号表161を一時記憶部16に格納する。
(S123)〜(S125):図11と同様のため説明を省略する。
例えば、複数ファイルで構成されるプログラムにて、数ファイルのみ変更して解析を再度行う場合、実施の形態2では、展開済データ23の再利用が可能であるため、解析を高速に行える。
逆に、展開済データ名202があれば、展開済データ23をソースコード21と異なるディレクトリ格納しても構わない。
このようにすることで、実施の形態2における解析システムの第2の動作では、関数呼び出しに関する箇所のみ解析すればよく、解析を高速に行えるといった利点がある。
このようにすることで、ソースコード21に対する変更の後、単にソースコード解析装置1を用いた解析を行うだけで、ソースコード21に対する変更を解析結果22に反映することが可能になるといった利点がある。
CPU911は、バス912を介して、例えば、ROM(Read Only Memory)913、RAM(Random Access Memory)914、通信ボード915、表示装置901、キーボード902、マウス903、磁気ディスク装置920と接続され、これらのハードウェアデバイスを制御する。
更に、CPU911は、FDD904(Flexible Disk Drive)、コンパクトディスク装置905(CDD)、プリンタ装置906、スキャナ装置907と接続していてもよい。また、磁気ディスク装置920の代わりに、光ディスク装置、メモリカード(登録商標)読み書き装置などの記憶装置でもよい。
RAM914は、揮発性メモリの一例である。ROM913、FDD904、CDD905、磁気ディスク装置920の記憶媒体は、不揮発性メモリの一例である。これらは、記憶装置の一例である。
通信ボード915、キーボード902、マウス903、スキャナ装置907、FDD904などは、入力装置の一例である。
また、通信ボード915、表示装置901、プリンタ装置906などは、出力装置の一例である。
プログラム群923のプログラムは、CPU911がオペレーティングシステム921、ウィンドウシステム922を利用しながら実行する。
また、RAM914には、CPU911による処理に必要な各種データが格納される。
ソースコード解析装置1の起動時には、ROM913のBIOSプログラム及び磁気ディスク装置920のブートプログラムが実行され、BIOSプログラム及びブートプログラムによりオペレーティングシステム921が起動される。
「〜ファイル」や「〜データベース」は、ディスクやメモリなどの記録媒体に記憶される。ディスクやメモリなどの記憶媒体に記憶された情報やデータや信号値や変数値やパラメータは、読み書き回路を介してCPU911によりメインメモリやキャッシュメモリに読み出され、抽出・検索・参照・比較・演算・計算・処理・編集・出力・印刷・表示などのCPUの動作に用いられる。
抽出・検索・参照・比較・演算・計算・処理・編集・出力・印刷・表示のCPUの動作の間、情報やデータや信号値や変数値やパラメータは、メインメモリ、レジスタ、キャッシュメモリ、バッファメモリ等に一時的に記憶される。
また、実施の形態1及び2で説明しているフローチャートの矢印の部分は主としてデータや信号の入出力を示し、データや信号値は、RAM914のメモリ、FDD904のフレキシブルディスク、CDD905のコンパクトディスク、磁気ディスク装置920の磁気ディスク、その他光ディスク、ミニディスク、DVD等の記録媒体に記録される。また、データや信号は、バス912や信号線やケーブルその他の伝送媒体によりオンライン伝送される。
Claims (12)
- 大域変数及び局所変数が含まれるプログラムコードを解析対象プログラムコードとして指定するコード指定部と、
前記コード指定部により指定された解析対象プログラムコードに対する解析を行い、大域変数のアドレスの局所変数への代入と、いずれかのアドレスを格納する引数の局所変数への代入と、大域変数のアドレスを格納する局所変数の他の局所変数への代入と、いずれかのアドレスを格納する引数を格納する局所変数の他の局所変数への代入の少なくともいずれかと、いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出するコード解析抽出部と、
前記コード解析抽出部の抽出結果を記憶する抽出結果記憶部とを有することを特徴とする情報処理装置。 - 前記コード解析抽出部は、
いずれかのアドレスを格納する引数を格納する局所変数の参照と、
いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出することを特徴とする請求項1に記載の情報処理装置。 - 前記コード解析抽出部は、
大域変数のアドレスを代入した局所変数を介した大域変数又は局所変数の参照と、
いずれかのアドレスを格納する引数を代入した局所変数を介した大域変数又は局所変数の参照と、
大域変数のアドレスを格納する局所変数を代入した局所変数を介した大域変数又は局所変数の参照と、
いずれかのアドレスを格納する引数を格納する局所変数を代入した局所変数を介した大域変数又は局所変数の参照の少なくともいずれかと、
いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出することを特徴とする請求項1又は2に記載の情報処理装置。 - 前記コード解析抽出部は、
大域変数のアドレスを代入した局所変数を介した大域変数又は局所変数への代入と、
いずれかのアドレスを格納する引数を代入した局所変数を介した大域変数又は局所変数への代入と、
大域変数のアドレスを格納する局所変数を代入した局所変数を介した大域変数又は局所変数への代入と、
いずれかのアドレスを格納する引数を格納する局所変数を代入した局所変数を介した大域変数又は局所変数への代入の少なくともいずれかと、
いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出することを特徴とする請求項1〜3のいずれかに記載の情報処理装置。 - 前記コード解析抽出部は、
いずれかのアドレスを格納する引数の参照と、
いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出することを特徴とする請求項1〜4のいずれかに記載の情報処理装置。 - 前記コード解析抽出部は、
いずれかのアドレスを格納する引数を介した大域変数の参照と、いずれかのアドレスを格納する引数を介した局所変数の参照の少なくともいずれかと、
いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出することを特徴とする請求項1〜5のいずれかに記載の情報処理装置。 - 前記コード解析抽出部は、
いずれかのアドレスを格納する引数を介した大域変数への代入と、いずれかのアドレスを格納する引数を介した局所変数への代入の少なくともいずれかと、
いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出することを特徴とする請求項1〜6のいずれかに記載の情報処理装置。 - 前記コード指定部は、
前記解析対象プログラムコードに関数呼び出しが含まれている場合に、呼び出し対象の関数が含まれているプログラムコードを識別し、当該プログラムコードを新たな解析対象プログラムコードとして指定し、
前記コード解析抽出部は、
前記コード指定部により新たな解析対象プログラムコードが指定された場合に、それまで解析を行っていた解析対象プログラムコードに対する解析を中断し、前記新たな解析対象プログラムコードに対する解析を開始し、前記新たな解析対象プログラムコードに対する解析が終了した際に、前記新たな解析対象プログラムコードの前に解析を行っていた解析対象プログラムコードに対する解析を再開することを特徴とする請求項1〜7のいずれかに記載の情報処理装置。 - 前記コード解析抽出部は、
前記解析対象プログラムコードを解析して、前記解析対象プログラムコードの構文木と記号表を生成し、生成した構文木と記号表を用いて抽出処理を行うことを特徴とする請求項1〜8のいずれかに記載の情報処理装置。 - 前記コード解析抽出部は、
前記コード指定部による解析対象プログラムコードの指定前に複数のプログラムコードを解析し、各プログラムコードの構文木と記号表を生成し、
前記コード指定部により解析対象プログラムコードが指定された際に、解析対象プログラムコードの構文木と記号表を用いて抽出処理を行うことを特徴とする請求項1〜9のいずれかに記載の情報処理装置。 - コンピュータが、大域変数及び局所変数が含まれるプログラムコードを解析対象プログラムコードとして指定するコード指定ステップと、
前記コンピュータが、前記コード指定ステップにより指定された解析対象プログラムコードに対する解析を行い、大域変数のアドレスの局所変数への代入と、いずれかのアドレスを格納する引数の局所変数への代入と、大域変数のアドレスを格納する局所変数の他の局所変数への代入と、いずれかのアドレスを格納する引数を格納する局所変数の他の局所変数への代入の少なくともいずれかと、いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出するコード解析抽出ステップと、
前記コンピュータが、前記コード解析抽出ステップの抽出結果を記憶する抽出結果記憶ステップとを有することを特徴とする情報処理方法。 - 大域変数及び局所変数が含まれるプログラムコードを解析対象プログラムコードとして指定するコード指定処理と、
前記コード指定処理により指定された解析対象プログラムコードに対する解析を行い、大域変数のアドレスの局所変数への代入と、いずれかのアドレスを格納する引数の局所変数への代入と、大域変数のアドレスを格納する局所変数の他の局所変数への代入と、いずれかのアドレスを格納する引数を格納する局所変数の他の局所変数への代入の少なくともいずれかと、いずれかのアドレスを格納する変数が当該アドレスを通じて指し示している他の変数とを前記解析対象プログラムコードから抽出するコード解析抽出処理と、
前記コード解析抽出処理の抽出結果を記憶する抽出結果記憶処理とをコンピュータに実行させることを特徴とするプログラム。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2010130320A JP5342508B2 (ja) | 2010-06-07 | 2010-06-07 | 情報処理装置及び情報処理方法及びプログラム |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2010130320A JP5342508B2 (ja) | 2010-06-07 | 2010-06-07 | 情報処理装置及び情報処理方法及びプログラム |
Publications (2)
Publication Number | Publication Date |
---|---|
JP2011257872A JP2011257872A (ja) | 2011-12-22 |
JP5342508B2 true JP5342508B2 (ja) | 2013-11-13 |
Family
ID=45474013
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2010130320A Expired - Fee Related JP5342508B2 (ja) | 2010-06-07 | 2010-06-07 | 情報処理装置及び情報処理方法及びプログラム |
Country Status (1)
Country | Link |
---|---|
JP (1) | JP5342508B2 (ja) |
Families Citing this family (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US9015831B2 (en) | 2012-08-08 | 2015-04-21 | Synopsys, Inc | Method and apparatus for static taint analysis of computer program code |
Family Cites Families (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JPH06348475A (ja) * | 1993-06-14 | 1994-12-22 | Nec Corp | ポインタ解析システム |
JP2990084B2 (ja) * | 1997-01-24 | 1999-12-13 | 日本電気株式会社 | 演算装置合成方法 |
JP2004013184A (ja) * | 2002-06-03 | 2004-01-15 | Matsushita Electric Ind Co Ltd | プログラム並列化方式およびプログラム並列化用の記録媒体 |
-
2010
- 2010-06-07 JP JP2010130320A patent/JP5342508B2/ja not_active Expired - Fee Related
Also Published As
Publication number | Publication date |
---|---|
JP2011257872A (ja) | 2011-12-22 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US10354069B2 (en) | Automated reverse engineering | |
US8555266B2 (en) | Managing variable assignments in a program | |
JP2005018767A (ja) | クエリオプティマイザのシステムおよび方法 | |
US20090182689A1 (en) | Rule-based dynamic operation evaluation | |
CN109564540B (zh) | 用于jit编译器的调试的系统、方法和设备 | |
US9043757B2 (en) | Identifying differences between source codes of different versions of a software when each source code is organized using incorporated files | |
US8332833B2 (en) | Procedure control descriptor-based code specialization for context sensitive memory disambiguation | |
JP2015143939A (ja) | コンパイルプログラム、コンパイル方法およびコンパイル装置 | |
JP6070847B2 (ja) | 検証方法、検証装置および検証プログラム | |
CN115017516A (zh) | 一种基于符号执行的模糊测试方法 | |
JP6440895B2 (ja) | ソフトウェア分析装置及びソフトウェア分析方法 | |
JP5409039B2 (ja) | 情報処理装置及び情報処理方法及びプログラム | |
JP5342508B2 (ja) | 情報処理装置及び情報処理方法及びプログラム | |
JPWO2019102786A1 (ja) | ソースコード分割装置、ソースコード解析装置、ソースコード分割方法及びソースコード分割プログラム | |
JP7111967B2 (ja) | プログラム検証プログラム、プログラム検証方法およびプログラム検証装置 | |
KR102117165B1 (ko) | 바이너리 분석을 위한 중간 언어 테스트 방법 및 장치 | |
JP2022531515A (ja) | コンピュータ支援コンピュータプログラミングのシステムおよび方法 | |
JP5578625B2 (ja) | プログラム分析装置、プログラム分析方法、及びプログラム | |
JP6748357B2 (ja) | 解析装置、解析プログラムおよび解析方法 | |
WO2022254487A1 (ja) | 情報処理プログラム、情報処理方法および情報処理装置 | |
JP6081144B2 (ja) | ソースコード解析装置 | |
JP6983693B2 (ja) | スタブ生成支援装置、スタブ生成支援方法、及びプログラム | |
JP5343840B2 (ja) | プログラムの解析装置及び解析方法 | |
WO2022195726A1 (ja) | 情報処理プログラム、情報処理方法および情報処理装置 | |
JP6953962B2 (ja) | 解析方法、解析装置及び解析プログラム |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
A621 | Written request for application examination |
Free format text: JAPANESE INTERMEDIATE CODE: A621 Effective date: 20121029 |
|
TRDD | Decision of grant or rejection written | ||
A977 | Report on retrieval |
Free format text: JAPANESE INTERMEDIATE CODE: A971007 Effective date: 20130710 |
|
A01 | Written decision to grant a patent or to grant a registration (utility model) |
Free format text: JAPANESE INTERMEDIATE CODE: A01 Effective date: 20130716 |
|
A61 | First payment of annual fees (during grant procedure) |
Free format text: JAPANESE INTERMEDIATE CODE: A61 Effective date: 20130809 |
|
R150 | Certificate of patent or registration of utility model |
Free format text: JAPANESE INTERMEDIATE CODE: R150 |
|
R250 | Receipt of annual fees |
Free format text: JAPANESE INTERMEDIATE CODE: R250 |
|
R250 | Receipt of annual fees |
Free format text: JAPANESE INTERMEDIATE CODE: R250 |
|
LAPS | Cancellation because of no payment of annual fees |