pragma Restrictions

……の用途がようやくわかった。
pragma Restrictionsというのは、ある機能を封印するpragmaです。
ですが、RMにはたいしたものが定義されて無くて実装依存の機能やObsolescentなものを弾いてPureなサンプルコードを書くためのものか?ぐらいの認識だったのですよ。
違いました。いや、違って無いですが、価値は他にもあります。
このpragmaは実装が項目を追加してこそ意味があります。gccの場合はこれ。
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gnat_rm/Implementation-Defined-Characteristics.html
例えば、サイズが実行時に変わる値を返す時、GNATはセカンダリスタックなるものを使用します。セカンダリスタックってのはよーするにスタックが2本あるわけです。Forthでデータスタックとリターンアドレス用のスタックが別れている……なんて意味のあるものでは全然ないです。無意味です。なんでこんなものがあるかというと、バックエンドとしてのgccが、可変長返値を(恐らく)サポートして無いからです。gccに限らずprintfが使うというだけで可変長引数は大抵のバックエンドが考慮してるのに世の中は不条理です。つーかAdaCoreもgccのメンテナなんですからバックエンドのほうを修正すりゃいいんじゃないかとも思うのですが、どーせgcc以外のバックエンド(CLRとか)も可変長返値なんてサポートして無いんだろうなあってあたりでgcc以外にも使い回されてるフロントエンドとしては意味があるんでしょう多分。
で、そーいう裏でランタイムを必要とする機能ってのは、AdaをCみたいに使う時の障害になるわけです。gccファミリー以外とリンクするとかあと組み込みとか。
で、セカンダリスタックを使わないようにしたければ、ソースの先頭にでもこう書くわけです。

pragma Restrictions(No_Secondary_Stack);

で、こんなの書いたからって、セカンダリスタックを使わないよう苦心して回りくどいコードを吐いてくれる、なんてことは決して無くて、単にセカンダリスタックを使うコードがコンパイルエラーになるだけなんですが。
いざリンクしてから愕然とするよりはいいって話なんだと思います。
しかし、No_Elaboration_Codeでtagged型までもが禁止されてしまうのは、どうかと思うんですが。吐いたコードを見るとですね、VMTを実行時に組み立ててるのが、いろんな意味で救いが無い。単にバックエンドに渡すフラグかなんか間違えてるんじゃないかなあと思うんですが。つーかこんなパッチが今さら出てくるあたりそうとしか思えん。
あと、こんなpragmaがRMではなくGNAT側で定義されているのはなんかのギャグでしょうか。

pragma Restrictions(No_Implementation_Restrictions);