明らかに関数の内部に不正な方法で入ってくることがない関数を静的に調べたい
HSP では goto などで関数の内部に外側から簡単に入ったりできる。そのために仮引数やローカル変数の参照、代入や return がその関数がスタックトップの状態で実行されるかということが静的には分からない。でも、明らかに不正な方法で関数内部に入ってくることがありえないものは調べられるんじゃないかと思った。
関数の内部に不正な方法で入ってくる例
その前に、関数の内部に不正な方法で入ってくる例を挙げておく。
上から
; program head #deffunc f int a mes a return
関数定義の上から直接入ってくる
上から(ほかの関数から)
#module #deffunc f int a ; fall #deffunc f2 int a mes a return #global f 42
ほかの関数からreturnせずに落ちてくる。
goto
#module #deffunc f int a *lab_f mes a return #deffunc f2 int a goto *lab_f #global f2 42
repeat から不正な方法で脱出した後、 repeat の位置に戻ってくる
#module #deffunc f int a repeat ; 2) ループスタックトップが記憶しているこの位置にジャンプする return loop #global repeat 1 f 42 loop ; 1) loop を実行すると
というか
- 関数の内部に不正でない方法で入ってきたり、ループの中から不正な方法で脱出したりとかエラーにしてほしいわー
- 関数の終了位置を明示できるようにしてほしいわー。もしくは、return せずに次の関数の内部に入り込もうとしたらエラーとか。
それはさておき、どうやって判定するかを考える
- 上から落ちてこないことを調べるのが難しそう
- 上方向に直近の return / goto / stop / end の位置からラベルが存在するか調べる
- ラベルがあったらアウト
- でもそれじゃあ repeat 〜 loop が自動的に作るラベルがあってもアウトになっちゃう
- ラベルがあっても外から飛んでこなけりゃ別に問題ない
- while、 for、 switch マクロもラベルを作るし、ラベルがあるだけでアウトはきついか
- 「repeat ループから不正な方法で脱出しない」ことを判定するのも難しそう