This patch fixes an infinite recursion in the application of predicate checks to type conversions.
The following must compile quietly: gcc -c -gnat12 ./why-conversions.ads --- with Why.Ids; use Why.Ids; package Why.Conversions is function "+" (Id : W_Unused_At_Start_OId) return W_Unused_At_Start_Valid_OId; private function "+" (Id : W_Unused_At_Start_OId) return W_Unused_At_Start_Valid_OId is (W_Unused_At_Start_Valid_OId (Id)); end Why.Conversions; --- package Why is pragma Pure; end Why; --- with Why.Unchecked_Ids; use Why.Unchecked_Ids; package Why.Ids is subtype W_Unused_At_Start_Valid_OId is W_Unused_At_Start_Unchecked_OId; type W_Unused_At_Start_OId is new W_Unused_At_Start_Valid_OId; end Why.Ids; --- with Why.Opaque_Ids; use Why.Opaque_Ids; package Why.Kind_Validity is -- Kind-validity checks function Unused_At_Start_OId_Kind_Valid (Id : W_Unused_At_Start_Opaque_OId) return Boolean; private function Unused_At_Start_OId_Kind_Valid (Id : W_Unused_At_Start_Opaque_OId) return Boolean is (Id /= 0); end Why.Kind_Validity; --- package Why.Opaque_Ids is subtype W_Unused_At_Start_Opaque_OId is Integer; end Why.Opaque_Ids; --- with Why.Opaque_Ids; use Why.Opaque_Ids; with Why.Kind_Validity; use Why.Kind_Validity; package Why.Unchecked_Ids is subtype W_Unused_At_Start_Unchecked_OId is W_Unused_At_Start_Opaque_OId with Predicate => (Unused_At_Start_OId_Kind_Valid (W_Unused_At_Start_Unchecked_OId)); end Why.Unchecked_Ids; Tested on x86_64-pc-linux-gnu, committed on trunk 2011-08-05 Ed Schonberg <schonb...@adacore.com> * exp_ch4.adb (Expand_N_Type_Conversion): When expanding a predicate check, indicate that the copy of the original node does not come from source, to prevent an infinite recursion of the expansion.
Index: exp_ch4.adb =================================================================== --- exp_ch4.adb (revision 177431) +++ exp_ch4.adb (working copy) @@ -9154,8 +9154,16 @@ and then Target_Type /= Operand_Type and then Comes_From_Source (N) then - Insert_Action (N, - Make_Predicate_Check (Target_Type, Duplicate_Subexpr (N))); + declare + New_Expr : constant Node_Id := Duplicate_Subexpr (N); + + begin + -- Avoid infinite recursion on the subsequent expansion of + -- of the copy of the original type conversion. + + Set_Comes_From_Source (New_Expr, False); + Insert_Action (N, Make_Predicate_Check (Target_Type, New_Expr)); + end; end if; end Expand_N_Type_Conversion;