-- --
-- B o d y --
-- --
--- $Revision: 1.25 $
--- --
--- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2009, 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 2, or (at your option) any later ver- --
+-- 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 COPYING. If not, write --
--- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
--- MA 02111-1307, USA. --
+-- 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. --
--- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
Arg1 : constant Node_Id := First_Actual (N);
begin
- -- For Import_xxx calls, argument must be static string
+ -- For Import_xxx calls, argument must be static string. A string
+ -- literal is legal even in Ada83 mode, where such literals are
+ -- not static.
if Cnam = Name_Import_Address
or else
then
null;
- elsif not Is_Static_Expression (Arg1) then
- Error_Msg_NE
- ("call to & requires static string argument", N, Nam);
+ elsif Nkind (Arg1) /= N_String_Literal
+ and then not Is_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
("argument in call to & must be 31 characters or less", 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_Free
+ and then Can_Never_Be_Null (Etype (Arg1))
+ then
+ Error_Msg_N
+ ("freeing `NOT NULL` object will raise Constraint_Error?", N);
+
-- For now, no other special checks are required
else
------------------------------
procedure Check_Intrinsic_Operator (E : Entity_Id; N : Node_Id) is
- Nam : Name_Id := Chars (E);
+ Ret : constant Entity_Id := Etype (E);
+ Nam : constant Name_Id := Chars (E);
T1 : Entity_Id;
T2 : Entity_Id;
- Ret : constant Entity_Id := Etype (E);
begin
+ -- Arithmetic operators
+
if Nam = Name_Op_Add
- or else Nam = Name_Op_Subtract
- or else Nam = Name_Op_Multiply
- or else Nam = Name_Op_Divide
+ or else
+ Nam = Name_Op_Subtract
+ or else
+ Nam = Name_Op_Multiply
+ or else
+ Nam = Name_Op_Divide
+ or else
+ Nam = Name_Op_Rem
+ or else
+ Nam = Name_Op_Mod
+ or else
+ Nam = Name_Op_Abs
then
T1 := Etype (First_Formal (E));
if No (Next_Formal (First_Formal (E))) then
- -- previous error in declaration.
- return;
+ if Nam = Name_Op_Add
+ or else
+ Nam = Name_Op_Subtract
+ or else
+ Nam = Name_Op_Abs
+ then
+ T2 := T1;
+
+ else
+ -- Previous error in declaration
+
+ return;
+ end if;
else
T2 := Etype (Next_Formal (First_Formal (E)));
if Root_Type (T1) /= Root_Type (T2)
or else Root_Type (T1) /= Root_Type (Ret)
then
- Errint (
- "types of intrinsic operator must have the same size", E, N);
+ Errint
+ ("types of intrinsic operator must have the same size", E, N);
+ end if;
+
+ -- Comparison operators
+
+ elsif Nam = Name_Op_Eq
+ or else
+ Nam = Name_Op_Ge
+ or else
+ Nam = Name_Op_Gt
+ or else
+ Nam = Name_Op_Le
+ or else
+ Nam = Name_Op_Lt
+ or else
+ Nam = Name_Op_Ne
+ then
+ T1 := Etype (First_Formal (E));
+
+ if No (Next_Formal (First_Formal (E))) then
+
+ -- Previous error in declaration
+
+ return;
- elsif not Is_Numeric_Type (T1) then
- Errint (
- " intrinsic operator can only apply to numeric types", E, N);
+ 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;
+
+ if not Is_Numeric_Type (T1) then
+ Errint ("intrinsic operator can only apply to numeric types", E, N);
end if;
end Check_Intrinsic_Operator;
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);
-- We always allow intrinsic specifications in language defined units
- -- and in expanded code. We assume that the GNAT implemetors know what
+ -- 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)
Ptyp1, N);
return;
- elsif Is_Modular_Integer_Type (Typ1)
- and then Non_Binary_Modulus (Typ1)
- then
+ elsif Non_Binary_Modulus (Typ1) then
Errint
("shifts not allowed for non-binary modular types",
Ptyp1, N);