gcc/ada/ * Makefile.rtl (GNATRTL_128BIT_PAIRS): New variable. (GNATRTL_128BIT_OBJS): Likewise. (Windows): In 64-bit mode, add the former to LIBGNAT_TARGET_PAIRS and the latter to EXTRA_GNATRTL_NONTASKING_OBJS. (x86_64/linux): Likewise, but unconditionally. (GNATRTL_NONTASKING_OBJS): Add s-aridou, s-exponn, s-expont, s-exponu. * ada_get_targ.adb (Get_Long_Long_Long_Size): New function. * checks.adb (Apply_Arithmetic_Overflow_Strict): Use Integer_Type_For to find an appropriate integer type; if it does not exist and the max integer size is larger than 64, use the 128-bit arithmetic routines. * cstand.adb (Create_Standard): Build Standard_Long_Long_Long_Integer and its base type. Use it for Etype of Any_Integer, Any_Modular and Any_Numeric. Use its size for Build Standard_Long_Long_Long_Unsigned and Universal_Integer. (Print_Standard): Print Long_Long_Long_Integer. * exp_attr.adb (Expand_N_Attribute_Reference) <Attribute_Mod>: Adjust comment. * exp_ch3.adb (Simple_Init_Initialize_Scalars_Type): Deal with 128-bit types. * exp_ch4.adb (Expand_Array_Comparison): Likewise. (Expand_N_Op_Expon): Likewise. (Narrow_Large_Operation): Likewise. * exp_dbug.adb (Bounds_Match_Size): Handle 128-bit size. * exp_fixd.adb (Build_Double_Divide_Code): Use RE_Double_Divide64. * exp_intr.adb (Expand_Binary_Operator_Call): Handle 128-bit size. * exp_pakd.ads (E_Array): Extend range to 127. (Bits_Id): Fill in up to 127. (Get_Id): Likewise. (GetU_Id): Likewise. (Set_Id): Likewise. (SetU_Id): Likewise. * exp_pakd.adb (Revert_Storage_Order): Handle 128-bit size. * exp_util.adb (Integer_Type_For): Likewise. (Small_Integer_Type_For): Likewise. * fname.adb (Is_Predefined_File_Name): Do not return False for names larger than 12 characters if they start with "s-". * freeze.adb (Adjust_Esize_For_Alignment): Change the maximum value to System_Max_Integer_Size. (Check_Suspicious_Modulus): Adjust comment. (Freeze_Entity): Likewise. * get_targ.ads (Get_Long_Long_Long_Size): New function. * get_targ.adb (Get_Long_Long_Long_Size): Likewise. (Width_From_Size): Deal with 128-bit size. * gnat1drv.adb (Adjust_Global_Switches): Deal with 128-bit types. * impunit.adb (Get_Kind_Of_File): Bump buffer size. Accept files with 13 characters if they start with 's'. Compare slice of Buffer. (Not_Impl_Defined_Unit): Accept files with 13 characters if they start with 's'. * krunch.ads: Document length for 128-bit support units. * krunch.adb (Krunch): Set length to 9 for 128-bit support units. * layout.adb (Layout_Type): Use System_Max_Integer_Size as alignment limit. * rtsfind.ads (RTU_Id): Add System_Arith_128, System_Compare_Array_Signed_128, System_Compare_Array_Unsigned_128, System_Exn_LLLI, System_Exp_LLLU, System_Pack_[65..127]. (RE_Id): Add RE_Integer_128, RE_Unsigned_128, RE_Add_With_Ovflo_Check128 RE_Multiply_With_Ovflo_Check128, RE_Subtract_With_Ovflo_Check128, RE_Bswap_128, RE_Compare_Array_S128, RE_Compare_Array_U128, RE_Exn_Long_Long_Long_Integer, RE_Exp_Long_Long_Long_Integer, RE_Exp_Long_Long_Long_Unsigned, RE_Bits_[65-127], RE_Get_[65-127], RE_Set_[65-127], RE_IS_Is16, RE_IS_Iu16, RE_Integer_128 and RE_Unsigned_128. Rename RE_Add_With_Ovflo_Check, RE_Double_Divide, RE_Multiply_With_Ovflo_Check, RE_Scaled_Divide and RE_Subtract_With_Ovflo_Check. Remove RE_IS_Iz1, RE_IS_Iz2, RE_IS_Iz4, RE_IS_Iz8, RE_Long_Unsigned, RE_Short_Unsigned, RE_Short_Short_Unsigned (RE_Unit_Table): Likewise. * sem_aux.adb (Corresponding_Unsigned_Type): Deal with a size equal to that of Standard_Long_Long_Long_Integer. (First_Subtype): Deal with Standard_Long_Long_Long_Integer'Base. * sem_ch13.adb (Analyze_Attribute_Definition_Clause) <Attribute_Size>: Check the size against powers of 2 and System_Max_Integer_Size for objects as well. (Set_Enum_Esize): Deal with 128-bit bounds. * sem_ch3.adb (Set_Modular_Size): Handle 128-bit size. (Modular_Type_Declaration): Deal with 128-bit types. (Signed_Integer_Type_Declaration): Support derivation from Standard_Long_Long_Long_Integer. * sem_ch4.adb (Analyze_Mod): Handle 128-bit modulus. * sem_intr.adb: Add with and use clauses for Ttypes. (Check_Shift): Handle 128-bit size and modulus. * sem_prag.adb (Analyze_Pragma) <Pragma_Initialize_Scalars>: Deal with Signed_128 and Unsigned_128. (Analyze_Integer_Value): Handle 128-bit size. * sem_util.ads (Addressable): Adjust description. * sem_util.adb (Addressable): Return true for 128 if the system supports 128 bits. (Set_Invalid_Binder_Values): Deal with Signed_128 and Unsigned_128. * set_targ.ads (Long_Long_Long_Size): New variable. * set_targ.adb (S_Long_Long_Long_Size): New constant. (DTN): Add entry for S_Long_Long_Long_Size. (DTV): Add entry for Long_Long_Long_Size. (Set_Targ): Set Long_Long_Long_Size. * snames.ads-tmpl (Name_Max_Integer_Size): New attribute name. (Name_Signed_128): New scalar name. (Name_Unsigned_128): Likewise. (Scalar_Id): Adjust. (Integer_Scalar_Id): Likewise. (Attribute_Id): Add Attribute_Max_Integer_Size. * stand.ads (Standard_Entity_Type): Add S_Long_Long_Long_Integer. (Standard_Long_Long_Long_Integer): New renaming. (Universal_Integer): Adjust description. (Standard_Long_Long_Long_Unsigned): New variable. * switch-c.adb (Scan_Front_End_Switches): Deal with -gnate128. * ttypes.ads (Standard_Long_Long_Long_Integer_Size): New variable. (Standard_Long_Long_Long_Integer_Width): Likewise. (System_Max_Integer_Size): Turn into variable. (System_Max_Binary_Modulus_Power): Likewise. * uintp.ads (Uint_127): New constant. * uintp.adb (UI_Power_2): Extednd to 128. (UI_Power_10): Likewise. (UI_Expon): Deal with exponent up to 128 specially. * usage.adb (Write_Switch_Char): Print -gnate128 switch. * libgnat/a-tifiio.adb (Put_Scaled): Call Scaled_Divide64. * libgnat/interfac__2020.ads (Integer_128): New integer type. (Unsigned_128): New modular type. (Shift_Left, Shift_Right, Shift_Right_Arithmetic, Rotate_Left, Rotate_Right): New intrinsic functions operating on it. * libgnat/s-aridou.ads, libgnat/s-aridou.adb: New generic package. * libgnat/s-arit64.ads, libgnat/s-arit64.adb: Instantiate System.Arithmetic_Double. * libgnat/s-arit128.ads, libgnat/s-arit128.adb: Likewise. * libgnat/s-bytswa.ads: Add with clause for Interfaces, use subtypes of unsigned types defined in Interfaces and add Bswap_128. * libgnat/s-casi128.ads, libgnat/s-casi128.adb: New package. * libgnat/s-caun128.ads, libgnat/s-caun128.adb: Likewise. * libgnat/s-exnint.ads: Instantiate System.Exponn. * libgnat/s-exnint.adb: Add pragma No_Body. * libgnat/s-exnlli.ads: Instantiate System.Exponn. * libgnat/s-exnlli.adb: Add pragma No_Body. * libgnat/s-exnllli.ads: Instantiate System.Exponn. * libgnat/s-expint.ads: Likewise. * libgnat/s-expint.adb: Add pragma No_Body. * libgnat/s-explli.ads: Instantiate System.Exponn. * libgnat/s-explli.adb: Add pragma No_Body. * libgnat/s-expllli.ads: Instantiate System.Exponn. * libgnat/s-explllu.ads: Instantiate System.Exponu. * libgnat/s-expllu.ads: Likewise. * libgnat/s-expllu.adb: Add pragma No_Body. * libgnat/s-exponn.ads, libgnat/s-exponn.adb: New generic function. * libgnat/s-expont.ads, libgnat/s-expont.adb: Likewise. * libgnat/s-exponu.ads, libgnat/s-exponu.adb: Likewise. * libgnat/s-expuns.ads, libgnat/s-expuns.adb: Likewise. * libgnat/s-pack65.ads, libgnat/s-pack65.adb: New package. * libgnat/s-pack66.ads, libgnat/s-pack66.adb: New package. * libgnat/s-pack67.ads, libgnat/s-pack67.adb: New package. * libgnat/s-pack68.ads, libgnat/s-pack68.adb: New package. * libgnat/s-pack69.ads, libgnat/s-pack69.adb: New package. * libgnat/s-pack70.ads, libgnat/s-pack70.adb: New package. * libgnat/s-pack71.ads, libgnat/s-pack71.adb: New package. * libgnat/s-pack72.ads, libgnat/s-pack72.adb: New package. * libgnat/s-pack73.ads, libgnat/s-pack73.adb: New package. * libgnat/s-pack74.ads, libgnat/s-pack74.adb: New package. * libgnat/s-pack75.ads, libgnat/s-pack75.adb: New package. * libgnat/s-pack76.ads, libgnat/s-pack76.adb: New package. * libgnat/s-pack77.ads, libgnat/s-pack77.adb: New package. * libgnat/s-pack78.ads, libgnat/s-pack78.adb: New package. * libgnat/s-pack79.ads, libgnat/s-pack79.adb: New package. * libgnat/s-pack80.ads, libgnat/s-pack80.adb: New package. * libgnat/s-pack81.ads, libgnat/s-pack81.adb: New package. * libgnat/s-pack82.ads, libgnat/s-pack82.adb: New package. * libgnat/s-pack83.ads, libgnat/s-pack83.adb: New package. * libgnat/s-pack84.ads, libgnat/s-pack84.adb: New package. * libgnat/s-pack85.ads, libgnat/s-pack85.adb: New package. * libgnat/s-pack86.ads, libgnat/s-pack86.adb: New package. * libgnat/s-pack87.ads, libgnat/s-pack87.adb: New package. * libgnat/s-pack88.ads, libgnat/s-pack88.adb: New package. * libgnat/s-pack89.ads, libgnat/s-pack89.adb: New package. * libgnat/s-pack90.ads, libgnat/s-pack90.adb: New package. * libgnat/s-pack91.ads, libgnat/s-pack91.adb: New package. * libgnat/s-pack92.ads, libgnat/s-pack92.adb: New package. * libgnat/s-pack93.ads, libgnat/s-pack93.adb: New package. * libgnat/s-pack94.ads, libgnat/s-pack94.adb: New package. * libgnat/s-pack95.ads, libgnat/s-pack95.adb: New package. * libgnat/s-pack96.ads, libgnat/s-pack96.adb: New package. * libgnat/s-pack97.ads, libgnat/s-pack97.adb: New package. * libgnat/s-pack98.ads, libgnat/s-pack98.adb: New package. * libgnat/s-pack99.ads, libgnat/s-pack99.adb: New package. * libgnat/s-pack100.ads, libgnat/s-pack100.adb: New package. * libgnat/s-pack101.ads, libgnat/s-pack101.adb: New package. * libgnat/s-pack102.ads, libgnat/s-pack102.adb: New package. * libgnat/s-pack103.ads, libgnat/s-pack103.adb: New package. * libgnat/s-pack104.ads, libgnat/s-pack104.adb: New package. * libgnat/s-pack105.ads, libgnat/s-pack105.adb: New package. * libgnat/s-pack106.ads, libgnat/s-pack106.adb: New package. * libgnat/s-pack107.ads, libgnat/s-pack107.adb: New package. * libgnat/s-pack108.ads, libgnat/s-pack108.adb: New package. * libgnat/s-pack109.ads, libgnat/s-pack109.adb: New package. * libgnat/s-pack110.ads, libgnat/s-pack110.adb: New package. * libgnat/s-pack111.ads, libgnat/s-pack111.adb: New package. * libgnat/s-pack112.ads, libgnat/s-pack112.adb: New package. * libgnat/s-pack113.ads, libgnat/s-pack113.adb: New package. * libgnat/s-pack114.ads, libgnat/s-pack114.adb: New package. * libgnat/s-pack115.ads, libgnat/s-pack115.adb: New package. * libgnat/s-pack116.ads, libgnat/s-pack116.adb: New package. * libgnat/s-pack117.ads, libgnat/s-pack117.adb: New package. * libgnat/s-pack118.ads, libgnat/s-pack118.adb: New package. * libgnat/s-pack119.ads, libgnat/s-pack119.adb: New package. * libgnat/s-pack120.ads, libgnat/s-pack120.adb: New package. * libgnat/s-pack121.ads, libgnat/s-pack121.adb: New package. * libgnat/s-pack122.ads, libgnat/s-pack122.adb: New package. * libgnat/s-pack123.ads, libgnat/s-pack123.adb: New package. * libgnat/s-pack124.ads, libgnat/s-pack124.adb: New package. * libgnat/s-pack125.ads, libgnat/s-pack125.adb: New package. * libgnat/s-pack126.ads, libgnat/s-pack126.adb: New package. * libgnat/s-pack127.ads, libgnat/s-pack127.adb: New package. * libgnat/s-rannum.ads (Random): New function returning 128-bit. * libgnat/s-rannum.adb (Random): Implement it. * libgnat/s-scaval.ads: Add with clause for Interfaces, use subtypes of unsigned types defined in Interfaces. * libgnat/s-scaval.adb: Add use clause for Interfaces. * libgnat/s-scaval__128.ads, libgnat/s-scaval__128.adb: New package. * libgnat/s-unstyp.ads (Long_Long_Long_Unsigned): New modular type. (Shift_Left, Shift_Right, Shift_Right_Arithmetic, Rotate_Left, Rotate_Right): New intrinsic functions operating on it. gcc/testsuite/ * gnat.dg/multfixed.adb: Update expected exception message.
500 lines
16 KiB
Ada
500 lines
16 KiB
Ada
------------------------------------------------------------------------------
|
|
-- --
|
|
-- GNAT COMPILER COMPONENTS --
|
|
-- --
|
|
-- S E M _ I N T R --
|
|
-- --
|
|
-- B o d y --
|
|
-- --
|
|
-- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
|
|
-- --
|
|
-- GNAT is free software; you can redistribute it and/or modify it under --
|
|
-- terms of the GNU General Public License as published by the Free Soft- --
|
|
-- ware Foundation; either version 3, or (at your option) any later ver- --
|
|
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
|
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
|
|
-- for more details. You should have received a copy of the GNU General --
|
|
-- Public License distributed with GNAT; see file COPYING3. If not, go to --
|
|
-- http://www.gnu.org/licenses for a complete copy of the license. --
|
|
-- --
|
|
-- GNAT was originally developed by the GNAT team at New York University. --
|
|
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
|
-- --
|
|
------------------------------------------------------------------------------
|
|
|
|
-- Processing for intrinsic subprogram declarations
|
|
|
|
with Atree; use Atree;
|
|
with Einfo; use Einfo;
|
|
with Errout; use Errout;
|
|
with Lib; use Lib;
|
|
with Namet; use Namet;
|
|
with Opt; use Opt;
|
|
with Sem_Aux; use Sem_Aux;
|
|
with Sem_Eval; use Sem_Eval;
|
|
with Sem_Util; use Sem_Util;
|
|
with Sinfo; use Sinfo;
|
|
with Snames; use Snames;
|
|
with Stand; use Stand;
|
|
with Stringt; use Stringt;
|
|
with Ttypes; use Ttypes;
|
|
with Uintp; use Uintp;
|
|
|
|
package body Sem_Intr is
|
|
|
|
-----------------------
|
|
-- Local Subprograms --
|
|
-----------------------
|
|
|
|
procedure Check_Exception_Function (E : Entity_Id; N : Node_Id);
|
|
-- Check use of intrinsic Exception_Message, Exception_Info or
|
|
-- Exception_Name, as used in the DEC compatible Current_Exceptions
|
|
-- package. In each case we must have a parameterless function that
|
|
-- returns type String.
|
|
|
|
procedure Check_Intrinsic_Operator (E : Entity_Id; N : Node_Id);
|
|
-- Check that operator is one of the binary arithmetic operators, and that
|
|
-- the types involved both have underlying integer types.
|
|
|
|
procedure Check_Shift (E : Entity_Id; N : Node_Id);
|
|
-- Check intrinsic shift subprogram, the two arguments are the same
|
|
-- as for Check_Intrinsic_Subprogram (i.e. the entity of the subprogram
|
|
-- declaration, and the node for the pragma argument, used for messages).
|
|
|
|
procedure Errint
|
|
(Msg : String; S : Node_Id; N : Node_Id; Relaxed : Boolean := False);
|
|
-- Post error message for bad intrinsic, the message itself is posted
|
|
-- on the appropriate spec node and another message is placed on the
|
|
-- pragma itself, referring to the spec. S is the node in the spec on
|
|
-- which the message is to be placed, and N is the pragma argument node.
|
|
-- Relaxed is True if the message should not be emitted in
|
|
-- Relaxed_RM_Semantics mode.
|
|
|
|
------------------------------
|
|
-- Check_Exception_Function --
|
|
------------------------------
|
|
|
|
procedure Check_Exception_Function (E : Entity_Id; N : Node_Id) is
|
|
begin
|
|
if Ekind (E) not in E_Function | E_Generic_Function then
|
|
Errint
|
|
("intrinsic exception subprogram must be a function", E, N);
|
|
|
|
elsif Present (First_Formal (E)) then
|
|
Errint
|
|
("intrinsic exception subprogram may not have parameters",
|
|
E, First_Formal (E));
|
|
return;
|
|
|
|
elsif Etype (E) /= Standard_String then
|
|
Errint
|
|
("return type of exception subprogram must be String", E, N);
|
|
return;
|
|
end if;
|
|
end Check_Exception_Function;
|
|
|
|
--------------------------
|
|
-- Check_Intrinsic_Call --
|
|
--------------------------
|
|
|
|
procedure Check_Intrinsic_Call (N : Node_Id) is
|
|
Nam : constant Entity_Id := Entity (Name (N));
|
|
Arg1 : constant Node_Id := First_Actual (N);
|
|
Typ : Entity_Id;
|
|
Rtyp : Entity_Id := Empty;
|
|
Cnam : Name_Id;
|
|
Unam : Node_Id;
|
|
|
|
begin
|
|
-- Set argument type if argument present
|
|
|
|
if Present (Arg1) then
|
|
Typ := Etype (Arg1);
|
|
Rtyp := Underlying_Type (Root_Type (Typ));
|
|
end if;
|
|
|
|
-- Set intrinsic name (getting original name in the generic case)
|
|
|
|
Unam := Ultimate_Alias (Nam);
|
|
|
|
if Present (Parent (Unam))
|
|
and then Present (Generic_Parent (Parent (Unam)))
|
|
then
|
|
Cnam := Chars (Generic_Parent (Parent (Unam)));
|
|
else
|
|
Cnam := Chars (Nam);
|
|
end if;
|
|
|
|
-- For Import_xxx calls, argument must be static string. A string
|
|
-- literal is legal even in Ada 83 mode, where such literals are
|
|
-- not static.
|
|
|
|
if Cnam in Name_Import_Address
|
|
| Name_Import_Largest_Value
|
|
| Name_Import_Value
|
|
then
|
|
if Etype (Arg1) = Any_Type
|
|
or else Raises_Constraint_Error (Arg1)
|
|
then
|
|
null;
|
|
|
|
elsif Nkind (Arg1) /= N_String_Literal
|
|
and then not Is_OK_Static_Expression (Arg1)
|
|
then
|
|
Error_Msg_FE
|
|
("call to & requires static string argument!", N, Nam);
|
|
Why_Not_Static (Arg1);
|
|
|
|
elsif String_Length (Strval (Expr_Value_S (Arg1))) = 0 then
|
|
Error_Msg_NE
|
|
("call to & does not permit null string", N, Nam);
|
|
end if;
|
|
|
|
-- Check for the case of freeing a non-null object which will raise
|
|
-- Constraint_Error. Issue warning here, do the expansion in Exp_Intr.
|
|
|
|
elsif Cnam = Name_Unchecked_Deallocation
|
|
and then Can_Never_Be_Null (Etype (Arg1))
|
|
then
|
|
Error_Msg_N
|
|
("freeing `NOT NULL` object will raise Constraint_Error??", N);
|
|
|
|
-- For unchecked deallocation, error to deallocate from empty pool.
|
|
-- Note: this test used to be in Exp_Intr as a warning, but AI 157
|
|
-- issues a binding interpretation that this should be an error, and
|
|
-- consequently it needs to be done in the semantic analysis so that
|
|
-- the error is issued even in semantics only mode.
|
|
|
|
elsif Cnam = Name_Unchecked_Deallocation
|
|
and then No_Pool_Assigned (Rtyp)
|
|
then
|
|
Error_Msg_N ("deallocation from empty storage pool!", N);
|
|
|
|
-- For now, no other special checks are required
|
|
|
|
else
|
|
return;
|
|
end if;
|
|
end Check_Intrinsic_Call;
|
|
|
|
------------------------------
|
|
-- Check_Intrinsic_Operator --
|
|
------------------------------
|
|
|
|
procedure Check_Intrinsic_Operator (E : Entity_Id; N : Node_Id) is
|
|
Ret : constant Entity_Id := Etype (E);
|
|
Nam : constant Name_Id := Chars (E);
|
|
T1 : Entity_Id;
|
|
T2 : Entity_Id;
|
|
|
|
begin
|
|
-- Arithmetic operators
|
|
|
|
if Nam in Name_Op_Add | Name_Op_Subtract | Name_Op_Multiply |
|
|
Name_Op_Divide | Name_Op_Rem | Name_Op_Mod |
|
|
Name_Op_Abs
|
|
then
|
|
T1 := Etype (First_Formal (E));
|
|
|
|
if No (Next_Formal (First_Formal (E))) then
|
|
if Nam in Name_Op_Add | Name_Op_Subtract | Name_Op_Abs then
|
|
T2 := T1;
|
|
|
|
-- Previous error in declaration
|
|
|
|
else
|
|
return;
|
|
end if;
|
|
|
|
else
|
|
T2 := Etype (Next_Formal (First_Formal (E)));
|
|
end if;
|
|
|
|
-- Same types, predefined operator will apply
|
|
|
|
if Root_Type (T1) = Root_Type (T2)
|
|
or else Root_Type (T1) = Root_Type (Ret)
|
|
then
|
|
null;
|
|
|
|
-- Expansion will introduce conversions if sizes are not equal
|
|
|
|
elsif Is_Integer_Type (Underlying_Type (T1))
|
|
and then Is_Integer_Type (Underlying_Type (T2))
|
|
and then Is_Integer_Type (Underlying_Type (Ret))
|
|
then
|
|
null;
|
|
|
|
else
|
|
Errint
|
|
("types of intrinsic operator operands do not match", E, N);
|
|
end if;
|
|
|
|
-- Comparison operators
|
|
|
|
elsif Nam in Name_Op_Eq | Name_Op_Ge | Name_Op_Gt | Name_Op_Le |
|
|
Name_Op_Lt | Name_Op_Ne
|
|
then
|
|
T1 := Etype (First_Formal (E));
|
|
|
|
-- Return if previous error in declaration, otherwise get T2 type
|
|
|
|
if No (Next_Formal (First_Formal (E))) then
|
|
Check_Error_Detected;
|
|
return;
|
|
|
|
else
|
|
T2 := Etype (Next_Formal (First_Formal (E)));
|
|
end if;
|
|
|
|
if Root_Type (T1) /= Root_Type (T2) then
|
|
Errint
|
|
("types of intrinsic operator must have the same size", E, N);
|
|
end if;
|
|
|
|
if Root_Type (Ret) /= Standard_Boolean then
|
|
Errint
|
|
("result type of intrinsic comparison must be boolean", E, N);
|
|
end if;
|
|
|
|
-- Exponentiation
|
|
|
|
elsif Nam = Name_Op_Expon then
|
|
T1 := Etype (First_Formal (E));
|
|
|
|
if No (Next_Formal (First_Formal (E))) then
|
|
|
|
-- Previous error in declaration
|
|
|
|
return;
|
|
|
|
else
|
|
T2 := Etype (Next_Formal (First_Formal (E)));
|
|
end if;
|
|
|
|
if not (Is_Integer_Type (T1)
|
|
or else
|
|
Is_Floating_Point_Type (T1))
|
|
or else Root_Type (T1) /= Root_Type (Ret)
|
|
or else Root_Type (T2) /= Root_Type (Standard_Integer)
|
|
then
|
|
Errint ("incorrect operands for intrinsic operator", N, E);
|
|
end if;
|
|
|
|
-- All other operators (are there any?) are not handled
|
|
|
|
else
|
|
Errint ("incorrect context for ""Intrinsic"" convention", E, N);
|
|
return;
|
|
end if;
|
|
|
|
-- The type must be fully defined and numeric.
|
|
|
|
if No (Underlying_Type (T1))
|
|
or else not Is_Numeric_Type (Underlying_Type (T1))
|
|
then
|
|
Errint ("intrinsic operator can only apply to numeric types", E, N);
|
|
end if;
|
|
end Check_Intrinsic_Operator;
|
|
|
|
--------------------------------
|
|
-- Check_Intrinsic_Subprogram --
|
|
--------------------------------
|
|
|
|
procedure Check_Intrinsic_Subprogram (E : Entity_Id; N : Node_Id) is
|
|
Spec : constant Node_Id := Specification (Unit_Declaration_Node (E));
|
|
Nam : Name_Id;
|
|
|
|
begin
|
|
if Present (Spec)
|
|
and then Present (Generic_Parent (Spec))
|
|
then
|
|
Nam := Chars (Generic_Parent (Spec));
|
|
else
|
|
Nam := Chars (E);
|
|
end if;
|
|
|
|
-- Check name is valid intrinsic name
|
|
|
|
Get_Name_String (Nam);
|
|
|
|
if Name_Buffer (1) /= 'O'
|
|
and then Nam /= Name_Asm
|
|
and then Nam /= Name_To_Address
|
|
and then Nam not in First_Intrinsic_Name .. Last_Intrinsic_Name
|
|
then
|
|
Errint ("unrecognized intrinsic subprogram", E, N);
|
|
|
|
-- Shift cases. We allow user specification of intrinsic shift operators
|
|
-- for any numeric types.
|
|
|
|
elsif Nam in Name_Rotate_Left | Name_Rotate_Right | Name_Shift_Left |
|
|
Name_Shift_Right | Name_Shift_Right_Arithmetic
|
|
then
|
|
Check_Shift (E, N);
|
|
|
|
-- We always allow intrinsic specifications in language defined units
|
|
-- and in expanded code. We assume that the GNAT implementors know what
|
|
-- they are doing, and do not write or generate junk use of intrinsic.
|
|
|
|
elsif not Comes_From_Source (E)
|
|
or else not Comes_From_Source (N)
|
|
or else In_Predefined_Unit (N)
|
|
then
|
|
null;
|
|
|
|
-- Exception functions
|
|
|
|
elsif Nam in Name_Exception_Information
|
|
| Name_Exception_Message
|
|
| Name_Exception_Name
|
|
then
|
|
Check_Exception_Function (E, N);
|
|
|
|
-- Intrinsic operators
|
|
|
|
elsif Nkind (E) = N_Defining_Operator_Symbol then
|
|
Check_Intrinsic_Operator (E, N);
|
|
|
|
-- Source_Location and navigation functions
|
|
|
|
elsif Nam in Name_File
|
|
| Name_Line
|
|
| Name_Source_Location
|
|
| Name_Enclosing_Entity
|
|
| Name_Compilation_ISO_Date
|
|
| Name_Compilation_Date
|
|
| Name_Compilation_Time
|
|
then
|
|
null;
|
|
|
|
-- For now, no other intrinsic subprograms are recognized in user code
|
|
|
|
else
|
|
Errint ("incorrect context for ""Intrinsic"" convention", E, N);
|
|
end if;
|
|
end Check_Intrinsic_Subprogram;
|
|
|
|
-----------------
|
|
-- Check_Shift --
|
|
-----------------
|
|
|
|
procedure Check_Shift (E : Entity_Id; N : Node_Id) is
|
|
Arg1 : Node_Id;
|
|
Arg2 : Node_Id;
|
|
Size : Nat;
|
|
Typ1 : Entity_Id;
|
|
Typ2 : Entity_Id;
|
|
Ptyp1 : Node_Id;
|
|
Ptyp2 : Node_Id;
|
|
|
|
begin
|
|
if Ekind (E) not in E_Function | E_Generic_Function then
|
|
Errint ("intrinsic shift subprogram must be a function", E, N);
|
|
return;
|
|
end if;
|
|
|
|
Arg1 := First_Formal (E);
|
|
|
|
if Present (Arg1) then
|
|
Arg2 := Next_Formal (Arg1);
|
|
else
|
|
Arg2 := Empty;
|
|
end if;
|
|
|
|
if Arg1 = Empty or else Arg2 = Empty then
|
|
Errint ("intrinsic shift function must have two arguments", E, N);
|
|
return;
|
|
end if;
|
|
|
|
Typ1 := Etype (Arg1);
|
|
Typ2 := Etype (Arg2);
|
|
|
|
Ptyp1 := Parameter_Type (Parent (Arg1));
|
|
Ptyp2 := Parameter_Type (Parent (Arg2));
|
|
|
|
if not Is_Integer_Type (Typ1) then
|
|
Errint ("first argument to shift must be integer type", Ptyp1, N);
|
|
return;
|
|
end if;
|
|
|
|
if Typ2 /= Standard_Natural then
|
|
Errint ("second argument to shift must be type Natural", Ptyp2, N);
|
|
return;
|
|
end if;
|
|
|
|
-- type'Size (not 'Object_Size) must be one of the allowed values
|
|
|
|
Size := UI_To_Int (RM_Size (Typ1));
|
|
|
|
if Size /= 8 and then
|
|
Size /= 16 and then
|
|
Size /= 32 and then
|
|
Size /= 64 and then
|
|
Size /= System_Max_Integer_Size
|
|
then
|
|
if System_Max_Integer_Size > 64 then
|
|
Errint
|
|
("first argument for shift must have size 8, 16, 32, 64 or 128",
|
|
Ptyp1, N, Relaxed => True);
|
|
else
|
|
Errint
|
|
("first argument for shift must have size 8, 16, 32 or 64",
|
|
Ptyp1, N, Relaxed => True);
|
|
end if;
|
|
return;
|
|
|
|
elsif Non_Binary_Modulus (Typ1) then
|
|
Errint ("shifts not allowed for nonbinary modular types", Ptyp1, N);
|
|
|
|
-- For modular type, modulus must be 2**8, 2**16, 2**32, or 2**64.
|
|
-- Don't apply to generic types, since we may not have a modulus value.
|
|
|
|
elsif Is_Modular_Integer_Type (Typ1)
|
|
and then not Is_Generic_Type (Typ1)
|
|
and then Modulus (Typ1) /= Uint_2 ** 8
|
|
and then Modulus (Typ1) /= Uint_2 ** 16
|
|
and then Modulus (Typ1) /= Uint_2 ** 32
|
|
and then Modulus (Typ1) /= Uint_2 ** 64
|
|
and then Modulus (Typ1) /= Uint_2 ** System_Max_Binary_Modulus_Power
|
|
then
|
|
if System_Max_Binary_Modulus_Power > 64 then
|
|
Errint
|
|
("modular type for shift must have modulus of 2'*'*8, "
|
|
& "2'*'*16, 2'*'*32, 2'*'*64 or 2'*'*128", Ptyp1, N,
|
|
Relaxed => True);
|
|
else
|
|
Errint
|
|
("modular type for shift must have modulus of 2'*'*8, "
|
|
& "2'*'*16, 2'*'*32, or 2'*'*64", Ptyp1, N,
|
|
Relaxed => True);
|
|
end if;
|
|
|
|
elsif Etype (Arg1) /= Etype (E) then
|
|
Errint
|
|
("first argument of shift must match return type", Ptyp1, N);
|
|
return;
|
|
end if;
|
|
|
|
Set_Has_Shift_Operator (Base_Type (Typ1));
|
|
end Check_Shift;
|
|
|
|
------------
|
|
-- Errint --
|
|
------------
|
|
|
|
procedure Errint
|
|
(Msg : String; S : Node_Id; N : Node_Id; Relaxed : Boolean := False) is
|
|
begin
|
|
-- Ignore errors on Intrinsic in Relaxed_RM_Semantics mode where we can
|
|
-- be more liberal.
|
|
|
|
if not (Relaxed and Relaxed_RM_Semantics) then
|
|
Error_Msg_N (Msg, S);
|
|
Error_Msg_N ("incorrect intrinsic subprogram, see spec", N);
|
|
end if;
|
|
end Errint;
|
|
|
|
end Sem_Intr;
|