This patch fixes a bug where the compiler would give an incorrect error message when an intrinsic operator is called with operands of private type, but with a result of a non-private type. The following test should compile quietly. package Test_Intrinsics is
type T is private; X : constant T; function "*" (X, Y : T) return Float; private type T is new Float; X : constant T := 0.0; pragma Import (Intrinsic, "*"); end Test_Intrinsics; with Test_Intrinsics; use Test_Intrinsics; procedure Test_Intrinsics_Main is Y : Float := X * X; begin null; end Test_Intrinsics_Main; Tested on x86_64-pc-linux-gnu, committed on trunk 2011-09-05 Bob Duff <d...@adacore.com> * sem_res.adb (Resolve_Intrinsic_Operator): Use unchecked conversions instead of normal type conversions in all cases where a type conversion would be illegal. In particular, use unchecked conversions when the operand types are private.
Index: sem_res.adb =================================================================== --- sem_res.adb (revision 178460) +++ sem_res.adb (working copy) @@ -7145,6 +7145,8 @@ return Res; end Convert_Operand; + -- Start of processing for Resolve_Intrinsic_Operator + begin -- We must preserve the original entity in a generic setting, so that -- the legality of the operation can be verified in an instance. @@ -7162,11 +7164,14 @@ Set_Entity (N, Op); Set_Is_Overloaded (N, False); - -- If the operand type is private, rewrite with suitable conversions on - -- the operands and the result, to expose the proper underlying numeric - -- type. + -- If the result or operand types are private, rewrite with unchecked + -- conversions on the operands and the result, to expose the proper + -- underlying numeric type. - if Is_Private_Type (Typ) then + if Is_Private_Type (Typ) + or else Is_Private_Type (Etype (Left_Opnd (N))) + or else Is_Private_Type (Etype (Right_Opnd (N))) + then Arg1 := Convert_Operand (Left_Opnd (N)); -- Unchecked_Convert_To (Btyp, Left_Opnd (N));