ST A : τ
'E̲RETURNI r e t u r n
文 [クラスst a t e m β n t
の主なso r t J 2 . 1
クラスstatement
のオブジェクトクラス
statement
のオブジェクト配列を用いて、各種の情報を得る。SDA
モ デルなどのI‑MODEL
を拡張したモデルについては、spdGe
tObjIdArray
とい ったAR4
関数を利用できる。サンプルプログラム5‑1
は、statement
オブジエ クトのI d
、so此を求め、出力する。解析対象のプログラム
5
・1
int bbb(int j)
j r
則 mjサ;void
c c
c() {p巾ぜ("aa¥n");Lunam(mt時 c,char**時 v){ inti
,
k;78 Sapidによるソフトウエア解析技法 char buffer[ 12叫;
if(argc !=̲ 2)e田t(o); 町cpy(buffer, 町gv[1]); k=1;
if(k< 10){ while(k< 1 O){
k=aaa( 2)+bbb( 3); for(i= 1 } ;i<4;i++){
C四O;}
ー )
除
k'h
M ‑ n u
抽 掛 川 別 )+aAruh h d
‑ 4 b
% k
; kf k"
‑‑
"
︐ ︒
i k k n h k e {
目"
¥
"
r L 1 I d n M M
‑ m d
国 代
muMwpfmM制
u n i p
‑
‑ q z
ー
=
= r t E .
︐hkkf
凶
% 刷
a M m m
州問
"
( { E t h u
d叫
・ 均 } 炉 問
n M
. n ‑n v ‑
' K
サンプルプログラムら
1
ークラスstatementの基本情報を求める(1)#include <stdio.h>
#include <Sapid/Sapid.h>
#include <Sapid/StmtModel.h>
剖nclude<Sapid/SDA model.h>
void openModel(SpdDBld); void getStatementSort(SpdObjld);
?tmain(imgc, 伽 暑 即 日 ) SpdObjldArray state̲array; SpdObjld state̲id; int i;
SpdDBld dbld; dbld = spdOpenSDBO;
openMoilel(dbld);
state̲array=s凶GetObjldArray("statement",NU比,NU叫);
for (i = 0; i < state̲array.si田;i++){ state̲id=statcaπay.id[il; getStatementSort(state̲id); printf("∞nd=%d¥n"
,
state̲id); spdFreeObjI<iArray(state̲array); spdCloseSOB(dbld);retum (EXIT̲SUCCESS);
第5章 制御構造と依存解析 SDAモデル 79
関数 openModel
ーモデル呼び出し( 2 )
void openModel(SpdDBld dbld){
SpdModelId ImodelId,PmodelId, StmtModelId, SDA modelId; ImodelId = spdUseModel(&Cmodel);
PmodelId = spdUseModel(&P ̲model); StmtModelId = spdUseModel(&StmCmodel);
SDA modelId = spdUseModel(&SDA̲model);
spdReadDB(lmodelId
,
dbld); spdRJ回dDB(pmodelId,dbld); si>dReadDB(StmtModelId, dbld); spdReadDB(SDAmodelId, dbld);関数 g e t S t a t e m e n t S o r t 一一 s t a t e m e n t
オブジエクトのSO此を求める
void getStatementSort(SpdObjld state̲id){int attr ̲ val;
a町 一val= spdGetAtlrValInt(state̲id,"sort") ; switch(a悦r̲val){
伺seSTATE NORMAL:
printf("NORMAL Statement ‑> ");break;
回 目STATE IF:
printf("IF Statement ‑> ");break; 省 略
caseSTATE‑BLock:
printf("BLOCK Statement ‑> ");break;
伺seSTATE RETURJN:
printf("RETURJN Statement ‑> ");break; default:
printf("Other Statement ‑> "); }
実行結果 ( s t a t e m n t
のI d ヘッダ部は 5 6 6 )
B1βCKStatement‑> 56623106RETURJN Statement ‑> 56623107 BLOCKStatement ‑> 56623108 RETURJN Statement ‑> 566231 09 BLOCKStatement ‑> 56623110 NORMALStatement‑> 56623111 B1βCK Statement ‑> 56623112 NORJMAL Statement ‑> 56623113 IFStatement‑> 56623114 BLOCKStatement‑> 56623115 WHlLE Statement ‑> 56623116 BLοCKStatement‑> 56623117 NORMALStatement‑> 56623118 FOR Statement ‑> 56623119 B1ρCK Statementー>56623120 NORJMALStatement‑> 56623121
以 下 省 略
8 0 S a p i d
によるソフトウェア解析技法2 . 2 ク ラ ス statement の 関 連
クラス statement
は10 個 の 関 連 を 持 つ 。 サ ン プ ル プ ロ グ ラ ム 号 2
はstatement オ ブ ジ ェ ク ト 中 で i f 文 で あ る も の を 求 め 、 そ の オ ブ ジ ェ ク ト か ら 関 連 iter̲expr に よ り 、 当 該 i f 文中の条件式を求める。
fω̲expr I cond̲expr r
モturnexpr
Ib l o c k ̲ de
c1i t e r ̲ e x p r
Istmt̲expr stmClabel b l ∞ k̲stmt I controUx
刈yI e l s e ̲ 以
xly[ statement の関連]
cond̲expr: 制御文とその条件式の聞の関係を示す.
i d I n t e g e r R e l a t i o n の識別番号
stmt i d I n t e g e r 制御文オブジェクトの識別番号 e x p r ̲ i d I n t e g e r e x p r e s s i o n の識別番号 o f f s e t I n t e g e r e x p r e s s i o n のo f f s e t i t e r ̲ e x p r : f o r 文とf o r 文の第3 式の聞の関係を示す.
i d I n t e g e r R e l a t i o n の識別番号 stmt i d I n t e g e r f o r 文オブジェクトの識別番号 exPcid I n t e g e r e x p r e s s i o n の識別番号 o f f s e t I n t e g e r e x p r e s s i o n のo f f s e t i t e r ̲ e x p r : f o r 文と f o r 文の第3 式の聞の関係を不す.
i d I n t e g e r R e l a t i o n の識別番号 stmt i d I n t e g e r statement の識別番号 e x p r ̲ i d I n t e g e r e x p r e s s i o n の識別番号 o f f s e t I n t e g e r e x p r e s s i o n のo f f s e t
[主な関連の例]
サ ン プ ル プ ロ グ ラ ム 手 2 ークラス statement の基本情報を求める
# i n c l u d e < s t d i o . h >
# i n c l u d e
<Sap i d f S a p i d . h >
# i n c l u d e
<Sap i d / S t m t M o d e
l.h >
# i n c l u d e
<Sap i d ! S D
Arno d e
l.h >
v o i d o p e n M o d e l ( S p d D B l d ) ; TtmMint
叩 ,c h a r * a r g v
[J)S p d O b j l
dArra y s t a t c a r r a y ; S
i>dO b j l d s t a t c i d
,e x p r ' : ' i d ; i n t i ;
S p d D B l d d b l d ; d b l d ; s
凶O
!lCn S D B O ; o p e n M o o e l ( d b l d ) ;
s t a t e ̲ a r r a y ; s p d
Get O b j l
dArr a y ( " s t a t e m e n t "
,NULL,NULL);f o r
(i; ( ,}i < s t a t c a r r a y . s i z e ; i + + )
i f ( s p d
GetAt t r V a
lIn t ( s i a t e ̲ a r r a y
.id [ i l
," s o r t " ) ; ; S T A T E ̲ I F ) {
第5章 制御構造と依存解析 ‑SDAモデル 81 exprーid=spdGetAReIObj(state̲array.id[i],"cond̲exprγany");
printf("CondExp of IF・>%s¥n", spdGetObjText(expUd)); spdFreeObjldArray(state̲array);
spdCloseSDB(dbld); return (EXIT̲SUCCESS); 実行結果
CondExp ofIF ‑> argc > 1 CondExpofIF‑> kuo CondExp ofIF ‑> k= 1
m SDA
モデルと制御フローsdafuncオブジェクトは、 vargオ ブ ジ ェ ク ト 、 関 数 定 義 文 (sortが DECL FUNCDEFであるdeclaration)や、最初に出現する文と関連を持つ。
最初の文は関連sfunc̲stmtをにより求める。
│
next̲stmtI
data一
d句 印dl負釦加1II即[SDAモデルの関連]
func sfunc 関数declaration
図
3 .
文が通常の文 (NORMAL)であれば、その実行文はnext̲stmt関連のただ
1
つの親である。関連を子の側へたどり、プログラム実行時の関数内の実行順 で 文 を 得 る 。 こ の と き 、 対 象 と な る オ ブ ジ ェ ク ト はstatementお よ び declaration、labelの一部など、 expressionを子に持つオブジエクトである。3 . 1
sdafuncオブジェクトの情報を求めるsdafuncのオブジェクトの一覧を求め、関連func sfuncをたどり、対応する 関数宣言のオブジェクトIdを求める。宣言のクラスはdeclarationである。
82 Sapidによるソフトウェア解析技法
そのオブジエクトidを基点とし、 I‑modelのクラス・関連を利用して、さまざ まな情報を得る。
Id func id sfunc id
Integer Integer Integer
R.elationの識別番号 declarationの識別番号 sdafuncの識別番号 [ stat疋mentの関連]
サンプルプログラムら
3
ークラスsdafuncの基本情報を求める#include <stdio.h>
#include <Sapid(Sapid目h>
#include <Sapid/StmtModel.h>
#include <Sapid/SDAmodel.h>
void openModel(SpdDBld); char* getFuncName(SpdObjld);
?t min{ht即 , 伽*argv[])
~P'!2N!~y 油_array;
Sj>dObjld sda̲id. decl.jd; irit i;
S凶DBId dbId; dbId = spdOpenSDBO;
openMooel(dbld);
sda̲array=spdGetObjldArra
メ
"sdafunc".NULL.NULL); for (i = 0; i < sda̲array.size; i++) {sda̲id=sda̲a町'ay.id[iJ; prinぜ'C"sda伽ncId = 96dヘsda̲id); d
白ecl
一
Ud=̲i司s凶pdG仇etARelωO均(ωsda̲array.i泊d[日ii汀J."加f釦.u町un阻cι一
sf釦u凹un児ピccピ' ..γ' } prdi n ぜ償'C"甲Fun児c= 96s叫¥n"ヘ.getFuncName(decUd));spdFreeObjldArray(sda̲a町ay); sj>dCloseSDB(dbId);
同 知m (EXIT̲SUCCESS);
関数getFuncName 一関数名を求める
char* getFuncName(SpdObjld decUd){
SpdObjld deccid. idenUd;
d田r̲iIl=spdGetARelObj(
d . 配
Cid."decl̲decl"."any"); idenUd=spdGe仏RelObj(d配r̲id...decl̲ident....・any"); retum spdGetName(idenCid);実行結果
sdafunc Id = 56623140Func = aaa sdafunc Id = 56623141 Func = bbb sdafunc Id = 56623142Func = 田C
sdafuncld= 56623143Func=main