2008-05-30 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / ada / sem_intr.adb
blob0b7adc45224c5c816e9098cc446b70ebd5c31247
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S E M _ I N T R --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 -- Processing for intrinsic subprogram declarations
28 with Atree; use Atree;
29 with Einfo; use Einfo;
30 with Errout; use Errout;
31 with Fname; use Fname;
32 with Lib; use Lib;
33 with Namet; use Namet;
34 with Sem_Eval; use Sem_Eval;
35 with Sem_Util; use Sem_Util;
36 with Sinfo; use Sinfo;
37 with Snames; use Snames;
38 with Stand; use Stand;
39 with Stringt; use Stringt;
40 with Targparm; use Targparm;
41 with Uintp; use Uintp;
43 package body Sem_Intr is
45 -----------------------
46 -- Local Subprograms --
47 -----------------------
49 procedure Check_Exception_Function (E : Entity_Id; N : Node_Id);
50 -- Check use of intrinsic Exception_Message, Exception_Info or
51 -- Exception_Name, as used in the DEC compatible Current_Exceptions
52 -- package. In each case we must have a parameterless function that
53 -- returns type String.
55 procedure Check_Intrinsic_Operator (E : Entity_Id; N : Node_Id);
56 -- Check that operator is one of the binary arithmetic operators, and
57 -- that the types involved have the same size.
59 procedure Check_Shift (E : Entity_Id; N : Node_Id);
60 -- Check intrinsic shift subprogram, the two arguments are the same
61 -- as for Check_Intrinsic_Subprogram (i.e. the entity of the subprogram
62 -- declaration, and the node for the pragma argument, used for messages)
64 procedure Errint (Msg : String; S : Node_Id; N : Node_Id);
65 -- Post error message for bad intrinsic, the message itself is posted
66 -- on the appropriate spec node and another message is placed on the
67 -- pragma itself, referring to the spec. S is the node in the spec on
68 -- which the message is to be placed, and N is the pragma argument node.
70 ------------------------------
71 -- Check_Exception_Function --
72 ------------------------------
74 procedure Check_Exception_Function (E : Entity_Id; N : Node_Id) is
75 begin
76 if Ekind (E) /= E_Function
77 and then Ekind (E) /= E_Generic_Function
78 then
79 Errint
80 ("intrinsic exception subprogram must be a function", E, N);
82 elsif Present (First_Formal (E)) then
83 Errint
84 ("intrinsic exception subprogram may not have parameters",
85 E, First_Formal (E));
86 return;
88 elsif Etype (E) /= Standard_String then
89 Errint
90 ("return type of exception subprogram must be String", E, N);
91 return;
92 end if;
93 end Check_Exception_Function;
95 --------------------------
96 -- Check_Intrinsic_Call --
97 --------------------------
99 procedure Check_Intrinsic_Call (N : Node_Id) is
100 Nam : constant Entity_Id := Entity (Name (N));
101 Cnam : constant Name_Id := Chars (Nam);
102 Arg1 : constant Node_Id := First_Actual (N);
104 begin
105 -- For Import_xxx calls, argument must be static string
107 if Cnam = Name_Import_Address
108 or else
109 Cnam = Name_Import_Largest_Value
110 or else
111 Cnam = Name_Import_Value
112 then
113 if Etype (Arg1) = Any_Type
114 or else Raises_Constraint_Error (Arg1)
115 then
116 null;
118 elsif not Is_Static_Expression (Arg1) then
119 Error_Msg_FE
120 ("call to & requires static string argument!", N, Nam);
121 Why_Not_Static (Arg1);
123 elsif String_Length (Strval (Expr_Value_S (Arg1))) = 0 then
124 Error_Msg_NE
125 ("call to & does not permit null string", N, Nam);
127 elsif OpenVMS_On_Target
128 and then String_Length (Strval (Expr_Value_S (Arg1))) > 31
129 then
130 Error_Msg_NE
131 ("argument in call to & must be 31 characters or less", N, Nam);
132 end if;
134 -- Check for the case of freeing a non-null object which will raise
135 -- Constraint_Error. Issue warning here, do the expansion in Exp_Intr.
137 elsif Cnam = Name_Free
138 and then Can_Never_Be_Null (Etype (Arg1))
139 then
140 Error_Msg_N
141 ("freeing `NOT NULL` object will raise Constraint_Error?", N);
143 -- For now, no other special checks are required
145 else
146 return;
147 end if;
148 end Check_Intrinsic_Call;
150 ------------------------------
151 -- Check_Intrinsic_Operator --
152 ------------------------------
154 procedure Check_Intrinsic_Operator (E : Entity_Id; N : Node_Id) is
155 Ret : constant Entity_Id := Etype (E);
156 Nam : constant Name_Id := Chars (E);
157 T1 : Entity_Id;
158 T2 : Entity_Id;
160 begin
161 -- Arithmetic operators
163 if Nam = Name_Op_Add
164 or else
165 Nam = Name_Op_Subtract
166 or else
167 Nam = Name_Op_Multiply
168 or else
169 Nam = Name_Op_Divide
170 or else
171 Nam = Name_Op_Rem
172 or else
173 Nam = Name_Op_Mod
174 or else
175 Nam = Name_Op_Abs
176 then
177 T1 := Etype (First_Formal (E));
179 if No (Next_Formal (First_Formal (E))) then
181 if Nam = Name_Op_Add
182 or else
183 Nam = Name_Op_Subtract
184 or else
185 Nam = Name_Op_Abs
186 then
187 T2 := T1;
189 else
190 -- Previous error in declaration
192 return;
193 end if;
195 else
196 T2 := Etype (Next_Formal (First_Formal (E)));
197 end if;
199 if Root_Type (T1) /= Root_Type (T2)
200 or else Root_Type (T1) /= Root_Type (Ret)
201 then
202 Errint
203 ("types of intrinsic operator must have the same size", E, N);
204 end if;
206 -- Comparison operators
208 elsif Nam = Name_Op_Eq
209 or else
210 Nam = Name_Op_Ge
211 or else
212 Nam = Name_Op_Gt
213 or else
214 Nam = Name_Op_Le
215 or else
216 Nam = Name_Op_Lt
217 or else
218 Nam = Name_Op_Ne
219 then
220 T1 := Etype (First_Formal (E));
222 if No (Next_Formal (First_Formal (E))) then
224 -- Previous error in declaration
226 return;
228 else
229 T2 := Etype (Next_Formal (First_Formal (E)));
230 end if;
232 if Root_Type (T1) /= Root_Type (T2) then
233 Errint
234 ("types of intrinsic operator must have the same size", E, N);
235 end if;
237 if Root_Type (Ret) /= Standard_Boolean then
238 Errint
239 ("result type of intrinsic comparison must be boolean", E, N);
240 end if;
242 -- Exponentiation
244 elsif Nam = Name_Op_Expon then
245 T1 := Etype (First_Formal (E));
247 if No (Next_Formal (First_Formal (E))) then
249 -- Previous error in declaration
251 return;
253 else
254 T2 := Etype (Next_Formal (First_Formal (E)));
255 end if;
257 if not (Is_Integer_Type (T1)
258 or else
259 Is_Floating_Point_Type (T1))
260 or else Root_Type (T1) /= Root_Type (Ret)
261 or else Root_Type (T2) /= Root_Type (Standard_Integer)
262 then
263 Errint ("incorrect operands for intrinsic operator", N, E);
264 end if;
266 -- All other operators (are there any?) are not handled
268 else
269 Errint ("incorrect context for ""Intrinsic"" convention", E, N);
270 return;
271 end if;
273 if not Is_Numeric_Type (T1) then
274 Errint ("intrinsic operator can only apply to numeric types", E, N);
275 end if;
276 end Check_Intrinsic_Operator;
278 --------------------------------
279 -- Check_Intrinsic_Subprogram --
280 --------------------------------
282 procedure Check_Intrinsic_Subprogram (E : Entity_Id; N : Node_Id) is
283 Spec : constant Node_Id := Specification (Unit_Declaration_Node (E));
284 Nam : Name_Id;
286 begin
287 if Present (Spec)
288 and then Present (Generic_Parent (Spec))
289 then
290 Nam := Chars (Generic_Parent (Spec));
291 else
292 Nam := Chars (E);
293 end if;
295 -- Check name is valid intrinsic name
297 Get_Name_String (Nam);
299 if Name_Buffer (1) /= 'O'
300 and then Nam /= Name_Asm
301 and then Nam /= Name_To_Address
302 and then Nam not in First_Intrinsic_Name .. Last_Intrinsic_Name
303 then
304 Errint ("unrecognized intrinsic subprogram", E, N);
306 -- We always allow intrinsic specifications in language defined units
307 -- and in expanded code. We assume that the GNAT implementors know what
308 -- they are doing, and do not write or generate junk use of intrinsic!
310 elsif not Comes_From_Source (E)
311 or else not Comes_From_Source (N)
312 or else Is_Predefined_File_Name
313 (Unit_File_Name (Get_Source_Unit (N)))
314 then
315 null;
317 -- Shift cases. We allow user specification of intrinsic shift
318 -- operators for any numeric types.
320 elsif
321 Nam = Name_Rotate_Left
322 or else
323 Nam = Name_Rotate_Right
324 or else
325 Nam = Name_Shift_Left
326 or else
327 Nam = Name_Shift_Right
328 or else
329 Nam = Name_Shift_Right_Arithmetic
330 then
331 Check_Shift (E, N);
333 elsif
334 Nam = Name_Exception_Information
335 or else
336 Nam = Name_Exception_Message
337 or else
338 Nam = Name_Exception_Name
339 then
340 Check_Exception_Function (E, N);
342 elsif Nkind (E) = N_Defining_Operator_Symbol then
343 Check_Intrinsic_Operator (E, N);
345 elsif Nam = Name_File
346 or else Nam = Name_Line
347 or else Nam = Name_Source_Location
348 or else Nam = Name_Enclosing_Entity
349 then
350 null;
352 -- For now, no other intrinsic subprograms are recognized in user code
354 else
355 Errint ("incorrect context for ""Intrinsic"" convention", E, N);
356 end if;
357 end Check_Intrinsic_Subprogram;
359 -----------------
360 -- Check_Shift --
361 -----------------
363 procedure Check_Shift (E : Entity_Id; N : Node_Id) is
364 Arg1 : Node_Id;
365 Arg2 : Node_Id;
366 Size : Nat;
367 Typ1 : Entity_Id;
368 Typ2 : Entity_Id;
369 Ptyp1 : Node_Id;
370 Ptyp2 : Node_Id;
372 begin
373 if Ekind (E) /= E_Function
374 and then Ekind (E) /= E_Generic_Function
375 then
376 Errint ("intrinsic shift subprogram must be a function", E, N);
377 return;
378 end if;
380 Arg1 := First_Formal (E);
382 if Present (Arg1) then
383 Arg2 := Next_Formal (Arg1);
384 else
385 Arg2 := Empty;
386 end if;
388 if Arg1 = Empty or else Arg2 = Empty then
389 Errint ("intrinsic shift function must have two arguments", E, N);
390 return;
391 end if;
393 Typ1 := Etype (Arg1);
394 Typ2 := Etype (Arg2);
396 Ptyp1 := Parameter_Type (Parent (Arg1));
397 Ptyp2 := Parameter_Type (Parent (Arg2));
399 if not Is_Integer_Type (Typ1) then
400 Errint ("first argument to shift must be integer type", Ptyp1, N);
401 return;
402 end if;
404 if Typ2 /= Standard_Natural then
405 Errint ("second argument to shift must be type Natural", Ptyp2, N);
406 return;
407 end if;
409 Size := UI_To_Int (Esize (Typ1));
411 if Size /= 8
412 and then Size /= 16
413 and then Size /= 32
414 and then Size /= 64
415 then
416 Errint
417 ("first argument for shift must have size 8, 16, 32 or 64",
418 Ptyp1, N);
419 return;
421 elsif Non_Binary_Modulus (Typ1) then
422 Errint
423 ("shifts not allowed for non-binary modular types",
424 Ptyp1, N);
426 elsif Etype (Arg1) /= Etype (E) then
427 Errint
428 ("first argument of shift must match return type", Ptyp1, N);
429 return;
430 end if;
431 end Check_Shift;
433 ------------
434 -- Errint --
435 ------------
437 procedure Errint (Msg : String; S : Node_Id; N : Node_Id) is
438 begin
439 Error_Msg_N (Msg, S);
440 Error_Msg_N ("incorrect intrinsic subprogram, see spec", N);
441 end Errint;
443 end Sem_Intr;