明らかに関数の内部に不正な方法で入ってくることがない関数を静的に調べたい

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 ループから不正な方法で脱出しない」ことを判定するのも難しそう