1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * T R A N S *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 1992-2019, 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 see *
19 * <http://www.gnu.org/licenses/>. *
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 ****************************************************************************/
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "target.h"
30 #include "function.h"
31 #include "bitmap.h"
32 #include "tree.h"
33 #include "gimple-expr.h"
34 #include "stringpool.h"
35 #include "cgraph.h"
36 #include "predict.h"
37 #include "diagnostic.h"
38 #include "alias.h"
39 #include "fold-const.h"
40 #include "stor-layout.h"
41 #include "stmt.h"
42 #include "varasm.h"
43 #include "output.h"
44 #include "debug.h"
45 #include "libfuncs.h" /* For set_stack_check_libfunc. */
46 #include "tree-iterator.h"
47 #include "gimplify.h"
48 #include "opts.h"
49 #include "common/common-target.h"
50 #include "gomp-constants.h"
51 #include "stringpool.h"
52 #include "attribs.h"
53
54 #include "ada.h"
55 #include "adadecode.h"
56 #include "types.h"
57 #include "atree.h"
58 #include "namet.h"
59 #include "nlists.h"
60 #include "snames.h"
61 #include "stringt.h"
62 #include "uintp.h"
63 #include "urealp.h"
64 #include "fe.h"
65 #include "sinfo.h"
66 #include "einfo.h"
67 #include "gadaint.h"
68 #include "ada-tree.h"
69 #include "gigi.h"
70
71 /* We should avoid allocating more than ALLOCA_THRESHOLD bytes via alloca,
72 for fear of running out of stack space. If we need more, we use xmalloc
73 instead. */
74 #define ALLOCA_THRESHOLD 1000
75
76 /* Pointers to front-end tables accessed through macros. */
77 struct Node *Nodes_Ptr;
78 struct Flags *Flags_Ptr;
79 Node_Id *Next_Node_Ptr;
80 Node_Id *Prev_Node_Ptr;
81 struct Elist_Header *Elists_Ptr;
82 struct Elmt_Item *Elmts_Ptr;
83 struct String_Entry *Strings_Ptr;
84 Char_Code *String_Chars_Ptr;
85 struct List_Header *List_Headers_Ptr;
86
87 /* Highest number in the front-end node table. */
88 int max_gnat_nodes;
89
90 /* True when gigi is being called on an analyzed but unexpanded
91 tree, and the only purpose of the call is to properly annotate
92 types with representation information. */
93 bool type_annotate_only;
94
95 /* List of N_Validate_Unchecked_Conversion nodes in the unit. */
96 static vec<Node_Id> gnat_validate_uc_list;
97
98 /* List of expressions of pragma Compile_Time_{Error|Warning} in the unit. */
99 static vec<Node_Id> gnat_compile_time_expr_list;
100
101 /* When not optimizing, we cache the 'First, 'Last and 'Length attributes
102 of unconstrained array IN parameters to avoid emitting a great deal of
103 redundant instructions to recompute them each time. */
104 struct GTY (()) parm_attr_d {
105 int id; /* GTY doesn't like Entity_Id. */
106 int dim;
107 tree first;
108 tree last;
109 tree length;
110 };
111
112 typedef struct parm_attr_d *parm_attr;
113
114
115 struct GTY(()) language_function {
116 vec<parm_attr, va_gc> *parm_attr_cache;
117 bitmap named_ret_val;
118 vec<tree, va_gc> *other_ret_val;
119 int gnat_ret;
120 };
121
122 #define f_parm_attr_cache \
123 DECL_STRUCT_FUNCTION (current_function_decl)->language->parm_attr_cache
124
125 #define f_named_ret_val \
126 DECL_STRUCT_FUNCTION (current_function_decl)->language->named_ret_val
127
128 #define f_other_ret_val \
129 DECL_STRUCT_FUNCTION (current_function_decl)->language->other_ret_val
130
131 #define f_gnat_ret \
132 DECL_STRUCT_FUNCTION (current_function_decl)->language->gnat_ret
133
134 /* A structure used to gather together information about a statement group.
135 We use this to gather related statements, for example the "then" part
136 of a IF. In the case where it represents a lexical scope, we may also
137 have a BLOCK node corresponding to it and/or cleanups. */
138
139 struct GTY((chain_next ("%h.previous"))) stmt_group {
140 struct stmt_group *previous; /* Previous code group. */
141 tree stmt_list; /* List of statements for this code group. */
142 tree block; /* BLOCK for this code group, if any. */
143 tree cleanups; /* Cleanups for this code group, if any. */
144 };
145
146 static GTY(()) struct stmt_group *current_stmt_group;
147
148 /* List of unused struct stmt_group nodes. */
149 static GTY((deletable)) struct stmt_group *stmt_group_free_list;
150
151 /* A structure used to record information on elaboration procedures
152 we've made and need to process.
153
154 ??? gnat_node should be Node_Id, but gengtype gets confused. */
155
156 struct GTY((chain_next ("%h.next"))) elab_info {
157 struct elab_info *next; /* Pointer to next in chain. */
158 tree elab_proc; /* Elaboration procedure. */
159 int gnat_node; /* The N_Compilation_Unit. */
160 };
161
162 static GTY(()) struct elab_info *elab_info_list;
163
164 /* Stack of exception pointer variables. Each entry is the VAR_DECL
165 that stores the address of the raised exception. Nonzero means we
166 are in an exception handler. Not used in the zero-cost case. */
167 static GTY(()) vec<tree, va_gc> *gnu_except_ptr_stack;
168
169 /* In ZCX case, current exception pointer. Used to re-raise it. */
170 static GTY(()) tree gnu_incoming_exc_ptr;
171
172 /* Stack for storing the current elaboration procedure decl. */
173 static GTY(()) vec<tree, va_gc> *gnu_elab_proc_stack;
174
175 /* Stack of labels to be used as a goto target instead of a return in
176 some functions. See processing for N_Subprogram_Body. */
177 static GTY(()) vec<tree, va_gc> *gnu_return_label_stack;
178
179 /* Stack of variable for the return value of a function with copy-in/copy-out
180 parameters. See processing for N_Subprogram_Body. */
181 static GTY(()) vec<tree, va_gc> *gnu_return_var_stack;
182
183 /* Structure used to record information for a range check. */
184 struct GTY(()) range_check_info_d {
185 tree low_bound;
186 tree high_bound;
187 tree disp;
188 bool neg_p;
189 tree type;
190 tree invariant_cond;
191 tree inserted_cond;
192 };
193
194 typedef struct range_check_info_d *range_check_info;
195
196
197 /* Structure used to record information for a loop. */
198 struct GTY(()) loop_info_d {
199 tree stmt;
200 tree loop_var;
201 tree low_bound;
202 tree high_bound;
203 tree omp_loop_clauses;
204 tree omp_construct_clauses;
205 enum tree_code omp_code;
206 vec<range_check_info, va_gc> *checks;
207 };
208
209 typedef struct loop_info_d *loop_info;
210
211
212 /* Stack of loop_info structures associated with LOOP_STMT nodes. */
213 static GTY(()) vec<loop_info, va_gc> *gnu_loop_stack;
214
215 /* The stacks for N_{Push,Pop}_*_Label. */
216 static vec<Entity_Id> gnu_constraint_error_label_stack;
217 static vec<Entity_Id> gnu_storage_error_label_stack;
218 static vec<Entity_Id> gnu_program_error_label_stack;
219
220 /* Map GNAT tree codes to GCC tree codes for simple expressions. */
221 static enum tree_code gnu_codes[Number_Node_Kinds];
222
223 static void init_code_table (void);
224 static tree get_elaboration_procedure (void);
225 static void Compilation_Unit_to_gnu (Node_Id);
226 static bool empty_stmt_list_p (tree);
227 static void record_code_position (Node_Id);
228 static void insert_code_for (Node_Id);
229 static void add_cleanup (tree, Node_Id);
230 static void add_stmt_list (List_Id);
231 static tree build_stmt_group (List_Id, bool);
232 static inline bool stmt_group_may_fallthru (void);
233 static enum gimplify_status gnat_gimplify_stmt (tree *);
234 static void elaborate_all_entities (Node_Id);
235 static void process_freeze_entity (Node_Id);
236 static void process_decls (List_Id, List_Id, Node_Id, bool, bool);
237 static tree emit_check (tree, tree, int, Node_Id);
238 static tree build_unary_op_trapv (enum tree_code, tree, tree, Node_Id);
239 static tree build_binary_op_trapv (enum tree_code, tree, tree, tree, Node_Id);
240 static tree convert_with_check (Entity_Id, tree, bool, bool, Node_Id);
241 static bool addressable_p (tree, tree);
242 static tree assoc_to_constructor (Entity_Id, Node_Id, tree);
243 static tree pos_to_constructor (Node_Id, tree);
244 static void validate_unchecked_conversion (Node_Id);
245 static Node_Id adjust_for_implicit_deref (Node_Id);
246 static tree maybe_implicit_deref (tree);
247 static void set_expr_location_from_node (tree, Node_Id, bool = false);
248 static void set_gnu_expr_location_from_node (tree, Node_Id);
249 static bool set_end_locus_from_node (tree, Node_Id);
250 static int lvalue_required_p (Node_Id, tree, bool, bool);
251 static tree build_raise_check (int, enum exception_info_kind);
252 static tree create_init_temporary (const char *, tree, tree *, Node_Id);
253 static bool maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk);
254
255 /* Hooks for debug info back-ends, only supported and used in a restricted set
256 of configurations. */
257 static const char *extract_encoding (const char *) ATTRIBUTE_UNUSED;
258 static const char *decode_name (const char *) ATTRIBUTE_UNUSED;
259
260 /* This makes gigi's file_info_ptr visible in this translation unit,
261 so that Sloc_to_locus can look it up when deciding whether to map
262 decls to instances. */
263
264 static struct File_Info_Type *file_map;
265
266 /* This is the main program of the back-end. It sets up all the table
267 structures and then generates code. */
268
269 void
gigi(Node_Id gnat_root,int max_gnat_node,int number_name ATTRIBUTE_UNUSED,struct Node * nodes_ptr,struct Flags * flags_ptr,Node_Id * next_node_ptr,Node_Id * prev_node_ptr,struct Elist_Header * elists_ptr,struct Elmt_Item * elmts_ptr,struct String_Entry * strings_ptr,Char_Code * string_chars_ptr,struct List_Header * list_headers_ptr,Nat number_file,struct File_Info_Type * file_info_ptr,Entity_Id standard_boolean,Entity_Id standard_integer,Entity_Id standard_character,Entity_Id standard_long_long_float,Entity_Id standard_exception_type,Int gigi_operating_mode)270 gigi (Node_Id gnat_root,
271 int max_gnat_node,
272 int number_name ATTRIBUTE_UNUSED,
273 struct Node *nodes_ptr,
274 struct Flags *flags_ptr,
275 Node_Id *next_node_ptr,
276 Node_Id *prev_node_ptr,
277 struct Elist_Header *elists_ptr,
278 struct Elmt_Item *elmts_ptr,
279 struct String_Entry *strings_ptr,
280 Char_Code *string_chars_ptr,
281 struct List_Header *list_headers_ptr,
282 Nat number_file,
283 struct File_Info_Type *file_info_ptr,
284 Entity_Id standard_boolean,
285 Entity_Id standard_integer,
286 Entity_Id standard_character,
287 Entity_Id standard_long_long_float,
288 Entity_Id standard_exception_type,
289 Int gigi_operating_mode)
290 {
291 Node_Id gnat_iter;
292 Entity_Id gnat_literal;
293 tree t, ftype, int64_type;
294 struct elab_info *info;
295 int i;
296
297 max_gnat_nodes = max_gnat_node;
298
299 Nodes_Ptr = nodes_ptr;
300 Flags_Ptr = flags_ptr;
301 Next_Node_Ptr = next_node_ptr;
302 Prev_Node_Ptr = prev_node_ptr;
303 Elists_Ptr = elists_ptr;
304 Elmts_Ptr = elmts_ptr;
305 Strings_Ptr = strings_ptr;
306 String_Chars_Ptr = string_chars_ptr;
307 List_Headers_Ptr = list_headers_ptr;
308
309 type_annotate_only = (gigi_operating_mode == 1);
310
311 if (Generate_SCO_Instance_Table != 0)
312 {
313 file_map = file_info_ptr;
314 maybe_create_decl_to_instance_map (number_file);
315 }
316
317 for (i = 0; i < number_file; i++)
318 {
319 /* Use the identifier table to make a permanent copy of the filename as
320 the name table gets reallocated after Gigi returns but before all the
321 debugging information is output. The __gnat_to_canonical_file_spec
322 call translates filenames from pragmas Source_Reference that contain
323 host style syntax not understood by gdb. */
324 const char *filename
325 = IDENTIFIER_POINTER
326 (get_identifier
327 (__gnat_to_canonical_file_spec
328 (Get_Name_String (file_info_ptr[i].File_Name))));
329
330 /* We rely on the order isomorphism between files and line maps. */
331 gcc_assert ((int) LINEMAPS_ORDINARY_USED (line_table) == i);
332
333 /* We create the line map for a source file at once, with a fixed number
334 of columns chosen to avoid jumping over the next power of 2. */
335 linemap_add (line_table, LC_ENTER, 0, filename, 1);
336 linemap_line_start (line_table, file_info_ptr[i].Num_Source_Lines, 252);
337 linemap_position_for_column (line_table, 252 - 1);
338 linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
339 }
340
341 gcc_assert (Nkind (gnat_root) == N_Compilation_Unit);
342
343 /* Declare the name of the compilation unit as the first global
344 name in order to make the middle-end fully deterministic. */
345 t = create_concat_name (Defining_Entity (Unit (gnat_root)), NULL);
346 first_global_object_name = ggc_strdup (IDENTIFIER_POINTER (t));
347
348 /* Initialize ourselves. */
349 init_code_table ();
350 init_gnat_decl ();
351 init_gnat_utils ();
352
353 /* If we are just annotating types, give VOID_TYPE zero sizes to avoid
354 errors. */
355 if (type_annotate_only)
356 {
357 TYPE_SIZE (void_type_node) = bitsize_zero_node;
358 TYPE_SIZE_UNIT (void_type_node) = size_zero_node;
359 }
360
361 /* Enable GNAT stack checking method if needed */
362 if (!Stack_Check_Probes_On_Target)
363 set_stack_check_libfunc ("_gnat_stack_check");
364
365 /* Retrieve alignment settings. */
366 double_float_alignment = get_target_double_float_alignment ();
367 double_scalar_alignment = get_target_double_scalar_alignment ();
368
369 /* Record the builtin types. Define `integer' and `character' first so that
370 dbx will output them first. */
371 record_builtin_type ("integer", integer_type_node, false);
372 record_builtin_type ("character", char_type_node, false);
373 record_builtin_type ("boolean", boolean_type_node, false);
374 record_builtin_type ("void", void_type_node, false);
375
376 /* Save the type we made for integer as the type for Standard.Integer. */
377 save_gnu_tree (Base_Type (standard_integer),
378 TYPE_NAME (integer_type_node),
379 false);
380
381 /* Likewise for character as the type for Standard.Character. */
382 finish_character_type (char_type_node);
383 save_gnu_tree (Base_Type (standard_character),
384 TYPE_NAME (char_type_node),
385 false);
386
387 /* Likewise for boolean as the type for Standard.Boolean. */
388 save_gnu_tree (Base_Type (standard_boolean),
389 TYPE_NAME (boolean_type_node),
390 false);
391 gnat_literal = First_Literal (Base_Type (standard_boolean));
392 t = UI_To_gnu (Enumeration_Rep (gnat_literal), boolean_type_node);
393 gcc_assert (t == boolean_false_node);
394 t = create_var_decl (get_entity_name (gnat_literal), NULL_TREE,
395 boolean_type_node, t, true, false, false, false, false,
396 true, false, NULL, gnat_literal);
397 save_gnu_tree (gnat_literal, t, false);
398 gnat_literal = Next_Literal (gnat_literal);
399 t = UI_To_gnu (Enumeration_Rep (gnat_literal), boolean_type_node);
400 gcc_assert (t == boolean_true_node);
401 t = create_var_decl (get_entity_name (gnat_literal), NULL_TREE,
402 boolean_type_node, t, true, false, false, false, false,
403 true, false, NULL, gnat_literal);
404 save_gnu_tree (gnat_literal, t, false);
405
406 /* Declare the building blocks of function nodes. */
407 void_list_node = build_tree_list (NULL_TREE, void_type_node);
408 void_ftype = build_function_type_list (void_type_node, NULL_TREE);
409 ptr_void_ftype = build_pointer_type (void_ftype);
410
411 /* Now declare run-time functions. */
412 malloc_decl
413 = create_subprog_decl (get_identifier ("__gnat_malloc"), NULL_TREE,
414 build_function_type_list (ptr_type_node, sizetype,
415 NULL_TREE),
416 NULL_TREE, is_default, true, true, true, false,
417 false, NULL, Empty);
418 DECL_IS_MALLOC (malloc_decl) = 1;
419
420 free_decl
421 = create_subprog_decl (get_identifier ("__gnat_free"), NULL_TREE,
422 build_function_type_list (void_type_node,
423 ptr_type_node, NULL_TREE),
424 NULL_TREE, is_default, true, true, true, false,
425 false, NULL, Empty);
426
427 realloc_decl
428 = create_subprog_decl (get_identifier ("__gnat_realloc"), NULL_TREE,
429 build_function_type_list (ptr_type_node,
430 ptr_type_node, sizetype,
431 NULL_TREE),
432 NULL_TREE, is_default, true, true, true, false,
433 false, NULL, Empty);
434
435 /* This is used for 64-bit multiplication with overflow checking. */
436 int64_type = gnat_type_for_size (64, 0);
437 mulv64_decl
438 = create_subprog_decl (get_identifier ("__gnat_mulv64"), NULL_TREE,
439 build_function_type_list (int64_type, int64_type,
440 int64_type, NULL_TREE),
441 NULL_TREE, is_default, true, true, true, false,
442 false, NULL, Empty);
443
444 /* Name of the _Parent field in tagged record types. */
445 parent_name_id = get_identifier (Get_Name_String (Name_uParent));
446
447 /* Name of the Exception_Data type defined in System.Standard_Library. */
448 exception_data_name_id
449 = get_identifier ("system__standard_library__exception_data");
450
451 /* Make the types and functions used for exception processing. */
452 except_type_node = gnat_to_gnu_type (Base_Type (standard_exception_type));
453
454 jmpbuf_type
455 = build_array_type (gnat_type_for_mode (Pmode, 0),
456 build_index_type (size_int (5)));
457 record_builtin_type ("JMPBUF_T", jmpbuf_type, true);
458 jmpbuf_ptr_type = build_pointer_type (jmpbuf_type);
459
460 /* Functions to get and set the jumpbuf pointer for the current thread. */
461 get_jmpbuf_decl
462 = create_subprog_decl
463 (get_identifier ("system__soft_links__get_jmpbuf_address_soft"),
464 NULL_TREE, build_function_type_list (jmpbuf_ptr_type, NULL_TREE),
465 NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
466
467 set_jmpbuf_decl
468 = create_subprog_decl
469 (get_identifier ("system__soft_links__set_jmpbuf_address_soft"),
470 NULL_TREE, build_function_type_list (void_type_node, jmpbuf_ptr_type,
471 NULL_TREE),
472 NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
473
474 get_excptr_decl
475 = create_subprog_decl
476 (get_identifier ("system__soft_links__get_gnat_exception"), NULL_TREE,
477 build_function_type_list (build_pointer_type (except_type_node),
478 NULL_TREE),
479 NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
480
481 not_handled_by_others_decl = get_identifier ("not_handled_by_others");
482 for (t = TYPE_FIELDS (except_type_node); t; t = DECL_CHAIN (t))
483 if (DECL_NAME (t) == not_handled_by_others_decl)
484 {
485 not_handled_by_others_decl = t;
486 break;
487 }
488 gcc_assert (DECL_P (not_handled_by_others_decl));
489
490 /* setjmp returns an integer and has one operand, which is a pointer to
491 a jmpbuf. */
492 setjmp_decl
493 = create_subprog_decl
494 (get_identifier ("__builtin_setjmp"), NULL_TREE,
495 build_function_type_list (integer_type_node, jmpbuf_ptr_type,
496 NULL_TREE),
497 NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
498 set_decl_built_in_function (setjmp_decl, BUILT_IN_NORMAL, BUILT_IN_SETJMP);
499
500 /* update_setjmp_buf updates a setjmp buffer from the current stack pointer
501 address. */
502 update_setjmp_buf_decl
503 = create_subprog_decl
504 (get_identifier ("__builtin_update_setjmp_buf"), NULL_TREE,
505 build_function_type_list (void_type_node, jmpbuf_ptr_type, NULL_TREE),
506 NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
507 set_decl_built_in_function (update_setjmp_buf_decl, BUILT_IN_NORMAL,
508 BUILT_IN_UPDATE_SETJMP_BUF);
509
510 /* Indicate that it never returns. */
511 ftype = build_function_type_list (void_type_node,
512 build_pointer_type (except_type_node),
513 NULL_TREE);
514 ftype = build_qualified_type (ftype, TYPE_QUAL_VOLATILE);
515 raise_nodefer_decl
516 = create_subprog_decl
517 (get_identifier ("__gnat_raise_nodefer_with_msg"), NULL_TREE, ftype,
518 NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
519
520 set_exception_parameter_decl
521 = create_subprog_decl
522 (get_identifier ("__gnat_set_exception_parameter"), NULL_TREE,
523 build_function_type_list (void_type_node, ptr_type_node, ptr_type_node,
524 NULL_TREE),
525 NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
526
527 /* Hooks to call when entering/leaving an exception handler. */
528 ftype = build_function_type_list (ptr_type_node,
529 ptr_type_node, NULL_TREE);
530 begin_handler_decl
531 = create_subprog_decl (get_identifier ("__gnat_begin_handler_v1"),
532 NULL_TREE, ftype, NULL_TREE,
533 is_default, true, true, true, false, false, NULL,
534 Empty);
535 /* __gnat_begin_handler_v1 is not a dummy procedure, but we arrange
536 for it not to throw. */
537 TREE_NOTHROW (begin_handler_decl) = 1;
538
539 ftype = build_function_type_list (ptr_type_node,
540 ptr_type_node, ptr_type_node,
541 ptr_type_node, NULL_TREE);
542 end_handler_decl
543 = create_subprog_decl (get_identifier ("__gnat_end_handler_v1"), NULL_TREE,
544 ftype, NULL_TREE,
545 is_default, true, true, true, false, false, NULL,
546 Empty);
547
548 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
549 unhandled_except_decl
550 = create_subprog_decl (get_identifier ("__gnat_unhandled_except_handler"),
551 NULL_TREE, ftype, NULL_TREE,
552 is_default, true, true, true, false, false, NULL,
553 Empty);
554
555 /* Indicate that it never returns. */
556 ftype = build_qualified_type (ftype, TYPE_QUAL_VOLATILE);
557 reraise_zcx_decl
558 = create_subprog_decl (get_identifier ("__gnat_reraise_zcx"), NULL_TREE,
559 ftype, NULL_TREE,
560 is_default, true, true, true, false, false, NULL,
561 Empty);
562
563 /* Dummy objects to materialize "others" and "all others" in the exception
564 tables. These are exported by a-exexpr-gcc.adb, so see this unit for
565 the types to use. */
566 others_decl
567 = create_var_decl (get_identifier ("OTHERS"),
568 get_identifier ("__gnat_others_value"),
569 char_type_node, NULL_TREE,
570 true, false, true, false, false, true, false,
571 NULL, Empty);
572
573 all_others_decl
574 = create_var_decl (get_identifier ("ALL_OTHERS"),
575 get_identifier ("__gnat_all_others_value"),
576 char_type_node, NULL_TREE,
577 true, false, true, false, false, true, false,
578 NULL, Empty);
579
580 unhandled_others_decl
581 = create_var_decl (get_identifier ("UNHANDLED_OTHERS"),
582 get_identifier ("__gnat_unhandled_others_value"),
583 char_type_node, NULL_TREE,
584 true, false, true, false, false, true, false,
585 NULL, Empty);
586
587 /* If in no exception handlers mode, all raise statements are redirected to
588 __gnat_last_chance_handler. No need to redefine raise_nodefer_decl since
589 this procedure will never be called in this mode. */
590 if (No_Exception_Handlers_Set ())
591 {
592 /* Indicate that it never returns. */
593 ftype = build_function_type_list (void_type_node,
594 build_pointer_type (char_type_node),
595 integer_type_node, NULL_TREE);
596 ftype = build_qualified_type (ftype, TYPE_QUAL_VOLATILE);
597 tree decl
598 = create_subprog_decl
599 (get_identifier ("__gnat_last_chance_handler"), NULL_TREE, ftype,
600 NULL_TREE, is_default, true, true, true, false, false, NULL,
601 Empty);
602 for (i = 0; i < (int) ARRAY_SIZE (gnat_raise_decls); i++)
603 gnat_raise_decls[i] = decl;
604 }
605 else
606 {
607 /* Otherwise, make one decl for each exception reason. */
608 for (i = 0; i < (int) ARRAY_SIZE (gnat_raise_decls); i++)
609 gnat_raise_decls[i] = build_raise_check (i, exception_simple);
610 for (i = 0; i < (int) ARRAY_SIZE (gnat_raise_decls_ext); i++)
611 gnat_raise_decls_ext[i]
612 = build_raise_check (i,
613 i == CE_Index_Check_Failed
614 || i == CE_Range_Check_Failed
615 || i == CE_Invalid_Data
616 ? exception_range : exception_column);
617 }
618
619 /* Build the special descriptor type and its null node if needed. */
620 if (TARGET_VTABLE_USES_DESCRIPTORS)
621 {
622 tree null_node = fold_convert (ptr_void_ftype, null_pointer_node);
623 tree field_list = NULL_TREE;
624 int j;
625 vec<constructor_elt, va_gc> *null_vec = NULL;
626 constructor_elt *elt;
627
628 fdesc_type_node = make_node (RECORD_TYPE);
629 vec_safe_grow (null_vec, TARGET_VTABLE_USES_DESCRIPTORS);
630 elt = (null_vec->address () + TARGET_VTABLE_USES_DESCRIPTORS - 1);
631
632 for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; j++)
633 {
634 tree field
635 = create_field_decl (NULL_TREE, ptr_void_ftype, fdesc_type_node,
636 NULL_TREE, NULL_TREE, 0, 1);
637 DECL_CHAIN (field) = field_list;
638 field_list = field;
639 elt->index = field;
640 elt->value = null_node;
641 elt--;
642 }
643
644 finish_record_type (fdesc_type_node, nreverse (field_list), 0, false);
645 record_builtin_type ("descriptor", fdesc_type_node, true);
646 null_fdesc_node = gnat_build_constructor (fdesc_type_node, null_vec);
647 }
648
649 longest_float_type_node
650 = get_unpadded_type (Base_Type (standard_long_long_float));
651
652 main_identifier_node = get_identifier ("main");
653
654 /* If we are using the GCC exception mechanism, let GCC know. */
655 if (Back_End_Exceptions ())
656 gnat_init_gcc_eh ();
657
658 /* Initialize the GCC support for FP operations. */
659 gnat_init_gcc_fp ();
660
661 /* Install the builtins we might need, either internally or as user-available
662 facilities for Intrinsic imports. Note that this must be done after the
663 GCC exception mechanism is initialized. */
664 gnat_install_builtins ();
665
666 vec_safe_push (gnu_except_ptr_stack, NULL_TREE);
667
668 gnu_constraint_error_label_stack.safe_push (Empty);
669 gnu_storage_error_label_stack.safe_push (Empty);
670 gnu_program_error_label_stack.safe_push (Empty);
671
672 /* Process any Pragma Ident for the main unit. */
673 if (Present (Ident_String (Main_Unit)))
674 targetm.asm_out.output_ident
675 (TREE_STRING_POINTER (gnat_to_gnu (Ident_String (Main_Unit))));
676
677 /* Force -fno-strict-aliasing if the configuration pragma was seen. */
678 if (No_Strict_Aliasing_CP)
679 flag_strict_aliasing = 0;
680
681 /* Save the current optimization options again after the above possible
682 global_options changes. */
683 optimization_default_node = build_optimization_node (&global_options);
684 optimization_current_node = optimization_default_node;
685
686 /* Now translate the compilation unit proper. */
687 Compilation_Unit_to_gnu (gnat_root);
688
689 /* Then process the N_Validate_Unchecked_Conversion nodes. We do this at
690 the very end to avoid having to second-guess the front-end when we run
691 into dummy nodes during the regular processing. */
692 for (i = 0; gnat_validate_uc_list.iterate (i, &gnat_iter); i++)
693 validate_unchecked_conversion (gnat_iter);
694 gnat_validate_uc_list.release ();
695
696 /* Finally see if we have any elaboration procedures to deal with. */
697 for (info = elab_info_list; info; info = info->next)
698 {
699 tree gnu_body = DECL_SAVED_TREE (info->elab_proc);
700
701 /* We should have a BIND_EXPR but it may not have any statements in it.
702 If it doesn't have any, we have nothing to do except for setting the
703 flag on the GNAT node. Otherwise, process the function as others. */
704 tree gnu_stmts = gnu_body;
705 if (TREE_CODE (gnu_stmts) == BIND_EXPR)
706 gnu_stmts = BIND_EXPR_BODY (gnu_stmts);
707 if (!gnu_stmts || empty_stmt_list_p (gnu_stmts))
708 Set_Has_No_Elaboration_Code (info->gnat_node, 1);
709 else
710 {
711 begin_subprog_body (info->elab_proc);
712 end_subprog_body (gnu_body);
713 rest_of_subprog_body_compilation (info->elab_proc);
714 }
715 }
716
717 /* Destroy ourselves. */
718 file_map = NULL;
719 destroy_gnat_decl ();
720 destroy_gnat_utils ();
721
722 /* We cannot track the location of errors past this point. */
723 Current_Error_Node = Empty;
724 }
725
726 /* Return a subprogram decl corresponding to __gnat_rcheck_xx for the given
727 CHECK if KIND is EXCEPTION_SIMPLE, or else to __gnat_rcheck_xx_ext. */
728
729 static tree
build_raise_check(int check,enum exception_info_kind kind)730 build_raise_check (int check, enum exception_info_kind kind)
731 {
732 tree result, ftype;
733 const char pfx[] = "__gnat_rcheck_";
734
735 strcpy (Name_Buffer, pfx);
736 Name_Len = sizeof (pfx) - 1;
737 Get_RT_Exception_Name (check);
738
739 if (kind == exception_simple)
740 {
741 Name_Buffer[Name_Len] = 0;
742 ftype
743 = build_function_type_list (void_type_node,
744 build_pointer_type (char_type_node),
745 integer_type_node, NULL_TREE);
746 }
747 else
748 {
749 tree t = (kind == exception_column ? NULL_TREE : integer_type_node);
750
751 strcpy (Name_Buffer + Name_Len, "_ext");
752 Name_Buffer[Name_Len + 4] = 0;
753 ftype
754 = build_function_type_list (void_type_node,
755 build_pointer_type (char_type_node),
756 integer_type_node, integer_type_node,
757 t, t, NULL_TREE);
758 }
759
760 /* Indicate that it never returns. */
761 ftype = build_qualified_type (ftype, TYPE_QUAL_VOLATILE);
762 result
763 = create_subprog_decl (get_identifier (Name_Buffer), NULL_TREE, ftype,
764 NULL_TREE, is_default, true, true, true, false,
765 false, NULL, Empty);
766
767 return result;
768 }
769
770 /* Return a positive value if an lvalue is required for GNAT_NODE, which is
771 an N_Attribute_Reference. */
772
773 static int
lvalue_required_for_attribute_p(Node_Id gnat_node)774 lvalue_required_for_attribute_p (Node_Id gnat_node)
775 {
776 switch (Get_Attribute_Id (Attribute_Name (gnat_node)))
777 {
778 case Attr_Pos:
779 case Attr_Val:
780 case Attr_Pred:
781 case Attr_Succ:
782 case Attr_First:
783 case Attr_Last:
784 case Attr_Range_Length:
785 case Attr_Length:
786 case Attr_Object_Size:
787 case Attr_Size:
788 case Attr_Value_Size:
789 case Attr_Component_Size:
790 case Attr_Descriptor_Size:
791 case Attr_Max_Size_In_Storage_Elements:
792 case Attr_Min:
793 case Attr_Max:
794 case Attr_Null_Parameter:
795 case Attr_Passed_By_Reference:
796 case Attr_Mechanism_Code:
797 case Attr_Machine:
798 case Attr_Model:
799 return 0;
800
801 case Attr_Address:
802 case Attr_Access:
803 case Attr_Unchecked_Access:
804 case Attr_Unrestricted_Access:
805 case Attr_Code_Address:
806 case Attr_Pool_Address:
807 case Attr_Alignment:
808 case Attr_Bit_Position:
809 case Attr_Position:
810 case Attr_First_Bit:
811 case Attr_Last_Bit:
812 case Attr_Bit:
813 case Attr_Asm_Input:
814 case Attr_Asm_Output:
815 default:
816 return 1;
817 }
818 }
819
820 /* Return a positive value if an lvalue is required for GNAT_NODE. GNU_TYPE
821 is the type that will be used for GNAT_NODE in the translated GNU tree.
822 CONSTANT indicates whether the underlying object represented by GNAT_NODE
823 is constant in the Ada sense. If it is, ADDRESS_OF_CONSTANT indicates
824 whether its value is the address of another constant. If it isn't, then
825 ADDRESS_OF_CONSTANT is ignored.
826
827 The function climbs up the GNAT tree starting from the node and returns 1
828 upon encountering a node that effectively requires an lvalue downstream.
829 It returns int instead of bool to facilitate usage in non-purely binary
830 logic contexts. */
831
832 static int
lvalue_required_p(Node_Id gnat_node,tree gnu_type,bool constant,bool address_of_constant)833 lvalue_required_p (Node_Id gnat_node, tree gnu_type, bool constant,
834 bool address_of_constant)
835 {
836 Node_Id gnat_parent = Parent (gnat_node), gnat_temp;
837
838 switch (Nkind (gnat_parent))
839 {
840 case N_Reference:
841 return 1;
842
843 case N_Attribute_Reference:
844 return lvalue_required_for_attribute_p (gnat_parent);
845
846 case N_Parameter_Association:
847 case N_Function_Call:
848 case N_Procedure_Call_Statement:
849 /* If the parameter is by reference, an lvalue is required. */
850 return (!constant
851 || must_pass_by_ref (gnu_type)
852 || default_pass_by_ref (gnu_type));
853
854 case N_Indexed_Component:
855 /* Only the array expression can require an lvalue. */
856 if (Prefix (gnat_parent) != gnat_node)
857 return 0;
858
859 /* ??? Consider that referencing an indexed component with a variable
860 index forces the whole aggregate to memory. Note that testing only
861 for literals is conservative, any static expression in the RM sense
862 could probably be accepted with some additional work. */
863 for (gnat_temp = First (Expressions (gnat_parent));
864 Present (gnat_temp);
865 gnat_temp = Next (gnat_temp))
866 if (Nkind (gnat_temp) != N_Character_Literal
867 && Nkind (gnat_temp) != N_Integer_Literal
868 && !(Is_Entity_Name (gnat_temp)
869 && Ekind (Entity (gnat_temp)) == E_Enumeration_Literal))
870 return 1;
871
872 /* ... fall through ... */
873
874 case N_Slice:
875 /* Only the array expression can require an lvalue. */
876 if (Prefix (gnat_parent) != gnat_node)
877 return 0;
878
879 return lvalue_required_p (gnat_parent,
880 get_unpadded_type (Etype (gnat_parent)),
881 constant, address_of_constant);
882
883 case N_Selected_Component:
884 return lvalue_required_p (gnat_parent,
885 get_unpadded_type (Etype (gnat_parent)),
886 constant, address_of_constant);
887
888 case N_Object_Renaming_Declaration:
889 /* We need to preserve addresses through a renaming. */
890 return 1;
891
892 case N_Object_Declaration:
893 /* We cannot use a constructor if this is an atomic object because
894 the actual assignment might end up being done component-wise. */
895 return (!constant
896 ||(Is_Composite_Type (Underlying_Type (Etype (gnat_node)))
897 && Is_Atomic_Or_VFA (Defining_Entity (gnat_parent)))
898 /* We don't use a constructor if this is a class-wide object
899 because the effective type of the object is the equivalent
900 type of the class-wide subtype and it smashes most of the
901 data into an array of bytes to which we cannot convert. */
902 || Ekind ((Etype (Defining_Entity (gnat_parent))))
903 == E_Class_Wide_Subtype);
904
905 case N_Assignment_Statement:
906 /* We cannot use a constructor if the LHS is an atomic object because
907 the actual assignment might end up being done component-wise. */
908 return (!constant
909 || Name (gnat_parent) == gnat_node
910 || (Is_Composite_Type (Underlying_Type (Etype (gnat_node)))
911 && Is_Entity_Name (Name (gnat_parent))
912 && Is_Atomic_Or_VFA (Entity (Name (gnat_parent)))));
913
914 case N_Unchecked_Type_Conversion:
915 if (!constant)
916 return 1;
917
918 /* ... fall through ... */
919
920 case N_Type_Conversion:
921 case N_Qualified_Expression:
922 /* We must look through all conversions because we may need to bypass
923 an intermediate conversion that is meant to be purely formal. */
924 return lvalue_required_p (gnat_parent,
925 get_unpadded_type (Etype (gnat_parent)),
926 constant, address_of_constant);
927
928 case N_Allocator:
929 /* We should only reach here through the N_Qualified_Expression case.
930 Force an lvalue for composite types since a block-copy to the newly
931 allocated area of memory is made. */
932 return Is_Composite_Type (Underlying_Type (Etype (gnat_node)));
933
934 case N_Explicit_Dereference:
935 /* We look through dereferences for address of constant because we need
936 to handle the special cases listed above. */
937 if (constant && address_of_constant)
938 return lvalue_required_p (gnat_parent,
939 get_unpadded_type (Etype (gnat_parent)),
940 true, false);
941
942 /* ... fall through ... */
943
944 default:
945 return 0;
946 }
947
948 gcc_unreachable ();
949 }
950
951 /* Return true if T is a constant DECL node that can be safely replaced
952 by its initializer. */
953
954 static bool
constant_decl_with_initializer_p(tree t)955 constant_decl_with_initializer_p (tree t)
956 {
957 if (!TREE_CONSTANT (t) || !DECL_P (t) || !DECL_INITIAL (t))
958 return false;
959
960 /* Return false for aggregate types that contain a placeholder since
961 their initializers cannot be manipulated easily. */
962 if (AGGREGATE_TYPE_P (TREE_TYPE (t))
963 && !TYPE_IS_FAT_POINTER_P (TREE_TYPE (t))
964 && type_contains_placeholder_p (TREE_TYPE (t)))
965 return false;
966
967 return true;
968 }
969
970 /* Return an expression equivalent to EXP but where constant DECL nodes
971 have been replaced by their initializer. */
972
973 static tree
fold_constant_decl_in_expr(tree exp)974 fold_constant_decl_in_expr (tree exp)
975 {
976 enum tree_code code = TREE_CODE (exp);
977 tree op0;
978
979 switch (code)
980 {
981 case CONST_DECL:
982 case VAR_DECL:
983 if (!constant_decl_with_initializer_p (exp))
984 return exp;
985
986 return DECL_INITIAL (exp);
987
988 case COMPONENT_REF:
989 op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0));
990 if (op0 == TREE_OPERAND (exp, 0))
991 return exp;
992
993 return fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0,
994 TREE_OPERAND (exp, 1), NULL_TREE);
995
996 case BIT_FIELD_REF:
997 op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0));
998 if (op0 == TREE_OPERAND (exp, 0))
999 return exp;
1000
1001 return fold_build3 (BIT_FIELD_REF, TREE_TYPE (exp), op0,
1002 TREE_OPERAND (exp, 1), TREE_OPERAND (exp, 2));
1003
1004 case ARRAY_REF:
1005 case ARRAY_RANGE_REF:
1006 /* If the index is not itself constant, then nothing can be folded. */
1007 if (!TREE_CONSTANT (TREE_OPERAND (exp, 1)))
1008 return exp;
1009 op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0));
1010 if (op0 == TREE_OPERAND (exp, 0))
1011 return exp;
1012
1013 return fold (build4 (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1),
1014 TREE_OPERAND (exp, 2), NULL_TREE));
1015
1016 case REALPART_EXPR:
1017 case IMAGPART_EXPR:
1018 case VIEW_CONVERT_EXPR:
1019 op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0));
1020 if (op0 == TREE_OPERAND (exp, 0))
1021 return exp;
1022
1023 return fold_build1 (code, TREE_TYPE (exp), op0);
1024
1025 default:
1026 return exp;
1027 }
1028
1029 gcc_unreachable ();
1030 }
1031
1032 /* Return true if TYPE and DEF_TYPE are compatible GNAT types for Gigi. */
1033
1034 static bool
Gigi_Types_Compatible(Entity_Id type,Entity_Id def_type)1035 Gigi_Types_Compatible (Entity_Id type, Entity_Id def_type)
1036 {
1037 /* The trivial case. */
1038 if (type == def_type)
1039 return true;
1040
1041 /* A class-wide type is equivalent to a subtype of itself. */
1042 if (Is_Class_Wide_Type (type))
1043 return true;
1044
1045 /* A packed array type is compatible with its implementation type. */
1046 if (Is_Packed (def_type) && type == Packed_Array_Impl_Type (def_type))
1047 return true;
1048
1049 /* If both types are Itypes, one may be a copy of the other. */
1050 if (Is_Itype (def_type) && Is_Itype (type))
1051 return true;
1052
1053 /* If the type is incomplete and comes from a limited context, then also
1054 consider its non-limited view. */
1055 if (Is_Incomplete_Type (def_type)
1056 && From_Limited_With (def_type)
1057 && Present (Non_Limited_View (def_type)))
1058 return Gigi_Types_Compatible (type, Non_Limited_View (def_type));
1059
1060 /* If the type is incomplete/private, then also consider its full view. */
1061 if (Is_Incomplete_Or_Private_Type (def_type)
1062 && Present (Full_View (def_type)))
1063 return Gigi_Types_Compatible (type, Full_View (def_type));
1064
1065 return false;
1066 }
1067
1068 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Identifier,
1069 to a GCC tree, which is returned. GNU_RESULT_TYPE_P is a pointer
1070 to where we should place the result type. */
1071
1072 static tree
Identifier_to_gnu(Node_Id gnat_node,tree * gnu_result_type_p)1073 Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
1074 {
1075 /* The entity of GNAT_NODE and its type. */
1076 Node_Id gnat_entity = (Nkind (gnat_node) == N_Defining_Identifier
1077 || Nkind (gnat_node) == N_Defining_Operator_Symbol)
1078 ? gnat_node : Entity (gnat_node);
1079 Node_Id gnat_entity_type = Etype (gnat_entity);
1080 /* If GNAT_NODE is a constant, whether we should use the initialization
1081 value instead of the constant entity, typically for scalars with an
1082 address clause when the parent doesn't require an lvalue. */
1083 bool use_constant_initializer = false;
1084 /* Whether we should require an lvalue for GNAT_NODE. Needed in
1085 specific circumstances only, so evaluated lazily. < 0 means
1086 unknown, > 0 means known true, 0 means known false. */
1087 int require_lvalue = -1;
1088 Node_Id gnat_result_type;
1089 tree gnu_result, gnu_result_type;
1090
1091 /* If the Etype of this node is not the same as that of the Entity, then
1092 something went wrong, probably in generic instantiation. However, this
1093 does not apply to types. Since we sometime have strange Ekind's, just
1094 do this test for objects, except for discriminants because their type
1095 may have been changed to a subtype by Exp_Ch3.Adjust_Discriminants. */
1096 gcc_assert (!Is_Object (gnat_entity)
1097 || Ekind (gnat_entity) == E_Discriminant
1098 || Etype (gnat_node) == gnat_entity_type
1099 || Gigi_Types_Compatible (Etype (gnat_node), gnat_entity_type));
1100
1101 /* If this is a reference to a deferred constant whose partial view is an
1102 unconstrained private type, the proper type is on the full view of the
1103 constant, not on the full view of the type, which may be unconstrained.
1104
1105 This may be a reference to a type, for example in the prefix of the
1106 attribute Position, generated for dispatching code (see Make_DT in
1107 exp_disp,adb). In that case we need the type itself, not is parent,
1108 in particular if it is a derived type */
1109 if (Ekind (gnat_entity) == E_Constant
1110 && Is_Private_Type (gnat_entity_type)
1111 && (Has_Unknown_Discriminants (gnat_entity_type)
1112 || (Present (Full_View (gnat_entity_type))
1113 && Has_Discriminants (Full_View (gnat_entity_type))))
1114 && Present (Full_View (gnat_entity)))
1115 {
1116 gnat_entity = Full_View (gnat_entity);
1117 gnat_result_type = Etype (gnat_entity);
1118 }
1119 else
1120 {
1121 /* We use the Actual_Subtype only if it has already been elaborated,
1122 as we may be invoked precisely during its elaboration, otherwise
1123 the Etype. Avoid using it for packed arrays to simplify things,
1124 except in a return statement because we need the actual size and
1125 the front-end does not make it explicit in this case. */
1126 if ((Ekind (gnat_entity) == E_Constant
1127 || Ekind (gnat_entity) == E_Variable
1128 || Is_Formal (gnat_entity))
1129 && !(Is_Array_Type (Etype (gnat_entity))
1130 && Present (Packed_Array_Impl_Type (Etype (gnat_entity)))
1131 && Nkind (Parent (gnat_node)) != N_Simple_Return_Statement)
1132 && Present (Actual_Subtype (gnat_entity))
1133 && present_gnu_tree (Actual_Subtype (gnat_entity)))
1134 gnat_result_type = Actual_Subtype (gnat_entity);
1135 else
1136 gnat_result_type = Etype (gnat_node);
1137 }
1138
1139 /* Expand the type of this identifier first, in case it is an enumeral
1140 literal, which only get made when the type is expanded. There is no
1141 order-of-elaboration issue here. */
1142 gnu_result_type = get_unpadded_type (gnat_result_type);
1143
1144 /* If this is a non-imported elementary constant with an address clause,
1145 retrieve the value instead of a pointer to be dereferenced unless
1146 an lvalue is required. This is generally more efficient and actually
1147 required if this is a static expression because it might be used
1148 in a context where a dereference is inappropriate, such as a case
1149 statement alternative or a record discriminant. There is no possible
1150 volatile-ness short-circuit here since Volatile constants must be
1151 imported per C.6. */
1152 if (Ekind (gnat_entity) == E_Constant
1153 && Is_Elementary_Type (gnat_result_type)
1154 && !Is_Imported (gnat_entity)
1155 && Present (Address_Clause (gnat_entity)))
1156 {
1157 require_lvalue
1158 = lvalue_required_p (gnat_node, gnu_result_type, true, false);
1159 use_constant_initializer = !require_lvalue;
1160 }
1161
1162 if (use_constant_initializer)
1163 {
1164 /* If this is a deferred constant, the initializer is attached to
1165 the full view. */
1166 if (Present (Full_View (gnat_entity)))
1167 gnat_entity = Full_View (gnat_entity);
1168
1169 gnu_result = gnat_to_gnu (Expression (Declaration_Node (gnat_entity)));
1170 }
1171 else
1172 gnu_result = gnat_to_gnu_entity (gnat_entity, NULL_TREE, false);
1173
1174 /* Some objects (such as parameters passed by reference, globals of
1175 variable size, and renamed objects) actually represent the address
1176 of the object. In that case, we must do the dereference. Likewise,
1177 deal with parameters to foreign convention subprograms. */
1178 if (DECL_P (gnu_result)
1179 && (DECL_BY_REF_P (gnu_result)
1180 || (TREE_CODE (gnu_result) == PARM_DECL
1181 && DECL_BY_COMPONENT_PTR_P (gnu_result))))
1182 {
1183 const bool read_only = DECL_POINTS_TO_READONLY_P (gnu_result);
1184
1185 /* If it's a PARM_DECL to foreign convention subprogram, convert it. */
1186 if (TREE_CODE (gnu_result) == PARM_DECL
1187 && DECL_BY_COMPONENT_PTR_P (gnu_result))
1188 gnu_result
1189 = convert (build_pointer_type (gnu_result_type), gnu_result);
1190
1191 /* If it's a CONST_DECL, return the underlying constant like below. */
1192 else if (TREE_CODE (gnu_result) == CONST_DECL
1193 && !(DECL_CONST_ADDRESS_P (gnu_result)
1194 && lvalue_required_p (gnat_node, gnu_result_type, true,
1195 true)))
1196 gnu_result = DECL_INITIAL (gnu_result);
1197
1198 /* If it's a renaming pointer, get to the renamed object. */
1199 if (TREE_CODE (gnu_result) == VAR_DECL
1200 && !DECL_LOOP_PARM_P (gnu_result)
1201 && DECL_RENAMED_OBJECT (gnu_result))
1202 gnu_result = DECL_RENAMED_OBJECT (gnu_result);
1203
1204 /* Otherwise, do the final dereference. */
1205 else
1206 {
1207 gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
1208
1209 if ((TREE_CODE (gnu_result) == INDIRECT_REF
1210 || TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF)
1211 && No (Address_Clause (gnat_entity)))
1212 TREE_THIS_NOTRAP (gnu_result) = 1;
1213
1214 if (read_only)
1215 TREE_READONLY (gnu_result) = 1;
1216 }
1217 }
1218
1219 /* If we have a constant declaration and its initializer, try to return the
1220 latter to avoid the need to call fold in lots of places and the need for
1221 elaboration code if this identifier is used as an initializer itself. */
1222 if (constant_decl_with_initializer_p (gnu_result))
1223 {
1224 bool constant_only = (TREE_CODE (gnu_result) == CONST_DECL
1225 && !DECL_CONST_CORRESPONDING_VAR (gnu_result));
1226 bool address_of_constant = (TREE_CODE (gnu_result) == CONST_DECL
1227 && DECL_CONST_ADDRESS_P (gnu_result));
1228
1229 /* If there is a (corresponding) variable or this is the address of a
1230 constant, we only want to return the initializer if an lvalue isn't
1231 required. Evaluate this now if we have not already done so. */
1232 if ((!constant_only || address_of_constant) && require_lvalue < 0)
1233 require_lvalue
1234 = lvalue_required_p (gnat_node, gnu_result_type, true,
1235 address_of_constant);
1236
1237 /* Finally retrieve the initializer if this is deemed valid. */
1238 if ((constant_only && !address_of_constant) || !require_lvalue)
1239 gnu_result = DECL_INITIAL (gnu_result);
1240 }
1241
1242 /* But for a constant renaming we couldn't do that incrementally for its
1243 definition because of the need to return an lvalue so, if the present
1244 context doesn't itself require an lvalue, we try again here. */
1245 else if (Ekind (gnat_entity) == E_Constant
1246 && Is_Elementary_Type (gnat_result_type)
1247 && Present (Renamed_Object (gnat_entity)))
1248 {
1249 if (require_lvalue < 0)
1250 require_lvalue
1251 = lvalue_required_p (gnat_node, gnu_result_type, true, false);
1252 if (!require_lvalue)
1253 gnu_result = fold_constant_decl_in_expr (gnu_result);
1254 }
1255
1256 /* The GNAT tree has the type of a function set to its result type, so we
1257 adjust here. Also use the type of the result if the Etype is a subtype
1258 that is nominally unconstrained. Likewise if this is a deferred constant
1259 of a discriminated type whose full view can be elaborated statically, to
1260 avoid problematic conversions to the nominal subtype. But remove any
1261 padding from the resulting type. */
1262 if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (gnu_result))
1263 || Is_Constr_Subt_For_UN_Aliased (gnat_result_type)
1264 || (Ekind (gnat_entity) == E_Constant
1265 && Present (Full_View (gnat_entity))
1266 && Has_Discriminants (gnat_result_type)
1267 && TREE_CODE (gnu_result) == CONSTRUCTOR))
1268 {
1269 gnu_result_type = TREE_TYPE (gnu_result);
1270 if (TYPE_IS_PADDING_P (gnu_result_type))
1271 gnu_result_type = TREE_TYPE (TYPE_FIELDS (gnu_result_type));
1272 }
1273
1274 *gnu_result_type_p = gnu_result_type;
1275
1276 return gnu_result;
1277 }
1278
1279 /* If GNAT_EXPR is an N_Identifier, N_Integer_Literal or N_Operator_Symbol,
1280 call FN on it. If GNAT_EXPR is an aggregate, call FN on each of its
1281 elements. In both cases, pass GNU_EXPR and DATA as additional arguments.
1282
1283 This function is used everywhere OpenAcc pragmas are processed if these
1284 pragmas can accept aggregates. */
1285
1286 static tree
Iterate_Acc_Clause_Arg(Node_Id gnat_expr,tree gnu_expr,tree (* fn)(Node_Id,tree,void *),void * data)1287 Iterate_Acc_Clause_Arg (Node_Id gnat_expr, tree gnu_expr,
1288 tree (*fn)(Node_Id, tree, void*),
1289 void* data)
1290 {
1291 switch (Nkind (gnat_expr))
1292 {
1293 case N_Aggregate:
1294 if (Present (Expressions (gnat_expr)))
1295 {
1296 for (Node_Id gnat_list_expr = First (Expressions (gnat_expr));
1297 Present (gnat_list_expr);
1298 gnat_list_expr = Next (gnat_list_expr))
1299 gnu_expr = fn (gnat_list_expr, gnu_expr, data);
1300 }
1301 else if (Present (Component_Associations (gnat_expr)))
1302 {
1303 for (Node_Id gnat_list_expr = First (Component_Associations
1304 (gnat_expr));
1305 Present (gnat_list_expr);
1306 gnat_list_expr = Next (gnat_list_expr))
1307 gnu_expr = fn (Expression (gnat_list_expr), gnu_expr, data);
1308 }
1309 else
1310 gcc_unreachable ();
1311 break;
1312
1313 case N_Identifier:
1314 case N_Integer_Literal:
1315 case N_Operator_Symbol:
1316 gnu_expr = fn (gnat_expr, gnu_expr, data);
1317 break;
1318
1319 default:
1320 gcc_unreachable ();
1321 }
1322
1323 return gnu_expr;
1324 }
1325
1326 /* Same as gnat_to_gnu for a GNAT_NODE referenced within an OpenAcc directive,
1327 undoing transformations that are inappropriate for such context. */
1328
1329 tree
Acc_gnat_to_gnu(Node_Id gnat_node)1330 Acc_gnat_to_gnu (Node_Id gnat_node)
1331 {
1332 tree gnu_result = gnat_to_gnu (gnat_node);
1333
1334 /* If gnat_node is an identifier for a boolean, gnat_to_gnu might have
1335 turned it into `identifier != 0`. Since arguments to OpenAcc pragmas
1336 need to be writable, we need to return the identifier residing in such
1337 expressions rather than the expression itself. */
1338 if (Nkind (gnat_node) == N_Identifier
1339 && TREE_CODE (gnu_result) == NE_EXPR
1340 && TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_result, 0))) == BOOLEAN_TYPE
1341 && integer_zerop (TREE_OPERAND (gnu_result, 1)))
1342 gnu_result = TREE_OPERAND (gnu_result, 0);
1343
1344 return gnu_result;
1345 }
1346
1347 /* Turn GNAT_EXPR into a tree node representing an OMP data clause and chain
1348 it to GNU_CLAUSES, a list of pre-existing OMP clauses. GNAT_EXPR should be
1349 a N_Identifier, this is enforced by the frontend.
1350
1351 This function is called every time translation of an argument for an OpenAcc
1352 clause (e.g. Acc_Parallel(Copy => My_Identifier)) is needed. */
1353
1354 static tree
Acc_Data_to_gnu(Node_Id gnat_expr,tree gnu_clauses,void * data)1355 Acc_Data_to_gnu (Node_Id gnat_expr, tree gnu_clauses, void* data)
1356 {
1357 const enum gomp_map_kind kind = *((enum gomp_map_kind*) data);
1358 tree gnu_clause
1359 = build_omp_clause (EXPR_LOCATION(gnu_loop_stack->last ()->stmt),
1360 OMP_CLAUSE_MAP);
1361
1362 gcc_assert (Nkind (gnat_expr) == N_Identifier);
1363 OMP_CLAUSE_DECL (gnu_clause)
1364 = gnat_to_gnu_entity (Entity (gnat_expr), NULL_TREE, false);
1365
1366 TREE_ADDRESSABLE (OMP_CLAUSE_DECL (gnu_clause)) = 1;
1367 OMP_CLAUSE_SET_MAP_KIND (gnu_clause, kind);
1368 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1369
1370 return gnu_clause;
1371 }
1372
1373 /* Turn GNAT_EXPR into a tree node representing an OMP clause and chain it to
1374 GNU_CLAUSES, a list of existing OMP clauses.
1375
1376 This function is used for parsing arguments of non-data clauses (e.g.
1377 Acc_Parallel(Wait => gnatexpr)). */
1378
1379 static tree
Acc_Var_to_gnu(Node_Id gnat_expr,tree gnu_clauses,void * data)1380 Acc_Var_to_gnu (Node_Id gnat_expr, tree gnu_clauses, void* data)
1381 {
1382 const enum omp_clause_code kind = *((enum omp_clause_code*) data);
1383 tree gnu_clause
1384 = build_omp_clause (EXPR_LOCATION (gnu_loop_stack->last ()->stmt), kind);
1385
1386 OMP_CLAUSE_DECL (gnu_clause) = Acc_gnat_to_gnu (gnat_expr);
1387 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1388
1389 return gnu_clause;
1390 }
1391
1392 /* Turn GNAT_EXPR into a tree OMP clause representing a reduction clause.
1393 GNAT_EXPR has to be a N_Identifier, this is enforced by the frontend.
1394
1395 For example, GNAT_EXPR could be My_Identifier in the following pragma:
1396 Acc_Parallel(Reduction => ("+" => My_Identifier)). */
1397
1398 static tree
Acc_Reduc_Var_to_gnu(Node_Id gnat_expr,tree gnu_clauses,void * data)1399 Acc_Reduc_Var_to_gnu (Node_Id gnat_expr, tree gnu_clauses, void* data)
1400 {
1401 const tree_code code = *((tree_code*) data);
1402 tree gnu_clause
1403 = build_omp_clause (EXPR_LOCATION (gnu_loop_stack->last ()->stmt),
1404 OMP_CLAUSE_REDUCTION);
1405
1406 OMP_CLAUSE_DECL (gnu_clause) = Acc_gnat_to_gnu (gnat_expr);
1407 OMP_CLAUSE_REDUCTION_CODE (gnu_clause) = code;
1408 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1409
1410 return gnu_clause;
1411 }
1412
1413 /* Turn GNAT_EXPR into a list of OMP reduction clauses. GNAT_EXPR has to
1414 follow the structure of a reduction clause, e.g. ("+" => Identifier). */
1415
1416 static tree
Acc_Reduc_to_gnu(Node_Id gnat_expr)1417 Acc_Reduc_to_gnu (Node_Id gnat_expr)
1418 {
1419 tree gnu_clauses = NULL_TREE;
1420
1421 for (Node_Id gnat_op = First (Component_Associations (gnat_expr));
1422 Present (gnat_op);
1423 gnat_op = Next (gnat_op))
1424 {
1425 tree_code code = ERROR_MARK;
1426 String_Id str = Strval (First (Choices (gnat_op)));
1427 switch (Get_String_Char (str, 1))
1428 {
1429 case '+':
1430 code = PLUS_EXPR;
1431 break;
1432 case '*':
1433 code = MULT_EXPR;
1434 break;
1435 case 'm':
1436 if (Get_String_Char (str, 2) == 'i'
1437 && Get_String_Char (str, 3) == 'n')
1438 code = MIN_EXPR;
1439 else if (Get_String_Char (str, 2) == 'a'
1440 && Get_String_Char (str, 3) == 'x')
1441 code = MAX_EXPR;
1442 break;
1443 case 'a':
1444 if (Get_String_Char (str, 2) == 'n'
1445 && Get_String_Char (str, 3) == 'd')
1446 code = TRUTH_ANDIF_EXPR;
1447 break;
1448 case 'o':
1449 if (Get_String_Char (str, 2) == 'r')
1450 code = TRUTH_ORIF_EXPR;
1451 break;
1452 default:
1453 gcc_unreachable ();
1454 }
1455
1456 /* Unsupported reduction operation. This should have been
1457 caught in sem_prag.adb. */
1458 gcc_assert (code != ERROR_MARK);
1459
1460 gnu_clauses = Iterate_Acc_Clause_Arg (Expression (gnat_op),
1461 gnu_clauses,
1462 Acc_Reduc_Var_to_gnu,
1463 &code);
1464 }
1465
1466 return gnu_clauses;
1467 }
1468
1469 /* Turn GNAT_EXPR, either '*' or an integer literal, into a tree_cons. This is
1470 only used by Acc_Size_List_to_gnu. */
1471
1472 static tree
Acc_Size_Expr_to_gnu(Node_Id gnat_expr,tree gnu_clauses,void *)1473 Acc_Size_Expr_to_gnu (Node_Id gnat_expr, tree gnu_clauses, void *)
1474 {
1475 tree gnu_expr;
1476
1477 if (Nkind (gnat_expr) == N_Operator_Symbol
1478 && Get_String_Char (Strval (gnat_expr), 1) == '*')
1479 gnu_expr = integer_zero_node;
1480 else
1481 gnu_expr = Acc_gnat_to_gnu (gnat_expr);
1482
1483 return tree_cons (NULL_TREE, gnu_expr, gnu_clauses);
1484 }
1485
1486 /* Turn GNAT_EXPR, an aggregate of either '*' or integer literals, into an OMP
1487 clause node.
1488
1489 This function is used for the Tile clause of the Loop directive. This is
1490 what GNAT_EXPR might look like: (1, 1, '*'). */
1491
1492 static tree
Acc_Size_List_to_gnu(Node_Id gnat_expr)1493 Acc_Size_List_to_gnu (Node_Id gnat_expr)
1494 {
1495 tree gnu_clause
1496 = build_omp_clause (EXPR_LOCATION (gnu_loop_stack->last ()->stmt),
1497 OMP_CLAUSE_TILE);
1498 tree gnu_list = Iterate_Acc_Clause_Arg (gnat_expr, NULL_TREE,
1499 Acc_Size_Expr_to_gnu,
1500 NULL);
1501
1502 OMP_CLAUSE_TILE_LIST (gnu_clause) = nreverse (gnu_list);
1503
1504 return gnu_clause;
1505 }
1506
1507 /* Subroutine of gnat_to_gnu to process gnat_node, an N_Pragma. Return
1508 any statements we generate. */
1509
1510 static tree
Pragma_to_gnu(Node_Id gnat_node)1511 Pragma_to_gnu (Node_Id gnat_node)
1512 {
1513 tree gnu_result = alloc_stmt_list ();
1514 Node_Id gnat_temp;
1515
1516 /* Check for (and ignore) unrecognized pragmas. */
1517 if (!Is_Pragma_Name (Chars (Pragma_Identifier (gnat_node))))
1518 return gnu_result;
1519
1520 const unsigned char id
1521 = Get_Pragma_Id (Chars (Pragma_Identifier (gnat_node)));
1522
1523 /* Save the expression of pragma Compile_Time_{Error|Warning} for later. */
1524 if (id == Pragma_Compile_Time_Error || id == Pragma_Compile_Time_Warning)
1525 {
1526 gnat_temp = First (Pragma_Argument_Associations (gnat_node));
1527 gnat_compile_time_expr_list.safe_push (Expression (gnat_temp));
1528 return gnu_result;
1529 }
1530
1531 /* Stop there if we are just annotating types. */
1532 if (type_annotate_only)
1533 return gnu_result;
1534
1535 switch (id)
1536 {
1537 case Pragma_Inspection_Point:
1538 /* Do nothing at top level: all such variables are already viewable. */
1539 if (global_bindings_p ())
1540 break;
1541
1542 for (gnat_temp = First (Pragma_Argument_Associations (gnat_node));
1543 Present (gnat_temp);
1544 gnat_temp = Next (gnat_temp))
1545 {
1546 Node_Id gnat_expr = Expression (gnat_temp);
1547 tree gnu_expr = gnat_to_gnu (gnat_expr);
1548 tree asm_constraint = NULL_TREE;
1549 #ifdef ASM_COMMENT_START
1550 char *comment;
1551 #endif
1552 gnu_expr = maybe_unconstrained_array (gnu_expr);
1553 gnat_mark_addressable (gnu_expr);
1554
1555 #ifdef ASM_COMMENT_START
1556 comment = concat (ASM_COMMENT_START,
1557 " inspection point: ",
1558 Get_Name_String (Chars (gnat_expr)),
1559 " is at %0",
1560 NULL);
1561 asm_constraint = build_string (strlen (comment), comment);
1562 free (comment);
1563 #endif
1564 gnu_expr = build5 (ASM_EXPR, void_type_node,
1565 asm_constraint,
1566 NULL_TREE,
1567 tree_cons
1568 (build_tree_list (NULL_TREE,
1569 build_string (1, "m")),
1570 gnu_expr, NULL_TREE),
1571 NULL_TREE, NULL_TREE);
1572 ASM_VOLATILE_P (gnu_expr) = 1;
1573 set_expr_location_from_node (gnu_expr, gnat_node);
1574 append_to_statement_list (gnu_expr, &gnu_result);
1575 }
1576 break;
1577
1578 case Pragma_Acc_Loop:
1579 {
1580 if (!flag_openacc)
1581 break;
1582
1583 tree gnu_clauses = gnu_loop_stack->last ()->omp_loop_clauses;
1584
1585 if (!Present (Pragma_Argument_Associations (gnat_node)))
1586 break;
1587
1588 for (gnat_temp = First (Pragma_Argument_Associations (gnat_node));
1589 Present (gnat_temp);
1590 gnat_temp = Next (gnat_temp))
1591 {
1592 Node_Id gnat_expr = Expression (gnat_temp);
1593 tree gnu_clause = NULL_TREE;
1594 enum omp_clause_code kind;
1595
1596 if (Chars (gnat_temp) == No_Name)
1597 {
1598 /* The clause is an identifier without a parameter. */
1599 switch (Chars (gnat_expr))
1600 {
1601 case Name_Auto:
1602 kind = OMP_CLAUSE_AUTO;
1603 break;
1604 case Name_Gang:
1605 kind = OMP_CLAUSE_GANG;
1606 break;
1607 case Name_Independent:
1608 kind = OMP_CLAUSE_INDEPENDENT;
1609 break;
1610 case Name_Seq:
1611 kind = OMP_CLAUSE_SEQ;
1612 break;
1613 case Name_Vector:
1614 kind = OMP_CLAUSE_VECTOR;
1615 break;
1616 case Name_Worker:
1617 kind = OMP_CLAUSE_WORKER;
1618 break;
1619 default:
1620 gcc_unreachable ();
1621 }
1622 gnu_clause = build_omp_clause (EXPR_LOCATION
1623 (gnu_loop_stack->last ()->stmt),
1624 kind);
1625 }
1626 else
1627 {
1628 /* The clause is an identifier parameter(s). */
1629 switch (Chars (gnat_temp))
1630 {
1631 case Name_Collapse:
1632 gnu_clause = build_omp_clause
1633 (EXPR_LOCATION (gnu_loop_stack->last ()->stmt),
1634 OMP_CLAUSE_COLLAPSE);
1635 OMP_CLAUSE_COLLAPSE_EXPR (gnu_clause) =
1636 Acc_gnat_to_gnu (gnat_expr);
1637 break;
1638 case Name_Device_Type:
1639 /* Unimplemented by GCC yet. */
1640 gcc_unreachable ();
1641 break;
1642 case Name_Independent:
1643 gnu_clause = build_omp_clause
1644 (EXPR_LOCATION (gnu_loop_stack->last ()->stmt),
1645 OMP_CLAUSE_INDEPENDENT);
1646 break;
1647 case Name_Acc_Private:
1648 kind = OMP_CLAUSE_PRIVATE;
1649 gnu_clause = Iterate_Acc_Clause_Arg (gnat_expr, 0,
1650 Acc_Var_to_gnu,
1651 &kind);
1652 break;
1653 case Name_Reduction:
1654 gnu_clause = Acc_Reduc_to_gnu (gnat_expr);
1655 break;
1656 case Name_Tile:
1657 gnu_clause = Acc_Size_List_to_gnu (gnat_expr);
1658 break;
1659 case Name_Gang:
1660 case Name_Vector:
1661 case Name_Worker:
1662 /* These are for the Loop+Kernel combination, which is
1663 unimplemented by the frontend for now. */
1664 default:
1665 gcc_unreachable ();
1666 }
1667 }
1668 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1669 gnu_clauses = gnu_clause;
1670 }
1671 gnu_loop_stack->last ()->omp_loop_clauses = gnu_clauses;
1672 }
1673 break;
1674
1675 /* Grouping the transformation of these pragmas together makes sense
1676 because they are mutually exclusive, share most of their clauses and
1677 the verification that each clause can legally appear for the pragma has
1678 been done in the frontend. */
1679 case Pragma_Acc_Data:
1680 case Pragma_Acc_Kernels:
1681 case Pragma_Acc_Parallel:
1682 {
1683 if (!flag_openacc)
1684 break;
1685
1686 tree gnu_clauses = gnu_loop_stack->last ()->omp_construct_clauses;
1687 if (id == Pragma_Acc_Data)
1688 gnu_loop_stack->last ()->omp_code = OACC_DATA;
1689 else if (id == Pragma_Acc_Kernels)
1690 gnu_loop_stack->last ()->omp_code = OACC_KERNELS;
1691 else if (id == Pragma_Acc_Parallel)
1692 gnu_loop_stack->last ()->omp_code = OACC_PARALLEL;
1693 else
1694 gcc_unreachable ();
1695
1696 if (!Present (Pragma_Argument_Associations (gnat_node)))
1697 break;
1698
1699 for (gnat_temp = First (Pragma_Argument_Associations (gnat_node));
1700 Present (gnat_temp);
1701 gnat_temp = Next (gnat_temp))
1702 {
1703 Node_Id gnat_expr = Expression (gnat_temp);
1704 tree gnu_clause;
1705 enum omp_clause_code clause_code;
1706 enum gomp_map_kind map_kind;
1707
1708 switch (Chars (gnat_temp))
1709 {
1710 case Name_Async:
1711 gnu_clause = build_omp_clause
1712 (EXPR_LOCATION (gnu_loop_stack->last ()->stmt),
1713 OMP_CLAUSE_ASYNC);
1714 OMP_CLAUSE_ASYNC_EXPR (gnu_clause) =
1715 Acc_gnat_to_gnu (gnat_expr);
1716 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1717 gnu_clauses = gnu_clause;
1718 break;
1719
1720 case Name_Num_Gangs:
1721 gnu_clause = build_omp_clause
1722 (EXPR_LOCATION (gnu_loop_stack->last ()->stmt),
1723 OMP_CLAUSE_NUM_GANGS);
1724 OMP_CLAUSE_NUM_GANGS_EXPR (gnu_clause) =
1725 Acc_gnat_to_gnu (gnat_expr);
1726 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1727 gnu_clauses = gnu_clause;
1728 break;
1729
1730 case Name_Num_Workers:
1731 gnu_clause = build_omp_clause
1732 (EXPR_LOCATION (gnu_loop_stack->last ()->stmt),
1733 OMP_CLAUSE_NUM_WORKERS);
1734 OMP_CLAUSE_NUM_WORKERS_EXPR (gnu_clause) =
1735 Acc_gnat_to_gnu (gnat_expr);
1736 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1737 gnu_clauses = gnu_clause;
1738 break;
1739
1740 case Name_Vector_Length:
1741 gnu_clause = build_omp_clause
1742 (EXPR_LOCATION (gnu_loop_stack->last ()->stmt),
1743 OMP_CLAUSE_VECTOR_LENGTH);
1744 OMP_CLAUSE_VECTOR_LENGTH_EXPR (gnu_clause) =
1745 Acc_gnat_to_gnu (gnat_expr);
1746 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1747 gnu_clauses = gnu_clause;
1748 break;
1749
1750 case Name_Wait:
1751 clause_code = OMP_CLAUSE_WAIT;
1752 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1753 Acc_Var_to_gnu,
1754 &clause_code);
1755 break;
1756
1757 case Name_Acc_If:
1758 gnu_clause = build_omp_clause (EXPR_LOCATION
1759 (gnu_loop_stack->last ()->stmt),
1760 OMP_CLAUSE_IF);
1761 OMP_CLAUSE_IF_MODIFIER (gnu_clause) = ERROR_MARK;
1762 OMP_CLAUSE_IF_EXPR (gnu_clause) = Acc_gnat_to_gnu (gnat_expr);
1763 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1764 gnu_clauses = gnu_clause;
1765 break;
1766
1767 case Name_Copy:
1768 map_kind = GOMP_MAP_FORCE_TOFROM;
1769 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1770 Acc_Data_to_gnu,
1771 &map_kind);
1772 break;
1773
1774 case Name_Copy_In:
1775 map_kind = GOMP_MAP_FORCE_TO;
1776 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1777 Acc_Data_to_gnu,
1778 &map_kind);
1779 break;
1780
1781 case Name_Copy_Out:
1782 map_kind = GOMP_MAP_FORCE_FROM;
1783 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1784 Acc_Data_to_gnu,
1785 &map_kind);
1786 break;
1787
1788 case Name_Present:
1789 map_kind = GOMP_MAP_FORCE_PRESENT;
1790 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1791 Acc_Data_to_gnu,
1792 &map_kind);
1793 break;
1794
1795 case Name_Create:
1796 map_kind = GOMP_MAP_FORCE_ALLOC;
1797 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1798 Acc_Data_to_gnu,
1799 &map_kind);
1800 break;
1801
1802 case Name_Device_Ptr:
1803 map_kind = GOMP_MAP_FORCE_DEVICEPTR;
1804 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1805 Acc_Data_to_gnu,
1806 &map_kind);
1807 break;
1808
1809 case Name_Acc_Private:
1810 clause_code = OMP_CLAUSE_PRIVATE;
1811 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1812 Acc_Var_to_gnu,
1813 &clause_code);
1814 break;
1815
1816 case Name_First_Private:
1817 clause_code = OMP_CLAUSE_FIRSTPRIVATE;
1818 gnu_clauses = Iterate_Acc_Clause_Arg (gnat_expr, gnu_clauses,
1819 Acc_Var_to_gnu,
1820 &clause_code);
1821 break;
1822
1823 case Name_Default:
1824 gnu_clause = build_omp_clause (EXPR_LOCATION
1825 (gnu_loop_stack->last ()->stmt),
1826 OMP_CLAUSE_DEFAULT);
1827 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1828 /* The standard also accepts "present" but this isn't
1829 implemented in GCC yet. */
1830 OMP_CLAUSE_DEFAULT_KIND (gnu_clause) = OMP_CLAUSE_DEFAULT_NONE;
1831 OMP_CLAUSE_CHAIN (gnu_clause) = gnu_clauses;
1832 gnu_clauses = gnu_clause;
1833 break;
1834
1835 case Name_Reduction:
1836 gnu_clauses = Acc_Reduc_to_gnu(gnat_expr);
1837 break;
1838
1839 case Name_Detach:
1840 case Name_Attach:
1841 case Name_Device_Type:
1842 /* Unimplemented by GCC. */
1843 default:
1844 gcc_unreachable ();
1845 }
1846 }
1847 gnu_loop_stack->last ()->omp_construct_clauses = gnu_clauses;
1848 }
1849 break;
1850
1851 case Pragma_Loop_Optimize:
1852 for (gnat_temp = First (Pragma_Argument_Associations (gnat_node));
1853 Present (gnat_temp);
1854 gnat_temp = Next (gnat_temp))
1855 {
1856 tree gnu_loop_stmt = gnu_loop_stack->last ()->stmt;
1857
1858 switch (Chars (Expression (gnat_temp)))
1859 {
1860 case Name_Ivdep:
1861 LOOP_STMT_IVDEP (gnu_loop_stmt) = 1;
1862 break;
1863
1864 case Name_No_Unroll:
1865 LOOP_STMT_NO_UNROLL (gnu_loop_stmt) = 1;
1866 break;
1867
1868 case Name_Unroll:
1869 LOOP_STMT_UNROLL (gnu_loop_stmt) = 1;
1870 break;
1871
1872 case Name_No_Vector:
1873 LOOP_STMT_NO_VECTOR (gnu_loop_stmt) = 1;
1874 break;
1875
1876 case Name_Vector:
1877 LOOP_STMT_VECTOR (gnu_loop_stmt) = 1;
1878 break;
1879
1880 default:
1881 gcc_unreachable ();
1882 }
1883 }
1884 break;
1885
1886 case Pragma_Optimize:
1887 switch (Chars (Expression
1888 (First (Pragma_Argument_Associations (gnat_node)))))
1889 {
1890 case Name_Off:
1891 if (optimize)
1892 post_error ("must specify -O0?", gnat_node);
1893 break;
1894
1895 case Name_Space:
1896 if (!optimize_size)
1897 post_error ("must specify -Os?", gnat_node);
1898 break;
1899
1900 case Name_Time:
1901 if (!optimize)
1902 post_error ("insufficient -O value?", gnat_node);
1903 break;
1904
1905 default:
1906 gcc_unreachable ();
1907 }
1908 break;
1909
1910 case Pragma_Reviewable:
1911 if (write_symbols == NO_DEBUG)
1912 post_error ("must specify -g?", gnat_node);
1913 break;
1914
1915 case Pragma_Warning_As_Error:
1916 case Pragma_Warnings:
1917 {
1918 Node_Id gnat_expr;
1919 /* Preserve the location of the pragma. */
1920 const location_t location = input_location;
1921 struct cl_option_handlers handlers;
1922 unsigned int option_index;
1923 diagnostic_t kind;
1924 bool imply;
1925
1926 gnat_temp = First (Pragma_Argument_Associations (gnat_node));
1927
1928 /* This is the String form: pragma Warning{s|_As_Error}(String). */
1929 if (Nkind (Expression (gnat_temp)) == N_String_Literal)
1930 {
1931 switch (id)
1932 {
1933 case Pragma_Warning_As_Error:
1934 kind = DK_ERROR;
1935 imply = false;
1936 break;
1937
1938 case Pragma_Warnings:
1939 kind = DK_WARNING;
1940 imply = true;
1941 break;
1942
1943 default:
1944 gcc_unreachable ();
1945 }
1946
1947 gnat_expr = Expression (gnat_temp);
1948 }
1949
1950 /* This is the On/Off form: pragma Warnings (On | Off [,String]). */
1951 else if (Nkind (Expression (gnat_temp)) == N_Identifier)
1952 {
1953 switch (Chars (Expression (gnat_temp)))
1954 {
1955 case Name_Off:
1956 kind = DK_IGNORED;
1957 break;
1958
1959 case Name_On:
1960 kind = DK_WARNING;
1961 break;
1962
1963 default:
1964 gcc_unreachable ();
1965 }
1966
1967 /* Deal with optional pattern (but ignore Reason => "..."). */
1968 if (Present (Next (gnat_temp))
1969 && Chars (Next (gnat_temp)) != Name_Reason)
1970 {
1971 /* pragma Warnings (On | Off, Name) is handled differently. */
1972 if (Nkind (Expression (Next (gnat_temp))) != N_String_Literal)
1973 break;
1974
1975 gnat_expr = Expression (Next (gnat_temp));
1976 }
1977 else
1978 {
1979 gnat_expr = Empty;
1980
1981 /* For pragma Warnings (Off), we save the current state... */
1982 if (kind == DK_IGNORED)
1983 diagnostic_push_diagnostics (global_dc, location);
1984
1985 /* ...so that, for pragma Warnings (On), we do not enable all
1986 the warnings but just restore the previous state. */
1987 else
1988 {
1989 diagnostic_pop_diagnostics (global_dc, location);
1990 break;
1991 }
1992 }
1993
1994 imply = false;
1995 }
1996
1997 else
1998 gcc_unreachable ();
1999
2000 /* This is the same implementation as in the C family of compilers. */
2001 const unsigned int lang_mask = CL_Ada | CL_COMMON;
2002 const char *arg = NULL;
2003 if (Present (gnat_expr))
2004 {
2005 tree gnu_expr = gnat_to_gnu (gnat_expr);
2006 const char *option_string = TREE_STRING_POINTER (gnu_expr);
2007 const int len = TREE_STRING_LENGTH (gnu_expr);
2008 if (len < 3 || option_string[0] != '-' || option_string[1] != 'W')
2009 break;
2010 option_index = find_opt (option_string + 1, lang_mask);
2011 if (option_index == OPT_SPECIAL_unknown)
2012 {
2013 post_error ("?unknown -W switch", gnat_node);
2014 break;
2015 }
2016 else if (!(cl_options[option_index].flags & CL_WARNING))
2017 {
2018 post_error ("?-W switch does not control warning", gnat_node);
2019 break;
2020 }
2021 else if (!(cl_options[option_index].flags & lang_mask))
2022 {
2023 post_error ("?-W switch not valid for Ada", gnat_node);
2024 break;
2025 }
2026 if (cl_options[option_index].flags & CL_JOINED)
2027 arg = option_string + 1 + cl_options[option_index].opt_len;
2028 }
2029 else
2030 option_index = 0;
2031
2032 set_default_handlers (&handlers, NULL);
2033 control_warning_option (option_index, (int) kind, arg, imply, location,
2034 lang_mask, &handlers, &global_options,
2035 &global_options_set, global_dc);
2036 }
2037 break;
2038
2039 default:
2040 break;
2041 }
2042
2043 return gnu_result;
2044 }
2045
2046 /* Check the inline status of nested function FNDECL wrt its parent function.
2047
2048 If a non-inline nested function is referenced from an inline external
2049 function, we cannot honor both requests at the same time without cloning
2050 the nested function in the current unit since it is private to its unit.
2051 We could inline it as well but it's probably better to err on the side
2052 of too little inlining.
2053
2054 This must be done only on nested functions present in the source code
2055 and not on nested functions generated by the compiler, e.g. finalizers,
2056 because they may be not marked inline and we don't want them to block
2057 the inlining of the parent function. */
2058
2059 static void
check_inlining_for_nested_subprog(tree fndecl)2060 check_inlining_for_nested_subprog (tree fndecl)
2061 {
2062 if (DECL_IGNORED_P (current_function_decl) || DECL_IGNORED_P (fndecl))
2063 return;
2064
2065 if (DECL_DECLARED_INLINE_P (fndecl))
2066 return;
2067
2068 tree parent_decl = decl_function_context (fndecl);
2069 if (DECL_EXTERNAL (parent_decl) && DECL_DECLARED_INLINE_P (parent_decl))
2070 {
2071 const location_t loc1 = DECL_SOURCE_LOCATION (fndecl);
2072 const location_t loc2 = DECL_SOURCE_LOCATION (parent_decl);
2073
2074 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (parent_decl)))
2075 {
2076 error_at (loc1, "subprogram %q+F not marked %<Inline_Always%>",
2077 fndecl);
2078 error_at (loc2, "parent subprogram cannot be inlined");
2079 }
2080 else
2081 {
2082 warning_at (loc1, OPT_Winline, "subprogram %q+F not marked %<Inline%>",
2083 fndecl);
2084 warning_at (loc2, OPT_Winline, "parent subprogram cannot be inlined");
2085 }
2086
2087 DECL_DECLARED_INLINE_P (parent_decl) = 0;
2088 DECL_UNINLINABLE (parent_decl) = 1;
2089 }
2090 }
2091
2092 /* Return an expression for the length of TYPE, an integral type, computed in
2093 RESULT_TYPE, another integral type.
2094
2095 We used to compute the length as MAX (hb - lb + 1, 0) which could overflow
2096 when lb == TYPE'First. We now compute it as (hb >= lb) ? hb - lb + 1 : 0
2097 which would only overflow in much rarer cases, for extremely large arrays
2098 we expect never to encounter in practice. Besides, the former computation
2099 required the use of potentially constraining signed arithmetics while the
2100 latter does not. Note that the comparison must be done in the original
2101 base index type in order to avoid any overflow during the conversion. */
2102
2103 static tree
get_type_length(tree type,tree result_type)2104 get_type_length (tree type, tree result_type)
2105 {
2106 tree comp_type = get_base_type (result_type);
2107 tree base_type = maybe_character_type (get_base_type (type));
2108 tree lb = convert (base_type, TYPE_MIN_VALUE (type));
2109 tree hb = convert (base_type, TYPE_MAX_VALUE (type));
2110 tree length
2111 = build_binary_op (PLUS_EXPR, comp_type,
2112 build_binary_op (MINUS_EXPR, comp_type,
2113 convert (comp_type, hb),
2114 convert (comp_type, lb)),
2115 build_int_cst (comp_type, 1));
2116 length
2117 = build_cond_expr (result_type,
2118 build_binary_op (GE_EXPR, boolean_type_node, hb, lb),
2119 convert (result_type, length),
2120 build_int_cst (result_type, 0));
2121 return length;
2122 }
2123
2124 /* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Attribute node,
2125 to a GCC tree, which is returned. GNU_RESULT_TYPE_P is a pointer to
2126 where we should place the result type. ATTRIBUTE is the attribute ID. */
2127
2128 static tree
Attribute_to_gnu(Node_Id gnat_node,tree * gnu_result_type_p,int attribute)2129 Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
2130 {
2131 const Node_Id gnat_prefix = Prefix (gnat_node);
2132 tree gnu_prefix = gnat_to_gnu (gnat_prefix);
2133 tree gnu_type = TREE_TYPE (gnu_prefix);
2134 tree gnu_expr, gnu_result_type, gnu_result = error_mark_node;
2135 bool prefix_unused = false;
2136
2137 /* If the input is a NULL_EXPR, make a new one. */
2138 if (TREE_CODE (gnu_prefix) == NULL_EXPR)
2139 {
2140 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2141 *gnu_result_type_p = gnu_result_type;
2142 return build1 (NULL_EXPR, gnu_result_type, TREE_OPERAND (gnu_prefix, 0));
2143 }
2144
2145 switch (attribute)
2146 {
2147 case Attr_Pos:
2148 case Attr_Val:
2149 /* These are just conversions since representation clauses for
2150 enumeration types are handled in the front-end. */
2151 gnu_expr = gnat_to_gnu (First (Expressions (gnat_node)));
2152 if (attribute == Attr_Pos)
2153 gnu_expr = maybe_character_value (gnu_expr);
2154 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2155 gnu_result = convert (gnu_result_type, gnu_expr);
2156 break;
2157
2158 case Attr_Pred:
2159 case Attr_Succ:
2160 /* These just add or subtract the constant 1 since representation
2161 clauses for enumeration types are handled in the front-end. */
2162 gnu_expr = gnat_to_gnu (First (Expressions (gnat_node)));
2163 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2164 gnu_type = maybe_character_type (gnu_result_type);
2165 if (TREE_TYPE (gnu_expr) != gnu_type)
2166 gnu_expr = convert (gnu_type, gnu_expr);
2167 gnu_result
2168 = build_binary_op (attribute == Attr_Pred ? MINUS_EXPR : PLUS_EXPR,
2169 gnu_type, gnu_expr, build_int_cst (gnu_type, 1));
2170 break;
2171
2172 case Attr_Address:
2173 case Attr_Unrestricted_Access:
2174 /* Conversions don't change the address of references but can cause
2175 build_unary_op to miss the references below, so strip them off.
2176 On the contrary, if the address-of operation causes a temporary
2177 to be created, then it must be created with the proper type. */
2178 gnu_expr = remove_conversions (gnu_prefix,
2179 !Must_Be_Byte_Aligned (gnat_node));
2180 if (REFERENCE_CLASS_P (gnu_expr))
2181 gnu_prefix = gnu_expr;
2182
2183 /* If we are taking 'Address of an unconstrained object, this is the
2184 pointer to the underlying array. */
2185 if (attribute == Attr_Address)
2186 gnu_prefix = maybe_unconstrained_array (gnu_prefix);
2187
2188 /* If we are building a static dispatch table, we have to honor
2189 TARGET_VTABLE_USES_DESCRIPTORS if we want to be compatible
2190 with the C++ ABI. We do it in the non-static case as well,
2191 see gnat_to_gnu_entity, case E_Access_Subprogram_Type. */
2192 else if (TARGET_VTABLE_USES_DESCRIPTORS
2193 && Is_Dispatch_Table_Entity (Etype (gnat_node)))
2194 {
2195 tree gnu_field, t;
2196 /* Descriptors can only be built here for top-level functions. */
2197 bool build_descriptor = (global_bindings_p () != 0);
2198 int i;
2199 vec<constructor_elt, va_gc> *gnu_vec = NULL;
2200 constructor_elt *elt;
2201
2202 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2203
2204 /* If we're not going to build the descriptor, we have to retrieve
2205 the one which will be built by the linker (or by the compiler
2206 later if a static chain is requested). */
2207 if (!build_descriptor)
2208 {
2209 gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_prefix);
2210 gnu_result = fold_convert (build_pointer_type (gnu_result_type),
2211 gnu_result);
2212 gnu_result = build1 (INDIRECT_REF, gnu_result_type, gnu_result);
2213 }
2214
2215 vec_safe_grow (gnu_vec, TARGET_VTABLE_USES_DESCRIPTORS);
2216 elt = (gnu_vec->address () + TARGET_VTABLE_USES_DESCRIPTORS - 1);
2217 for (gnu_field = TYPE_FIELDS (gnu_result_type), i = 0;
2218 i < TARGET_VTABLE_USES_DESCRIPTORS;
2219 gnu_field = DECL_CHAIN (gnu_field), i++)
2220 {
2221 if (build_descriptor)
2222 {
2223 t = build2 (FDESC_EXPR, TREE_TYPE (gnu_field), gnu_prefix,
2224 build_int_cst (NULL_TREE, i));
2225 TREE_CONSTANT (t) = 1;
2226 }
2227 else
2228 t = build3 (COMPONENT_REF, ptr_void_ftype, gnu_result,
2229 gnu_field, NULL_TREE);
2230
2231 elt->index = gnu_field;
2232 elt->value = t;
2233 elt--;
2234 }
2235
2236 gnu_result = gnat_build_constructor (gnu_result_type, gnu_vec);
2237 break;
2238 }
2239
2240 /* ... fall through ... */
2241
2242 case Attr_Access:
2243 case Attr_Unchecked_Access:
2244 case Attr_Code_Address:
2245 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2246 gnu_result
2247 = build_unary_op (((attribute == Attr_Address
2248 || attribute == Attr_Unrestricted_Access)
2249 && !Must_Be_Byte_Aligned (gnat_node))
2250 ? ATTR_ADDR_EXPR : ADDR_EXPR,
2251 gnu_result_type, gnu_prefix);
2252
2253 /* For 'Code_Address, find an inner ADDR_EXPR and mark it so that we
2254 don't try to build a trampoline. */
2255 if (attribute == Attr_Code_Address)
2256 {
2257 gnu_expr = remove_conversions (gnu_result, false);
2258
2259 if (TREE_CODE (gnu_expr) == ADDR_EXPR)
2260 TREE_NO_TRAMPOLINE (gnu_expr) = TREE_CONSTANT (gnu_expr) = 1;
2261
2262 /* On targets for which function symbols denote a descriptor, the
2263 code address is stored within the first slot of the descriptor
2264 so we do an additional dereference:
2265 result = *((result_type *) result)
2266 where we expect result to be of some pointer type already. */
2267 if (targetm.calls.custom_function_descriptors == 0)
2268 gnu_result
2269 = build_unary_op (INDIRECT_REF, NULL_TREE,
2270 convert (build_pointer_type (gnu_result_type),
2271 gnu_result));
2272 }
2273
2274 /* For 'Access, issue an error message if the prefix is a C++ method
2275 since it can use a special calling convention on some platforms,
2276 which cannot be propagated to the access type. */
2277 else if (attribute == Attr_Access
2278 && TREE_CODE (TREE_TYPE (gnu_prefix)) == METHOD_TYPE)
2279 post_error ("access to C++ constructor or member function not allowed",
2280 gnat_node);
2281
2282 /* For other address attributes applied to a nested function,
2283 find an inner ADDR_EXPR and annotate it so that we can issue
2284 a useful warning with -Wtrampolines. */
2285 else if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (gnu_prefix))
2286 && (gnu_expr = remove_conversions (gnu_result, false))
2287 && TREE_CODE (gnu_expr) == ADDR_EXPR
2288 && decl_function_context (TREE_OPERAND (gnu_expr, 0)))
2289 {
2290 set_expr_location_from_node (gnu_expr, gnat_node);
2291
2292 /* Also check the inlining status. */
2293 check_inlining_for_nested_subprog (TREE_OPERAND (gnu_expr, 0));
2294
2295 /* Moreover, for 'Access or 'Unrestricted_Access with non-
2296 foreign-compatible representation, mark the ADDR_EXPR so
2297 that we can build a descriptor instead of a trampoline. */
2298 if ((attribute == Attr_Access
2299 || attribute == Attr_Unrestricted_Access)
2300 && targetm.calls.custom_function_descriptors > 0
2301 && Can_Use_Internal_Rep (Underlying_Type (Etype (gnat_node))))
2302 FUNC_ADDR_BY_DESCRIPTOR (gnu_expr) = 1;
2303
2304 /* Otherwise, we need to check that we are not violating the
2305 No_Implicit_Dynamic_Code restriction. */
2306 else if (targetm.calls.custom_function_descriptors != 0)
2307 Check_Implicit_Dynamic_Code_Allowed (gnat_node);
2308 }
2309 break;
2310
2311 case Attr_Pool_Address:
2312 {
2313 tree gnu_ptr = gnu_prefix;
2314 tree gnu_obj_type;
2315
2316 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2317
2318 /* If this is fat pointer, the object must have been allocated with the
2319 template in front of the array. So compute the template address; do
2320 it by converting to a thin pointer. */
2321 if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_ptr)))
2322 gnu_ptr
2323 = convert (build_pointer_type
2324 (TYPE_OBJECT_RECORD_TYPE
2325 (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (gnu_ptr)))),
2326 gnu_ptr);
2327
2328 gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr));
2329
2330 /* If this is a thin pointer, the object must have been allocated with
2331 the template in front of the array. So compute the template address
2332 and return it. */
2333 if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
2334 gnu_ptr
2335 = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
2336 gnu_ptr,
2337 fold_build1 (NEGATE_EXPR, sizetype,
2338 byte_position
2339 (DECL_CHAIN
2340 TYPE_FIELDS ((gnu_obj_type)))));
2341
2342 gnu_result = convert (gnu_result_type, gnu_ptr);
2343 }
2344 break;
2345
2346 case Attr_Size:
2347 case Attr_Object_Size:
2348 case Attr_Value_Size:
2349 case Attr_Max_Size_In_Storage_Elements:
2350 /* Strip NOPs, conversions between original and packable versions, and
2351 unpadding from GNU_PREFIX. Note that we cannot simply strip every
2352 VIEW_CONVERT_EXPR because some of them may give the actual size, e.g.
2353 for nominally unconstrained packed array. We use GNU_EXPR to see
2354 if a COMPONENT_REF was involved. */
2355 while (CONVERT_EXPR_P (gnu_prefix)
2356 || TREE_CODE (gnu_prefix) == NON_LVALUE_EXPR
2357 || (TREE_CODE (gnu_prefix) == VIEW_CONVERT_EXPR
2358 && TREE_CODE (TREE_TYPE (gnu_prefix)) == RECORD_TYPE
2359 && TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))
2360 == RECORD_TYPE
2361 && TYPE_NAME (TREE_TYPE (gnu_prefix))
2362 == TYPE_NAME (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))))
2363 gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
2364 gnu_expr = gnu_prefix;
2365 if (TREE_CODE (gnu_prefix) == COMPONENT_REF
2366 && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))))
2367 gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
2368 prefix_unused = true;
2369 gnu_type = TREE_TYPE (gnu_prefix);
2370
2371 /* Replace an unconstrained array type with the type of the underlying
2372 array, except for 'Max_Size_In_Storage_Elements because we need to
2373 return the (maximum) size requested for an allocator. */
2374 if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
2375 {
2376 gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
2377 if (attribute != Attr_Max_Size_In_Storage_Elements)
2378 gnu_type = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type)));
2379 }
2380
2381 /* The type must be frozen at this point. */
2382 gcc_assert (COMPLETE_TYPE_P (gnu_type));
2383
2384 /* If we're looking for the size of a field, return the field size. */
2385 if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
2386 gnu_result = DECL_SIZE (TREE_OPERAND (gnu_prefix, 1));
2387
2388 /* Otherwise, if the prefix is an object, or if we are looking for
2389 'Object_Size or 'Max_Size_In_Storage_Elements, the result is the
2390 GCC size of the type. We make an exception for padded objects,
2391 as we do not take into account alignment promotions for the size.
2392 This is in keeping with the object case of gnat_to_gnu_entity. */
2393 else if ((TREE_CODE (gnu_prefix) != TYPE_DECL
2394 && !(TYPE_IS_PADDING_P (gnu_type)
2395 && TREE_CODE (gnu_expr) == COMPONENT_REF
2396 && pad_type_has_rm_size (gnu_type)))
2397 || attribute == Attr_Object_Size
2398 || attribute == Attr_Max_Size_In_Storage_Elements)
2399 {
2400 /* If this is a dereference and we have a special dynamic constrained
2401 subtype on the prefix, use it to compute the size; otherwise, use
2402 the designated subtype. */
2403 if (Nkind (gnat_prefix) == N_Explicit_Dereference)
2404 {
2405 Node_Id gnat_actual_subtype
2406 = Actual_Designated_Subtype (gnat_prefix);
2407 tree gnu_ptr_type
2408 = TREE_TYPE (gnat_to_gnu (Prefix (gnat_prefix)));
2409
2410 if (TYPE_IS_FAT_OR_THIN_POINTER_P (gnu_ptr_type)
2411 && Present (gnat_actual_subtype))
2412 {
2413 tree gnu_actual_obj_type
2414 = gnat_to_gnu_type (gnat_actual_subtype);
2415 gnu_type
2416 = build_unc_object_type_from_ptr (gnu_ptr_type,
2417 gnu_actual_obj_type,
2418 get_identifier ("SIZE"),
2419 false);
2420 }
2421 }
2422
2423 gnu_result = TYPE_SIZE (gnu_type);
2424 }
2425
2426 /* Otherwise, the result is the RM size of the type. */
2427 else
2428 gnu_result = rm_size (gnu_type);
2429
2430 /* Deal with a self-referential size by qualifying the size with the
2431 object or returning the maximum size for a type. */
2432 if (TREE_CODE (gnu_prefix) != TYPE_DECL)
2433 gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
2434 else if (CONTAINS_PLACEHOLDER_P (gnu_result))
2435 gnu_result = max_size (gnu_result, true);
2436
2437 /* If the type contains a template, subtract the padded size of the
2438 template, except for 'Max_Size_In_Storage_Elements because we need
2439 to return the (maximum) size requested for an allocator. */
2440 if (TREE_CODE (gnu_type) == RECORD_TYPE
2441 && TYPE_CONTAINS_TEMPLATE_P (gnu_type)
2442 && attribute != Attr_Max_Size_In_Storage_Elements)
2443 gnu_result
2444 = size_binop (MINUS_EXPR, gnu_result,
2445 bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type))));
2446
2447 /* For 'Max_Size_In_Storage_Elements, adjust the unit. */
2448 if (attribute == Attr_Max_Size_In_Storage_Elements)
2449 gnu_result = size_binop (CEIL_DIV_EXPR, gnu_result, bitsize_unit_node);
2450
2451 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2452 break;
2453
2454 case Attr_Alignment:
2455 {
2456 unsigned int align;
2457
2458 if (TREE_CODE (gnu_prefix) == COMPONENT_REF
2459 && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))))
2460 gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
2461
2462 gnu_type = TREE_TYPE (gnu_prefix);
2463 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2464 prefix_unused = true;
2465
2466 if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
2467 align = DECL_ALIGN (TREE_OPERAND (gnu_prefix, 1)) / BITS_PER_UNIT;
2468 else
2469 {
2470 Entity_Id gnat_type = Etype (gnat_prefix);
2471 unsigned int double_align;
2472 bool is_capped_double, align_clause;
2473
2474 /* If the default alignment of "double" or larger scalar types is
2475 specifically capped and there is an alignment clause neither
2476 on the type nor on the prefix itself, return the cap. */
2477 if ((double_align = double_float_alignment) > 0)
2478 is_capped_double
2479 = is_double_float_or_array (gnat_type, &align_clause);
2480 else if ((double_align = double_scalar_alignment) > 0)
2481 is_capped_double
2482 = is_double_scalar_or_array (gnat_type, &align_clause);
2483 else
2484 is_capped_double = align_clause = false;
2485
2486 if (is_capped_double
2487 && Nkind (gnat_prefix) == N_Identifier
2488 && Present (Alignment_Clause (Entity (gnat_prefix))))
2489 align_clause = true;
2490
2491 if (is_capped_double && !align_clause)
2492 align = double_align;
2493 else
2494 align = TYPE_ALIGN (gnu_type) / BITS_PER_UNIT;
2495 }
2496
2497 gnu_result = size_int (align);
2498 }
2499 break;
2500
2501 case Attr_First:
2502 case Attr_Last:
2503 case Attr_Range_Length:
2504 prefix_unused = true;
2505
2506 if (INTEGRAL_TYPE_P (gnu_type) || TREE_CODE (gnu_type) == REAL_TYPE)
2507 {
2508 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2509
2510 if (attribute == Attr_First)
2511 gnu_result = TYPE_MIN_VALUE (gnu_type);
2512 else if (attribute == Attr_Last)
2513 gnu_result = TYPE_MAX_VALUE (gnu_type);
2514 else
2515 gnu_result = get_type_length (gnu_type, gnu_result_type);
2516 break;
2517 }
2518
2519 /* ... fall through ... */
2520
2521 case Attr_Length:
2522 {
2523 int Dimension = (Present (Expressions (gnat_node))
2524 ? UI_To_Int (Intval (First (Expressions (gnat_node))))
2525 : 1), i;
2526 struct parm_attr_d *pa = NULL;
2527 Entity_Id gnat_param = Empty;
2528 bool unconstrained_ptr_deref = false;
2529
2530 /* Make sure any implicit dereference gets done. */
2531 gnu_prefix = maybe_implicit_deref (gnu_prefix);
2532 gnu_prefix = maybe_unconstrained_array (gnu_prefix);
2533
2534 /* We treat unconstrained array In parameters specially. We also note
2535 whether we are dereferencing a pointer to unconstrained array. */
2536 if (!Is_Constrained (Etype (gnat_prefix)))
2537 switch (Nkind (gnat_prefix))
2538 {
2539 case N_Identifier:
2540 /* This is the direct case. */
2541 if (Ekind (Entity (gnat_prefix)) == E_In_Parameter)
2542 gnat_param = Entity (gnat_prefix);
2543 break;
2544
2545 case N_Explicit_Dereference:
2546 /* This is the indirect case. Note that we need to be sure that
2547 the access value cannot be null as we'll hoist the load. */
2548 if (Nkind (Prefix (gnat_prefix)) == N_Identifier
2549 && Ekind (Entity (Prefix (gnat_prefix))) == E_In_Parameter)
2550 {
2551 if (Can_Never_Be_Null (Entity (Prefix (gnat_prefix))))
2552 gnat_param = Entity (Prefix (gnat_prefix));
2553 }
2554 else
2555 unconstrained_ptr_deref = true;
2556 break;
2557
2558 default:
2559 break;
2560 }
2561
2562 /* If the prefix is the view conversion of a constrained array to an
2563 unconstrained form, we retrieve the constrained array because we
2564 might not be able to substitute the PLACEHOLDER_EXPR coming from
2565 the conversion. This can occur with the 'Old attribute applied
2566 to a parameter with an unconstrained type, which gets rewritten
2567 into a constrained local variable very late in the game. */
2568 if (TREE_CODE (gnu_prefix) == VIEW_CONVERT_EXPR
2569 && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (TREE_TYPE (gnu_prefix)))
2570 && !CONTAINS_PLACEHOLDER_P
2571 (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))))
2572 gnu_type = TREE_TYPE (TREE_OPERAND (gnu_prefix, 0));
2573 else
2574 gnu_type = TREE_TYPE (gnu_prefix);
2575
2576 prefix_unused = true;
2577 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2578
2579 if (TYPE_CONVENTION_FORTRAN_P (gnu_type))
2580 {
2581 int ndim;
2582 tree gnu_type_temp;
2583
2584 for (ndim = 1, gnu_type_temp = gnu_type;
2585 TREE_CODE (TREE_TYPE (gnu_type_temp)) == ARRAY_TYPE
2586 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type_temp));
2587 ndim++, gnu_type_temp = TREE_TYPE (gnu_type_temp))
2588 ;
2589
2590 Dimension = ndim + 1 - Dimension;
2591 }
2592
2593 for (i = 1; i < Dimension; i++)
2594 gnu_type = TREE_TYPE (gnu_type);
2595
2596 gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);
2597
2598 /* When not optimizing, look up the slot associated with the parameter
2599 and the dimension in the cache and create a new one on failure.
2600 Don't do this when the actual subtype needs debug info (this happens
2601 with -gnatD): in elaborate_expression_1, we create variables that
2602 hold the bounds, so caching attributes isn't very interesting and
2603 causes dependency issues between these variables and cached
2604 expressions. */
2605 if (!optimize
2606 && Present (gnat_param)
2607 && !(Present (Actual_Subtype (gnat_param))
2608 && Needs_Debug_Info (Actual_Subtype (gnat_param))))
2609 {
2610 FOR_EACH_VEC_SAFE_ELT (f_parm_attr_cache, i, pa)
2611 if (pa->id == gnat_param && pa->dim == Dimension)
2612 break;
2613
2614 if (!pa)
2615 {
2616 pa = ggc_cleared_alloc<parm_attr_d> ();
2617 pa->id = gnat_param;
2618 pa->dim = Dimension;
2619 vec_safe_push (f_parm_attr_cache, pa);
2620 }
2621 }
2622
2623 /* Return the cached expression or build a new one. */
2624 if (attribute == Attr_First)
2625 {
2626 if (pa && pa->first)
2627 {
2628 gnu_result = pa->first;
2629 break;
2630 }
2631
2632 gnu_result
2633 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)));
2634 }
2635
2636 else if (attribute == Attr_Last)
2637 {
2638 if (pa && pa->last)
2639 {
2640 gnu_result = pa->last;
2641 break;
2642 }
2643
2644 gnu_result
2645 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)));
2646 }
2647
2648 else /* attribute == Attr_Range_Length || attribute == Attr_Length */
2649 {
2650 if (pa && pa->length)
2651 {
2652 gnu_result = pa->length;
2653 break;
2654 }
2655
2656 gnu_result
2657 = get_type_length (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)),
2658 gnu_result_type);
2659 }
2660
2661 /* If this has a PLACEHOLDER_EXPR, qualify it by the object we are
2662 handling. Note that these attributes could not have been used on
2663 an unconstrained array type. */
2664 gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
2665
2666 /* Cache the expression we have just computed. Since we want to do it
2667 at run time, we force the use of a SAVE_EXPR and let the gimplifier
2668 create the temporary in the outermost binding level. We will make
2669 sure in Subprogram_Body_to_gnu that it is evaluated on all possible
2670 paths by forcing its evaluation on entry of the function. */
2671 if (pa)
2672 {
2673 gnu_result
2674 = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result);
2675 switch (attribute)
2676 {
2677 case Attr_First:
2678 pa->first = gnu_result;
2679 break;
2680
2681 case Attr_Last:
2682 pa->last = gnu_result;
2683 break;
2684
2685 case Attr_Length:
2686 case Attr_Range_Length:
2687 pa->length = gnu_result;
2688 break;
2689
2690 default:
2691 gcc_unreachable ();
2692 }
2693 }
2694
2695 /* Otherwise, evaluate it each time it is referenced. */
2696 else
2697 switch (attribute)
2698 {
2699 case Attr_First:
2700 case Attr_Last:
2701 /* If we are dereferencing a pointer to unconstrained array, we
2702 need to capture the value because the pointed-to bounds may
2703 subsequently be released. */
2704 if (unconstrained_ptr_deref)
2705 gnu_result
2706 = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result);
2707 break;
2708
2709 case Attr_Length:
2710 case Attr_Range_Length:
2711 /* Set the source location onto the predicate of the condition
2712 but not if the expression is cached to avoid messing up the
2713 debug info. */
2714 if (TREE_CODE (gnu_result) == COND_EXPR
2715 && EXPR_P (TREE_OPERAND (gnu_result, 0)))
2716 set_expr_location_from_node (TREE_OPERAND (gnu_result, 0),
2717 gnat_node);
2718 break;
2719
2720 default:
2721 gcc_unreachable ();
2722 }
2723
2724 break;
2725 }
2726
2727 case Attr_Bit_Position:
2728 case Attr_Position:
2729 case Attr_First_Bit:
2730 case Attr_Last_Bit:
2731 case Attr_Bit:
2732 {
2733 poly_int64 bitsize;
2734 poly_int64 bitpos;
2735 tree gnu_offset;
2736 tree gnu_field_bitpos;
2737 tree gnu_field_offset;
2738 tree gnu_inner;
2739 machine_mode mode;
2740 int unsignedp, reversep, volatilep;
2741
2742 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2743 gnu_prefix = remove_conversions (gnu_prefix, true);
2744 prefix_unused = true;
2745
2746 /* We can have 'Bit on any object, but if it isn't a COMPONENT_REF,
2747 the result is 0. Don't allow 'Bit on a bare component, though. */
2748 if (attribute == Attr_Bit
2749 && TREE_CODE (gnu_prefix) != COMPONENT_REF
2750 && TREE_CODE (gnu_prefix) != FIELD_DECL)
2751 {
2752 gnu_result = integer_zero_node;
2753 break;
2754 }
2755
2756 else
2757 gcc_assert (TREE_CODE (gnu_prefix) == COMPONENT_REF
2758 || (attribute == Attr_Bit_Position
2759 && TREE_CODE (gnu_prefix) == FIELD_DECL));
2760
2761 get_inner_reference (gnu_prefix, &bitsize, &bitpos, &gnu_offset,
2762 &mode, &unsignedp, &reversep, &volatilep);
2763
2764 if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
2765 {
2766 gnu_field_bitpos = bit_position (TREE_OPERAND (gnu_prefix, 1));
2767 gnu_field_offset = byte_position (TREE_OPERAND (gnu_prefix, 1));
2768
2769 for (gnu_inner = TREE_OPERAND (gnu_prefix, 0);
2770 TREE_CODE (gnu_inner) == COMPONENT_REF
2771 && DECL_INTERNAL_P (TREE_OPERAND (gnu_inner, 1));
2772 gnu_inner = TREE_OPERAND (gnu_inner, 0))
2773 {
2774 gnu_field_bitpos
2775 = size_binop (PLUS_EXPR, gnu_field_bitpos,
2776 bit_position (TREE_OPERAND (gnu_inner, 1)));
2777 gnu_field_offset
2778 = size_binop (PLUS_EXPR, gnu_field_offset,
2779 byte_position (TREE_OPERAND (gnu_inner, 1)));
2780 }
2781 }
2782 else if (TREE_CODE (gnu_prefix) == FIELD_DECL)
2783 {
2784 gnu_field_bitpos = bit_position (gnu_prefix);
2785 gnu_field_offset = byte_position (gnu_prefix);
2786 }
2787 else
2788 {
2789 gnu_field_bitpos = bitsize_zero_node;
2790 gnu_field_offset = size_zero_node;
2791 }
2792
2793 switch (attribute)
2794 {
2795 case Attr_Position:
2796 gnu_result = gnu_field_offset;
2797 break;
2798
2799 case Attr_First_Bit:
2800 case Attr_Bit:
2801 gnu_result = size_int (num_trailing_bits (bitpos));
2802 break;
2803
2804 case Attr_Last_Bit:
2805 gnu_result = bitsize_int (num_trailing_bits (bitpos));
2806 gnu_result = size_binop (PLUS_EXPR, gnu_result,
2807 TYPE_SIZE (TREE_TYPE (gnu_prefix)));
2808 /* ??? Avoid a large unsigned result that will overflow when
2809 converted to the signed universal_integer. */
2810 if (integer_zerop (gnu_result))
2811 gnu_result = integer_minus_one_node;
2812 else
2813 gnu_result
2814 = size_binop (MINUS_EXPR, gnu_result, bitsize_one_node);
2815 break;
2816
2817 case Attr_Bit_Position:
2818 gnu_result = gnu_field_bitpos;
2819 break;
2820 }
2821
2822 /* If this has a PLACEHOLDER_EXPR, qualify it by the object we are
2823 handling. */
2824 gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
2825 break;
2826 }
2827
2828 case Attr_Min:
2829 case Attr_Max:
2830 {
2831 tree gnu_lhs = gnat_to_gnu (First (Expressions (gnat_node)));
2832 tree gnu_rhs = gnat_to_gnu (Next (First (Expressions (gnat_node))));
2833
2834 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2835
2836 /* The result of {MIN,MAX}_EXPR is unspecified if either operand is
2837 a NaN so we implement the semantics of C99 f{min,max} to make it
2838 predictable in this case: if either operand is a NaN, the other
2839 is returned; if both operands are NaN's, a NaN is returned. */
2840 if (SCALAR_FLOAT_TYPE_P (gnu_result_type)
2841 && !Machine_Overflows_On_Target)
2842 {
2843 const bool lhs_side_effects_p = TREE_SIDE_EFFECTS (gnu_lhs);
2844 const bool rhs_side_effects_p = TREE_SIDE_EFFECTS (gnu_rhs);
2845 tree t = builtin_decl_explicit (BUILT_IN_ISNAN);
2846 tree lhs_is_nan, rhs_is_nan;
2847
2848 /* If the operands have side-effects, they need to be evaluated
2849 only once in spite of the multiple references in the result. */
2850 if (lhs_side_effects_p)
2851 gnu_lhs = gnat_protect_expr (gnu_lhs);
2852 if (rhs_side_effects_p)
2853 gnu_rhs = gnat_protect_expr (gnu_rhs);
2854
2855 lhs_is_nan = fold_build2 (NE_EXPR, boolean_type_node,
2856 build_call_expr (t, 1, gnu_lhs),
2857 integer_zero_node);
2858
2859 rhs_is_nan = fold_build2 (NE_EXPR, boolean_type_node,
2860 build_call_expr (t, 1, gnu_rhs),
2861 integer_zero_node);
2862
2863 gnu_result = build_binary_op (attribute == Attr_Min
2864 ? MIN_EXPR : MAX_EXPR,
2865 gnu_result_type, gnu_lhs, gnu_rhs);
2866 gnu_result = fold_build3 (COND_EXPR, gnu_result_type,
2867 rhs_is_nan, gnu_lhs, gnu_result);
2868 gnu_result = fold_build3 (COND_EXPR, gnu_result_type,
2869 lhs_is_nan, gnu_rhs, gnu_result);
2870
2871 /* If the operands have side-effects, they need to be evaluated
2872 before doing the tests above since the place they otherwise
2873 would end up being evaluated at run time could be wrong. */
2874 if (lhs_side_effects_p)
2875 gnu_result
2876 = build2 (COMPOUND_EXPR, gnu_result_type, gnu_lhs, gnu_result);
2877
2878 if (rhs_side_effects_p)
2879 gnu_result
2880 = build2 (COMPOUND_EXPR, gnu_result_type, gnu_rhs, gnu_result);
2881 }
2882 else
2883 gnu_result = build_binary_op (attribute == Attr_Min
2884 ? MIN_EXPR : MAX_EXPR,
2885 gnu_result_type, gnu_lhs, gnu_rhs);
2886 }
2887 break;
2888
2889 case Attr_Passed_By_Reference:
2890 gnu_result = size_int (default_pass_by_ref (gnu_type)
2891 || must_pass_by_ref (gnu_type));
2892 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2893 break;
2894
2895 case Attr_Component_Size:
2896 if (TREE_CODE (gnu_prefix) == COMPONENT_REF
2897 && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))))
2898 gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
2899
2900 gnu_prefix = maybe_implicit_deref (gnu_prefix);
2901 gnu_type = TREE_TYPE (gnu_prefix);
2902
2903 if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
2904 gnu_type = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_type))));
2905
2906 while (TREE_CODE (TREE_TYPE (gnu_type)) == ARRAY_TYPE
2907 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type)))
2908 gnu_type = TREE_TYPE (gnu_type);
2909
2910 gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);
2911
2912 /* Note this size cannot be self-referential. */
2913 gnu_result = TYPE_SIZE (TREE_TYPE (gnu_type));
2914 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2915 prefix_unused = true;
2916 break;
2917
2918 case Attr_Descriptor_Size:
2919 gnu_type = TREE_TYPE (gnu_prefix);
2920 gcc_assert (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE);
2921
2922 /* Return the padded size of the template in the object record type. */
2923 gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
2924 gnu_result = bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type)));
2925 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2926 prefix_unused = true;
2927 break;
2928
2929 case Attr_Null_Parameter:
2930 /* This is just a zero cast to the pointer type for our prefix and
2931 dereferenced. */
2932 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2933 gnu_result
2934 = build_unary_op (INDIRECT_REF, NULL_TREE,
2935 convert (build_pointer_type (gnu_result_type),
2936 integer_zero_node));
2937 TREE_PRIVATE (gnu_result) = 1;
2938 break;
2939
2940 case Attr_Mechanism_Code:
2941 {
2942 Entity_Id gnat_obj = Entity (gnat_prefix);
2943 int code;
2944
2945 prefix_unused = true;
2946 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2947 if (Present (Expressions (gnat_node)))
2948 {
2949 int i = UI_To_Int (Intval (First (Expressions (gnat_node))));
2950
2951 for (gnat_obj = First_Formal (gnat_obj); i > 1;
2952 i--, gnat_obj = Next_Formal (gnat_obj))
2953 ;
2954 }
2955
2956 code = Mechanism (gnat_obj);
2957 if (code == Default)
2958 code = ((present_gnu_tree (gnat_obj)
2959 && (DECL_BY_REF_P (get_gnu_tree (gnat_obj))
2960 || ((TREE_CODE (get_gnu_tree (gnat_obj))
2961 == PARM_DECL)
2962 && (DECL_BY_COMPONENT_PTR_P
2963 (get_gnu_tree (gnat_obj))))))
2964 ? By_Reference : By_Copy);
2965 gnu_result = convert (gnu_result_type, size_int (- code));
2966 }
2967 break;
2968
2969 case Attr_Model:
2970 /* We treat Model as identical to Machine. This is true for at least
2971 IEEE and some other nice floating-point systems. */
2972
2973 /* ... fall through ... */
2974
2975 case Attr_Machine:
2976 /* The trick is to force the compiler to store the result in memory so
2977 that we do not have extra precision used. But do this only when this
2978 is necessary, i.e. if FP_ARITH_MAY_WIDEN is true and the precision of
2979 the type is lower than that of the longest floating-point type. */
2980 prefix_unused = true;
2981 gnu_expr = gnat_to_gnu (First (Expressions (gnat_node)));
2982 gnu_result_type = get_unpadded_type (Etype (gnat_node));
2983 gnu_result = convert (gnu_result_type, gnu_expr);
2984
2985 if (TREE_CODE (gnu_result) != REAL_CST
2986 && fp_arith_may_widen
2987 && TYPE_PRECISION (gnu_result_type)
2988 < TYPE_PRECISION (longest_float_type_node))
2989 {
2990 tree rec_type = make_node (RECORD_TYPE);
2991 tree field
2992 = create_field_decl (get_identifier ("OBJ"), gnu_result_type,
2993 rec_type, NULL_TREE, NULL_TREE, 0, 0);
2994 tree rec_val, asm_expr;
2995
2996 finish_record_type (rec_type, field, 0, false);
2997
2998 rec_val = build_constructor_single (rec_type, field, gnu_result);
2999 rec_val = build1 (SAVE_EXPR, rec_type, rec_val);
3000
3001 asm_expr
3002 = build5 (ASM_EXPR, void_type_node,
3003 build_string (0, ""),
3004 tree_cons (build_tree_list (NULL_TREE,
3005 build_string (2, "=m")),
3006 rec_val, NULL_TREE),
3007 tree_cons (build_tree_list (NULL_TREE,
3008 build_string (1, "m")),
3009 rec_val, NULL_TREE),
3010 NULL_TREE, NULL_TREE);
3011 ASM_VOLATILE_P (asm_expr) = 1;
3012
3013 gnu_result
3014 = build_compound_expr (gnu_result_type, asm_expr,
3015 build_component_ref (rec_val, field,
3016 false));
3017 }
3018 break;
3019
3020 case Attr_Deref:
3021 prefix_unused = true;
3022 gnu_expr = gnat_to_gnu (First (Expressions (gnat_node)));
3023 gnu_result_type = get_unpadded_type (Etype (gnat_node));
3024 /* This can be a random address so build an alias-all pointer type. */
3025 gnu_expr
3026 = convert (build_pointer_type_for_mode (gnu_result_type, ptr_mode,
3027 true),
3028 gnu_expr);
3029 gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_expr);
3030 break;
3031
3032 default:
3033 /* This abort means that we have an unimplemented attribute. */
3034 gcc_unreachable ();
3035 }
3036
3037 /* If this is an attribute where the prefix was unused, force a use of it if
3038 it has a side-effect. But don't do it if the prefix is just an entity
3039 name. However, if an access check is needed, we must do it. See second
3040 example in AARM 11.6(5.e). */
3041 if (prefix_unused
3042 && TREE_SIDE_EFFECTS (gnu_prefix)
3043 && !Is_Entity_Name (gnat_prefix))
3044 gnu_result
3045 = build_compound_expr (TREE_TYPE (gnu_result), gnu_prefix, gnu_result);
3046
3047 *gnu_result_type_p = gnu_result_type;
3048 return gnu_result;
3049 }
3050
3051 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Case_Statement,
3052 to a GCC tree, which is returned. */
3053
3054 static tree
Case_Statement_to_gnu(Node_Id gnat_node)3055 Case_Statement_to_gnu (Node_Id gnat_node)
3056 {
3057 tree gnu_result, gnu_expr, gnu_type, gnu_label;
3058 Node_Id gnat_when;
3059 location_t end_locus;
3060 bool may_fallthru = false;
3061
3062 gnu_expr = gnat_to_gnu (Expression (gnat_node));
3063 gnu_expr = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr);
3064 gnu_expr = maybe_character_value (gnu_expr);
3065 gnu_type = TREE_TYPE (gnu_expr);
3066
3067 /* We build a SWITCH_EXPR that contains the code with interspersed
3068 CASE_LABEL_EXPRs for each label. */
3069 if (!Sloc_to_locus (End_Location (gnat_node), &end_locus))
3070 end_locus = input_location;
3071 gnu_label = create_artificial_label (end_locus);
3072 start_stmt_group ();
3073
3074 for (gnat_when = First_Non_Pragma (Alternatives (gnat_node));
3075 Present (gnat_when);
3076 gnat_when = Next_Non_Pragma (gnat_when))
3077 {
3078 bool choices_added_p = false;
3079 Node_Id gnat_choice;
3080
3081 /* First compile all the different case choices for the current WHEN
3082 alternative. */
3083 for (gnat_choice = First (Discrete_Choices (gnat_when));
3084 Present (gnat_choice);
3085 gnat_choice = Next (gnat_choice))
3086 {
3087 tree gnu_low = NULL_TREE, gnu_high = NULL_TREE;
3088 tree label = create_artificial_label (input_location);
3089
3090 switch (Nkind (gnat_choice))
3091 {
3092 case N_Range:
3093 gnu_low = gnat_to_gnu (Low_Bound (gnat_choice));
3094 gnu_high = gnat_to_gnu (High_Bound (gnat_choice));
3095 break;
3096
3097 case N_Subtype_Indication:
3098 gnu_low = gnat_to_gnu (Low_Bound (Range_Expression
3099 (Constraint (gnat_choice))));
3100 gnu_high = gnat_to_gnu (High_Bound (Range_Expression
3101 (Constraint (gnat_choice))));
3102 break;
3103
3104 case N_Identifier:
3105 case N_Expanded_Name:
3106 /* This represents either a subtype range or a static value of
3107 some kind; Ekind says which. */
3108 if (Is_Type (Entity (gnat_choice)))
3109 {
3110 tree gnu_type = get_unpadded_type (Entity (gnat_choice));
3111
3112 gnu_low = TYPE_MIN_VALUE (gnu_type);
3113 gnu_high = TYPE_MAX_VALUE (gnu_type);
3114 break;
3115 }
3116
3117 /* ... fall through ... */
3118
3119 case N_Character_Literal:
3120 case N_Integer_Literal:
3121 gnu_low = gnat_to_gnu (gnat_choice);
3122 break;
3123
3124 case N_Others_Choice:
3125 break;
3126
3127 default:
3128 gcc_unreachable ();
3129 }
3130
3131 /* Everything should be folded into constants at this point. */
3132 gcc_assert (!gnu_low || TREE_CODE (gnu_low) == INTEGER_CST);
3133 gcc_assert (!gnu_high || TREE_CODE (gnu_high) == INTEGER_CST);
3134
3135 if (gnu_low && TREE_TYPE (gnu_low) != gnu_type)
3136 gnu_low = convert (gnu_type, gnu_low);
3137 if (gnu_high && TREE_TYPE (gnu_high) != gnu_type)
3138 gnu_high = convert (gnu_type, gnu_high);
3139
3140 add_stmt_with_node (build_case_label (gnu_low, gnu_high, label),
3141 gnat_choice);
3142 choices_added_p = true;
3143 }
3144
3145 /* This construct doesn't define a scope so we shouldn't push a binding
3146 level around the statement list. Except that we have always done so
3147 historically and this makes it possible to reduce stack usage. As a
3148 compromise, we keep doing it for case statements, for which this has
3149 never been problematic, but not for case expressions in Ada 2012. */
3150 if (choices_added_p)
3151 {
3152 const bool is_case_expression
3153 = (Nkind (Parent (gnat_node)) == N_Expression_With_Actions);
3154 tree group
3155 = build_stmt_group (Statements (gnat_when), !is_case_expression);
3156 bool group_may_fallthru = block_may_fallthru (group);
3157 add_stmt (group);
3158 if (group_may_fallthru)
3159 {
3160 tree stmt = build1 (GOTO_EXPR, void_type_node, gnu_label);
3161 SET_EXPR_LOCATION (stmt, end_locus);
3162 add_stmt (stmt);
3163 may_fallthru = true;
3164 }
3165 }
3166 }
3167
3168 /* Now emit a definition of the label the cases branch to, if any. */
3169 if (may_fallthru)
3170 add_stmt (build1 (LABEL_EXPR, void_type_node, gnu_label));
3171 gnu_result = build2 (SWITCH_EXPR, gnu_type, gnu_expr, end_stmt_group ());
3172
3173 return gnu_result;
3174 }
3175
3176 /* Return true if we are in the body of a loop. */
3177
3178 static inline bool
inside_loop_p(void)3179 inside_loop_p (void)
3180 {
3181 return !vec_safe_is_empty (gnu_loop_stack);
3182 }
3183
3184 /* Find out whether EXPR is a simple additive expression based on the iteration
3185 variable of some enclosing loop in the current function. If so, return the
3186 loop and set *DISP to the displacement and *NEG_P to true if this is for a
3187 subtraction; otherwise, return NULL. */
3188
3189 static struct loop_info_d *
find_loop_for(tree expr,tree * disp,bool * neg_p)3190 find_loop_for (tree expr, tree *disp, bool *neg_p)
3191 {
3192 tree var, add, cst;
3193 bool minus_p;
3194 struct loop_info_d *iter = NULL;
3195 unsigned int i;
3196
3197 if (is_simple_additive_expression (expr, &add, &cst, &minus_p))
3198 {
3199 var = add;
3200 if (disp)
3201 *disp = cst;
3202 if (neg_p)
3203 *neg_p = minus_p;
3204 }
3205 else
3206 {
3207 var = expr;
3208 if (disp)
3209 *disp = NULL_TREE;
3210 if (neg_p)
3211 *neg_p = false;
3212 }
3213
3214 var = remove_conversions (var, false);
3215
3216 if (TREE_CODE (var) != VAR_DECL)
3217 return NULL;
3218
3219 if (decl_function_context (var) != current_function_decl)
3220 return NULL;
3221
3222 gcc_assert (vec_safe_length (gnu_loop_stack) > 0);
3223
3224 FOR_EACH_VEC_ELT_REVERSE (*gnu_loop_stack, i, iter)
3225 if (var == iter->loop_var)
3226 break;
3227
3228 return iter;
3229 }
3230
3231 /* Return true if VAL (of type TYPE) can equal the minimum value if MAX is
3232 false, or the maximum value if MAX is true, of TYPE. */
3233
3234 static bool
can_equal_min_or_max_val_p(tree val,tree type,bool max)3235 can_equal_min_or_max_val_p (tree val, tree type, bool max)
3236 {
3237 tree min_or_max_val = (max ? TYPE_MAX_VALUE (type) : TYPE_MIN_VALUE (type));
3238
3239 if (TREE_CODE (min_or_max_val) != INTEGER_CST)
3240 return true;
3241
3242 if (TREE_CODE (val) == NOP_EXPR)
3243 val = (max
3244 ? TYPE_MAX_VALUE (TREE_TYPE (TREE_OPERAND (val, 0)))
3245 : TYPE_MIN_VALUE (TREE_TYPE (TREE_OPERAND (val, 0))));
3246
3247 if (TREE_CODE (val) != INTEGER_CST)
3248 return true;
3249
3250 if (max)
3251 return tree_int_cst_lt (val, min_or_max_val) == 0;
3252 else
3253 return tree_int_cst_lt (min_or_max_val, val) == 0;
3254 }
3255
3256 /* Return true if VAL (of type TYPE) can equal the minimum value of TYPE.
3257 If REVERSE is true, minimum value is taken as maximum value. */
3258
3259 static inline bool
can_equal_min_val_p(tree val,tree type,bool reverse)3260 can_equal_min_val_p (tree val, tree type, bool reverse)
3261 {
3262 return can_equal_min_or_max_val_p (val, type, reverse);
3263 }
3264
3265 /* Return true if VAL (of type TYPE) can equal the maximum value of TYPE.
3266 If REVERSE is true, maximum value is taken as minimum value. */
3267
3268 static inline bool
can_equal_max_val_p(tree val,tree type,bool reverse)3269 can_equal_max_val_p (tree val, tree type, bool reverse)
3270 {
3271 return can_equal_min_or_max_val_p (val, type, !reverse);
3272 }
3273
3274 /* Return true if VAL1 can be lower than VAL2. */
3275
3276 static bool
can_be_lower_p(tree val1,tree val2)3277 can_be_lower_p (tree val1, tree val2)
3278 {
3279 if (TREE_CODE (val1) == NOP_EXPR)
3280 {
3281 tree type = TREE_TYPE (TREE_OPERAND (val1, 0));
3282 if (can_be_lower_p (TYPE_MAX_VALUE (type), TYPE_MIN_VALUE (type)))
3283 return true;
3284
3285 val1 = TYPE_MIN_VALUE (type);
3286 }
3287
3288 if (TREE_CODE (val1) != INTEGER_CST)
3289 return true;
3290
3291 if (TREE_CODE (val2) == NOP_EXPR)
3292 {
3293 tree type = TREE_TYPE (TREE_OPERAND (val2, 0));
3294 if (can_be_lower_p (TYPE_MAX_VALUE (type), TYPE_MIN_VALUE (type)))
3295 return true;
3296
3297 val2 = TYPE_MAX_VALUE (type);
3298 }
3299
3300 if (TREE_CODE (val2) != INTEGER_CST)
3301 return true;
3302
3303 return tree_int_cst_lt (val1, val2);
3304 }
3305
3306 /* Replace EXPR1 and EXPR2 by invariant expressions if possible. Return
3307 true if both expressions have been replaced and false otherwise. */
3308
3309 static bool
make_invariant(tree * expr1,tree * expr2)3310 make_invariant (tree *expr1, tree *expr2)
3311 {
3312 tree inv_expr1 = gnat_invariant_expr (*expr1);
3313 tree inv_expr2 = gnat_invariant_expr (*expr2);
3314
3315 if (inv_expr1)
3316 *expr1 = inv_expr1;
3317
3318 if (inv_expr2)
3319 *expr2 = inv_expr2;
3320
3321 return inv_expr1 && inv_expr2;
3322 }
3323
3324 /* Helper function for walk_tree, used by independent_iterations_p below. */
3325
3326 static tree
scan_rhs_r(tree * tp,int * walk_subtrees,void * data)3327 scan_rhs_r (tree *tp, int *walk_subtrees, void *data)
3328 {
3329 bitmap *params = (bitmap *)data;
3330 tree t = *tp;
3331
3332 /* No need to walk into types or decls. */
3333 if (IS_TYPE_OR_DECL_P (t))
3334 *walk_subtrees = 0;
3335
3336 if (TREE_CODE (t) == PARM_DECL && bitmap_bit_p (*params, DECL_UID (t)))
3337 return t;
3338
3339 return NULL_TREE;
3340 }
3341
3342 /* Return true if STMT_LIST generates independent iterations in a loop. */
3343
3344 static bool
independent_iterations_p(tree stmt_list)3345 independent_iterations_p (tree stmt_list)
3346 {
3347 tree_stmt_iterator tsi;
3348 bitmap params = BITMAP_GGC_ALLOC();
3349 auto_vec<tree, 16> rhs;
3350 tree iter;
3351 int i;
3352
3353 if (TREE_CODE (stmt_list) == BIND_EXPR)
3354 stmt_list = BIND_EXPR_BODY (stmt_list);
3355
3356 /* Scan the list and return false on anything that is not either a check
3357 or an assignment to a parameter with restricted aliasing. */
3358 for (tsi = tsi_start (stmt_list); !tsi_end_p (tsi); tsi_next (&tsi))
3359 {
3360 tree stmt = tsi_stmt (tsi);
3361
3362 switch (TREE_CODE (stmt))
3363 {
3364 case COND_EXPR:
3365 {
3366 if (COND_EXPR_ELSE (stmt))
3367 return false;
3368 if (TREE_CODE (COND_EXPR_THEN (stmt)) != CALL_EXPR)
3369 return false;
3370 tree func = get_callee_fndecl (COND_EXPR_THEN (stmt));
3371 if (!(func && TREE_THIS_VOLATILE (func)))
3372 return false;
3373 break;
3374 }
3375
3376 case MODIFY_EXPR:
3377 {
3378 tree lhs = TREE_OPERAND (stmt, 0);
3379 while (handled_component_p (lhs))
3380 lhs = TREE_OPERAND (lhs, 0);
3381 if (TREE_CODE (lhs) != INDIRECT_REF)
3382 return false;
3383 lhs = TREE_OPERAND (lhs, 0);
3384 if (!(TREE_CODE (lhs) == PARM_DECL
3385 && DECL_RESTRICTED_ALIASING_P (lhs)))
3386 return false;
3387 bitmap_set_bit (params, DECL_UID (lhs));
3388 rhs.safe_push (TREE_OPERAND (stmt, 1));
3389 break;
3390 }
3391
3392 default:
3393 return false;
3394 }
3395 }
3396
3397 /* At this point we know that the list contains only statements that will
3398 modify parameters with restricted aliasing. Check that the statements
3399 don't at the time read from these parameters. */
3400 FOR_EACH_VEC_ELT (rhs, i, iter)
3401 if (walk_tree_without_duplicates (&iter, scan_rhs_r, ¶ms))
3402 return false;
3403
3404 return true;
3405 }
3406
3407 /* Helper for Loop_Statement_to_gnu to translate the body of a loop,
3408 designated by GNAT_LOOP, to which an Acc_Loop pragma applies. The pragma
3409 arguments might instruct us to collapse a nest of loops, where computation
3410 statements are expected only within the innermost loop, as in:
3411
3412 for I in 1 .. 5 loop
3413 pragma Acc_Parallel;
3414 pragma Acc_Loop(Collapse => 3);
3415 for J in 1 .. 8 loop
3416 for K in 1 .. 4 loop
3417 X (I, J, K) := Y (I, J, K) + 2;
3418 end loop;
3419 end loop;
3420 end loop;
3421
3422 We expect the top of gnu_loop_stack to hold a pointer to the loop info
3423 setup for the translation of GNAT_LOOP, which holds a pointer to the
3424 initial gnu loop stmt node. We return the new gnu loop statement to
3425 use. */
3426
3427 static tree
Acc_Loop_to_gnu(Node_Id gnat_loop)3428 Acc_Loop_to_gnu (Node_Id gnat_loop)
3429 {
3430 tree acc_loop = make_node (OACC_LOOP);
3431 tree acc_bind_expr = NULL_TREE;
3432 Node_Id cur_loop = gnat_loop;
3433 int collapse_count = 1;
3434 tree initv;
3435 tree condv;
3436 tree incrv;
3437
3438 /* Parse the pragmas, adding clauses to the current gnu_loop_stack through
3439 side effects. */
3440 for (Node_Id tmp = First (Statements (gnat_loop));
3441 Present (tmp) && Nkind (tmp) == N_Pragma;
3442 tmp = Next (tmp))
3443 Pragma_to_gnu(tmp);
3444
3445 /* Find the number of loops that should be collapsed. */
3446 for (tree tmp = gnu_loop_stack->last ()->omp_loop_clauses; tmp ;
3447 tmp = OMP_CLAUSE_CHAIN (tmp))
3448 if (OMP_CLAUSE_CODE (tmp) == OMP_CLAUSE_COLLAPSE)
3449 collapse_count = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (tmp));
3450 else if (OMP_CLAUSE_CODE (tmp) == OMP_CLAUSE_TILE)
3451 collapse_count = list_length (OMP_CLAUSE_TILE_LIST (tmp));
3452
3453 initv = make_tree_vec (collapse_count);
3454 condv = make_tree_vec (collapse_count);
3455 incrv = make_tree_vec (collapse_count);
3456
3457 start_stmt_group ();
3458 gnat_pushlevel ();
3459
3460 /* For each nested loop that should be collapsed ... */
3461 for (int count = 0; count < collapse_count; ++count)
3462 {
3463 Node_Id lps =
3464 Loop_Parameter_Specification (Iteration_Scheme (cur_loop));
3465 tree low =
3466 Acc_gnat_to_gnu (Low_Bound (Discrete_Subtype_Definition (lps)));
3467 tree high =
3468 Acc_gnat_to_gnu (High_Bound (Discrete_Subtype_Definition (lps)));
3469 tree variable =
3470 gnat_to_gnu_entity (Defining_Identifier (lps), NULL_TREE, true);
3471
3472 /* Build the initial value of the variable of the invariant. */
3473 TREE_VEC_ELT (initv, count) = build2 (MODIFY_EXPR,
3474 TREE_TYPE (variable),
3475 variable,
3476 low);
3477 add_stmt (TREE_VEC_ELT (initv, count));
3478
3479 /* Build the invariant of the loop. */
3480 TREE_VEC_ELT (condv, count) = build2 (LE_EXPR,
3481 boolean_type_node,
3482 variable,
3483 high);
3484
3485 /* Build the incrementation expression of the loop. */
3486 TREE_VEC_ELT (incrv, count) =
3487 build2 (MODIFY_EXPR,
3488 TREE_TYPE (variable),
3489 variable,
3490 build2 (PLUS_EXPR,
3491 TREE_TYPE (variable),
3492 variable,
3493 build_int_cst (TREE_TYPE (variable), 1)));
3494
3495 /* Don't process the innermost loop because its statements belong to
3496 another statement group. */
3497 if (count < collapse_count - 1)
3498 /* Process the current loop's body. */
3499 for (Node_Id stmt = First (Statements (cur_loop));
3500 Present (stmt); stmt = Next (stmt))
3501 {
3502 /* If we are processsing the outermost loop, it is ok for it to
3503 contain pragmas. */
3504 if (Nkind (stmt) == N_Pragma && count == 0)
3505 ;
3506 /* The frontend might have inserted a N_Object_Declaration in the
3507 loop's body to declare the iteration variable of the next loop.
3508 It will need to be hoisted before the collapsed loops. */
3509 else if (Nkind (stmt) == N_Object_Declaration)
3510 Acc_gnat_to_gnu (stmt);
3511 else if (Nkind (stmt) == N_Loop_Statement)
3512 cur_loop = stmt;
3513 /* Every other kind of statement is prohibited in collapsed
3514 loops. */
3515 else if (count < collapse_count - 1)
3516 gcc_unreachable();
3517 }
3518 }
3519 gnat_poplevel ();
3520 acc_bind_expr = end_stmt_group ();
3521
3522 /* Parse the innermost loop. */
3523 start_stmt_group();
3524 for (Node_Id stmt = First (Statements (cur_loop));
3525 Present (stmt);
3526 stmt = Next (stmt))
3527 {
3528 /* When the innermost loop is the only loop, do not parse the pragmas
3529 again. */
3530 if (Nkind (stmt) == N_Pragma && collapse_count == 1)
3531 continue;
3532 add_stmt (Acc_gnat_to_gnu (stmt));
3533 }
3534
3535 TREE_TYPE (acc_loop) = void_type_node;
3536 OMP_FOR_INIT (acc_loop) = initv;
3537 OMP_FOR_COND (acc_loop) = condv;
3538 OMP_FOR_INCR (acc_loop) = incrv;
3539 OMP_FOR_BODY (acc_loop) = end_stmt_group ();
3540 OMP_FOR_PRE_BODY (acc_loop) = NULL;
3541 OMP_FOR_ORIG_DECLS (acc_loop) = NULL;
3542 OMP_FOR_CLAUSES (acc_loop) = gnu_loop_stack->last ()->omp_loop_clauses;
3543
3544 BIND_EXPR_BODY (acc_bind_expr) = acc_loop;
3545
3546 return acc_bind_expr;
3547 }
3548
3549 /* Helper for Loop_Statement_to_gnu, to translate the body of a loop not
3550 subject to any sort of parallelization directive or restriction, designated
3551 by GNAT_NODE.
3552
3553 We expect the top of gnu_loop_stack to hold a pointer to the loop info
3554 setup for the translation, which holds a pointer to the initial gnu loop
3555 stmt node. We return the new gnu loop statement to use.
3556
3557 We might also set *GNU_COND_EXPR_P to request a variant of the translation
3558 scheme in Loop_Statement_to_gnu. */
3559
3560 static tree
Regular_Loop_to_gnu(Node_Id gnat_node,tree * gnu_cond_expr_p)3561 Regular_Loop_to_gnu (Node_Id gnat_node, tree *gnu_cond_expr_p)
3562 {
3563 const Node_Id gnat_iter_scheme = Iteration_Scheme (gnat_node);
3564 struct loop_info_d *const gnu_loop_info = gnu_loop_stack->last ();
3565 tree gnu_loop_stmt = gnu_loop_info->stmt;
3566 tree gnu_loop_label = LOOP_STMT_LABEL (gnu_loop_stmt);
3567 tree gnu_cond_expr = *gnu_cond_expr_p;
3568 tree gnu_low = NULL_TREE, gnu_high = NULL_TREE;
3569
3570 /* Set the condition under which the loop must keep going. If we have an
3571 explicit condition, use it to set the location information throughout
3572 the translation of the loop statement to avoid having multiple SLOCs.
3573
3574 For the case "LOOP .... END LOOP;" the condition is always true. */
3575 if (No (gnat_iter_scheme))
3576 ;
3577
3578 /* For the case "WHILE condition LOOP ..... END LOOP;" it's immediate. */
3579 else if (Present (Condition (gnat_iter_scheme)))
3580 {
3581 LOOP_STMT_COND (gnu_loop_stmt)
3582 = gnat_to_gnu (Condition (gnat_iter_scheme));
3583
3584 set_expr_location_from_node (gnu_loop_stmt, gnat_iter_scheme);
3585 }
3586
3587 /* Otherwise we have an iteration scheme and the condition is given by the
3588 bounds of the subtype of the iteration variable. */
3589 else
3590 {
3591 Node_Id gnat_loop_spec = Loop_Parameter_Specification (gnat_iter_scheme);
3592 Entity_Id gnat_loop_var = Defining_Entity (gnat_loop_spec);
3593 Entity_Id gnat_type = Etype (gnat_loop_var);
3594 tree gnu_type = get_unpadded_type (gnat_type);
3595 tree gnu_base_type = maybe_character_type (get_base_type (gnu_type));
3596 tree gnu_one_node = build_int_cst (gnu_base_type, 1);
3597 tree gnu_loop_var, gnu_loop_iv, gnu_first, gnu_last, gnu_stmt;
3598 enum tree_code update_code, test_code, shift_code;
3599 bool reverse = Reverse_Present (gnat_loop_spec), use_iv = false;
3600
3601 gnu_low = convert (gnu_base_type, TYPE_MIN_VALUE (gnu_type));
3602 gnu_high = convert (gnu_base_type, TYPE_MAX_VALUE (gnu_type));
3603
3604 /* We must disable modulo reduction for the iteration variable, if any,
3605 in order for the loop comparison to be effective. */
3606 if (reverse)
3607 {
3608 gnu_first = gnu_high;
3609 gnu_last = gnu_low;
3610 update_code = MINUS_NOMOD_EXPR;
3611 test_code = GE_EXPR;
3612 shift_code = PLUS_NOMOD_EXPR;
3613 }
3614 else
3615 {
3616 gnu_first = gnu_low;
3617 gnu_last = gnu_high;
3618 update_code = PLUS_NOMOD_EXPR;
3619 test_code = LE_EXPR;
3620 shift_code = MINUS_NOMOD_EXPR;
3621 }
3622
3623 /* We use two different strategies to translate the loop, depending on
3624 whether optimization is enabled.
3625
3626 If it is, we generate the canonical loop form expected by the loop
3627 optimizer and the loop vectorizer, which is the do-while form:
3628
3629 ENTRY_COND
3630 loop:
3631 TOP_UPDATE
3632 BODY
3633 BOTTOM_COND
3634 GOTO loop
3635
3636 This avoids an implicit dependency on loop header copying and makes
3637 it possible to turn BOTTOM_COND into an inequality test.
3638
3639 If optimization is disabled, loop header copying doesn't come into
3640 play and we try to generate the loop form with the fewer conditional
3641 branches. First, the default form, which is:
3642
3643 loop:
3644 TOP_COND
3645 BODY
3646 BOTTOM_UPDATE
3647 GOTO loop
3648
3649 It should catch most loops with constant ending point. Then, if we
3650 cannot, we try to generate the shifted form:
3651
3652 loop:
3653 TOP_COND
3654 TOP_UPDATE
3655 BODY
3656 GOTO loop
3657
3658 which should catch loops with constant starting point. Otherwise, if
3659 we cannot, we generate the fallback form:
3660
3661 ENTRY_COND
3662 loop:
3663 BODY
3664 BOTTOM_COND
3665 BOTTOM_UPDATE
3666 GOTO loop
3667
3668 which works in all cases. */
3669
3670 if (optimize && !optimize_debug)
3671 {
3672 /* We can use the do-while form directly if GNU_FIRST-1 doesn't
3673 overflow. */
3674 if (!can_equal_min_val_p (gnu_first, gnu_base_type, reverse))
3675 ;
3676
3677 /* Otherwise, use the do-while form with the help of a special
3678 induction variable in the unsigned version of the base type
3679 or the unsigned version of the size type, whichever is the
3680 largest, in order to have wrap-around arithmetics for it. */
3681 else
3682 {
3683 if (TYPE_PRECISION (gnu_base_type)
3684 > TYPE_PRECISION (size_type_node))
3685 gnu_base_type
3686 = gnat_type_for_size (TYPE_PRECISION (gnu_base_type), 1);
3687 else
3688 gnu_base_type = size_type_node;
3689
3690 gnu_first = convert (gnu_base_type, gnu_first);
3691 gnu_last = convert (gnu_base_type, gnu_last);
3692 gnu_one_node = build_int_cst (gnu_base_type, 1);
3693 use_iv = true;
3694 }
3695
3696 gnu_first
3697 = build_binary_op (shift_code, gnu_base_type, gnu_first,
3698 gnu_one_node);
3699 LOOP_STMT_TOP_UPDATE_P (gnu_loop_stmt) = 1;
3700 LOOP_STMT_BOTTOM_COND_P (gnu_loop_stmt) = 1;
3701 }
3702 else
3703 {
3704 /* We can use the default form if GNU_LAST+1 doesn't overflow. */
3705 if (!can_equal_max_val_p (gnu_last, gnu_base_type, reverse))
3706 ;
3707
3708 /* Otherwise, we can use the shifted form if neither GNU_FIRST-1 nor
3709 GNU_LAST-1 does. */
3710 else if (!can_equal_min_val_p (gnu_first, gnu_base_type, reverse)
3711 && !can_equal_min_val_p (gnu_last, gnu_base_type, reverse))
3712 {
3713 gnu_first
3714 = build_binary_op (shift_code, gnu_base_type, gnu_first,
3715 gnu_one_node);
3716 gnu_last
3717 = build_binary_op (shift_code, gnu_base_type, gnu_last,
3718 gnu_one_node);
3719 LOOP_STMT_TOP_UPDATE_P (gnu_loop_stmt) = 1;
3720 }
3721
3722 /* Otherwise, use the fallback form. */
3723 else
3724 LOOP_STMT_BOTTOM_COND_P (gnu_loop_stmt) = 1;
3725 }
3726
3727 /* If we use the BOTTOM_COND, we can turn the test into an inequality
3728 test but we may have to add ENTRY_COND to protect the empty loop. */
3729 if (LOOP_STMT_BOTTOM_COND_P (gnu_loop_stmt))
3730 {
3731 test_code = NE_EXPR;
3732 if (can_be_lower_p (gnu_high, gnu_low))
3733 {
3734 gnu_cond_expr
3735 = build3 (COND_EXPR, void_type_node,
3736 build_binary_op (LE_EXPR, boolean_type_node,
3737 gnu_low, gnu_high),
3738 NULL_TREE, alloc_stmt_list ());
3739 set_expr_location_from_node (gnu_cond_expr, gnat_iter_scheme);
3740 }
3741 }
3742
3743 /* Open a new nesting level that will surround the loop to declare the
3744 iteration variable. */
3745 start_stmt_group ();
3746 gnat_pushlevel ();
3747
3748 /* If we use the special induction variable, create it and set it to
3749 its initial value. Morever, the regular iteration variable cannot
3750 itself be initialized, lest the initial value wrapped around. */
3751 if (use_iv)
3752 {
3753 gnu_loop_iv
3754 = create_init_temporary ("I", gnu_first, &gnu_stmt, gnat_loop_var);
3755 add_stmt (gnu_stmt);
3756 gnu_first = NULL_TREE;
3757 }
3758 else
3759 gnu_loop_iv = NULL_TREE;
3760
3761 /* Declare the iteration variable and set it to its initial value. */
3762 gnu_loop_var = gnat_to_gnu_entity (gnat_loop_var, gnu_first, true);
3763 if (DECL_BY_REF_P (gnu_loop_var))
3764 gnu_loop_var = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_loop_var);
3765 else if (use_iv)
3766 {
3767 gcc_assert (DECL_LOOP_PARM_P (gnu_loop_var));
3768 SET_DECL_INDUCTION_VAR (gnu_loop_var, gnu_loop_iv);
3769 }
3770 gnu_loop_info->loop_var = gnu_loop_var;
3771 gnu_loop_info->low_bound = gnu_low;
3772 gnu_loop_info->high_bound = gnu_high;
3773
3774 /* Do all the arithmetics in the base type. */
3775 gnu_loop_var = convert (gnu_base_type, gnu_loop_var);
3776
3777 /* Set either the top or bottom exit condition. */
3778 if (use_iv)
3779 LOOP_STMT_COND (gnu_loop_stmt)
3780 = build_binary_op (test_code, boolean_type_node, gnu_loop_iv,
3781 gnu_last);
3782 else
3783 LOOP_STMT_COND (gnu_loop_stmt)
3784 = build_binary_op (test_code, boolean_type_node, gnu_loop_var,
3785 gnu_last);
3786
3787 /* Set either the top or bottom update statement and give it the source
3788 location of the iteration for better coverage info. */
3789 if (use_iv)
3790 {
3791 gnu_stmt
3792 = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_loop_iv,
3793 build_binary_op (update_code, gnu_base_type,
3794 gnu_loop_iv, gnu_one_node));
3795 set_expr_location_from_node (gnu_stmt, gnat_iter_scheme);
3796 append_to_statement_list (gnu_stmt,
3797 &LOOP_STMT_UPDATE (gnu_loop_stmt));
3798 gnu_stmt
3799 = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_loop_var,
3800 gnu_loop_iv);
3801 set_expr_location_from_node (gnu_stmt, gnat_iter_scheme);
3802 append_to_statement_list (gnu_stmt,
3803 &LOOP_STMT_UPDATE (gnu_loop_stmt));
3804 }
3805 else
3806 {
3807 gnu_stmt
3808 = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_loop_var,
3809 build_binary_op (update_code, gnu_base_type,
3810 gnu_loop_var, gnu_one_node));
3811 set_expr_location_from_node (gnu_stmt, gnat_iter_scheme);
3812 LOOP_STMT_UPDATE (gnu_loop_stmt) = gnu_stmt;
3813 }
3814
3815 set_expr_location_from_node (gnu_loop_stmt, gnat_iter_scheme);
3816 }
3817
3818 /* If the loop was named, have the name point to this loop. In this case,
3819 the association is not a DECL node, but the end label of the loop. */
3820 if (Present (Identifier (gnat_node)))
3821 save_gnu_tree (Entity (Identifier (gnat_node)), gnu_loop_label, true);
3822
3823 /* Make the loop body into its own block, so any allocated storage will be
3824 released every iteration. This is needed for stack allocation. */
3825 LOOP_STMT_BODY (gnu_loop_stmt)
3826 = build_stmt_group (Statements (gnat_node), true);
3827 TREE_SIDE_EFFECTS (gnu_loop_stmt) = 1;
3828
3829 /* If we have an iteration scheme, then we are in a statement group. Add
3830 the LOOP_STMT to it, finish it and make it the "loop". */
3831 if (Present (gnat_iter_scheme) && No (Condition (gnat_iter_scheme)))
3832 {
3833 /* First, if we have computed invariant conditions for range (or index)
3834 checks applied to the iteration variable, find out whether they can
3835 be evaluated to false at compile time; otherwise, if there are not
3836 too many of them, combine them with the original checks. If loop
3837 unswitching is enabled, do not require the loop bounds to be also
3838 invariant, as their evaluation will still be ahead of the loop. */
3839 if (vec_safe_length (gnu_loop_info->checks) > 0
3840 && (make_invariant (&gnu_low, &gnu_high) || optimize >= 3))
3841 {
3842 struct range_check_info_d *rci;
3843 unsigned int i, n_remaining_checks = 0;
3844
3845 FOR_EACH_VEC_ELT (*gnu_loop_info->checks, i, rci)
3846 {
3847 tree low_ok, high_ok;
3848
3849 if (rci->low_bound)
3850 {
3851 tree gnu_adjusted_low = convert (rci->type, gnu_low);
3852 if (rci->disp)
3853 gnu_adjusted_low
3854 = fold_build2 (rci->neg_p ? MINUS_EXPR : PLUS_EXPR,
3855 rci->type, gnu_adjusted_low, rci->disp);
3856 low_ok
3857 = build_binary_op (GE_EXPR, boolean_type_node,
3858 gnu_adjusted_low, rci->low_bound);
3859 }
3860 else
3861 low_ok = boolean_true_node;
3862
3863 if (rci->high_bound)
3864 {
3865 tree gnu_adjusted_high = convert (rci->type, gnu_high);
3866 if (rci->disp)
3867 gnu_adjusted_high
3868 = fold_build2 (rci->neg_p ? MINUS_EXPR : PLUS_EXPR,
3869 rci->type, gnu_adjusted_high, rci->disp);
3870 high_ok
3871 = build_binary_op (LE_EXPR, boolean_type_node,
3872 gnu_adjusted_high, rci->high_bound);
3873 }
3874 else
3875 high_ok = boolean_true_node;
3876
3877 tree range_ok
3878 = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
3879 low_ok, high_ok);
3880
3881 rci->invariant_cond
3882 = build_unary_op (TRUTH_NOT_EXPR, boolean_type_node, range_ok);
3883
3884 if (rci->invariant_cond == boolean_false_node)
3885 TREE_OPERAND (rci->inserted_cond, 0) = rci->invariant_cond;
3886 else
3887 n_remaining_checks++;
3888 }
3889
3890 /* Note that loop unswitching can only be applied a small number of
3891 times to a given loop (PARAM_MAX_UNSWITCH_LEVEL default to 3). */
3892 if (IN_RANGE (n_remaining_checks, 1, 3)
3893 && optimize >= 2
3894 && !optimize_size)
3895 FOR_EACH_VEC_ELT (*gnu_loop_info->checks, i, rci)
3896 if (rci->invariant_cond != boolean_false_node)
3897 {
3898 TREE_OPERAND (rci->inserted_cond, 0) = rci->invariant_cond;
3899
3900 if (optimize >= 3)
3901 add_stmt_with_node_force (rci->inserted_cond, gnat_node);
3902 }
3903 }
3904
3905 /* Second, if loop vectorization is enabled and the iterations of the
3906 loop can easily be proved as independent, mark the loop. */
3907 if (optimize >= 3
3908 && independent_iterations_p (LOOP_STMT_BODY (gnu_loop_stmt)))
3909 LOOP_STMT_IVDEP (gnu_loop_stmt) = 1;
3910
3911 add_stmt (gnu_loop_stmt);
3912 gnat_poplevel ();
3913 gnu_loop_stmt = end_stmt_group ();
3914 }
3915
3916 *gnu_cond_expr_p = gnu_cond_expr;
3917
3918 return gnu_loop_stmt;
3919 }
3920
3921 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Loop_Statement,
3922 to a GCC tree, which is returned. */
3923
3924 static tree
Loop_Statement_to_gnu(Node_Id gnat_node)3925 Loop_Statement_to_gnu (Node_Id gnat_node)
3926 {
3927 struct loop_info_d *gnu_loop_info = ggc_cleared_alloc<loop_info_d> ();
3928
3929 tree gnu_loop_stmt = build4 (LOOP_STMT, void_type_node, NULL_TREE,
3930 NULL_TREE, NULL_TREE, NULL_TREE);
3931 tree gnu_cond_expr = NULL_TREE;
3932 tree gnu_loop_label = create_artificial_label (input_location);
3933 tree gnu_result;
3934
3935 /* Push the loop_info structure associated with the LOOP_STMT. */
3936 vec_safe_push (gnu_loop_stack, gnu_loop_info);
3937
3938 /* Set location information for statement and end label. */
3939 set_expr_location_from_node (gnu_loop_stmt, gnat_node);
3940 Sloc_to_locus (Sloc (End_Label (gnat_node)),
3941 &DECL_SOURCE_LOCATION (gnu_loop_label));
3942 LOOP_STMT_LABEL (gnu_loop_stmt) = gnu_loop_label;
3943
3944 /* Save the statement for later reuse. */
3945 gnu_loop_info->stmt = gnu_loop_stmt;
3946
3947 /* Perform the core loop body translation. */
3948 if (Is_OpenAcc_Loop (gnat_node))
3949 gnu_loop_stmt = Acc_Loop_to_gnu (gnat_node);
3950 else
3951 gnu_loop_stmt = Regular_Loop_to_gnu (gnat_node, &gnu_cond_expr);
3952
3953 /* A gnat_node that has its OpenAcc_Environment flag set needs to be
3954 offloaded. Note that the OpenAcc_Loop flag is not necessarily set. */
3955 if (Is_OpenAcc_Environment (gnat_node))
3956 {
3957 tree_code code = gnu_loop_stack->last ()->omp_code;
3958 tree tmp = make_node (code);
3959 TREE_TYPE (tmp) = void_type_node;
3960 if (code == OACC_PARALLEL || code == OACC_KERNELS)
3961 {
3962 OMP_BODY (tmp) = gnu_loop_stmt;
3963 OMP_CLAUSES (tmp) = gnu_loop_stack->last ()->omp_construct_clauses;
3964 }
3965 else if (code == OACC_DATA)
3966 {
3967 OACC_DATA_BODY (tmp) = gnu_loop_stmt;
3968 OACC_DATA_CLAUSES (tmp) =
3969 gnu_loop_stack->last ()->omp_construct_clauses;
3970 }
3971 else
3972 gcc_unreachable();
3973 set_expr_location_from_node (tmp, gnat_node);
3974 gnu_loop_stmt = tmp;
3975 }
3976
3977 /* If we have an outer COND_EXPR, that's our result and this loop is its
3978 "true" statement. Otherwise, the result is the LOOP_STMT. */
3979 if (gnu_cond_expr)
3980 {
3981 COND_EXPR_THEN (gnu_cond_expr) = gnu_loop_stmt;
3982 TREE_SIDE_EFFECTS (gnu_cond_expr) = 1;
3983 gnu_result = gnu_cond_expr;
3984 }
3985 else
3986 gnu_result = gnu_loop_stmt;
3987
3988 gnu_loop_stack->pop ();
3989
3990 return gnu_result;
3991 }
3992
3993 /* This page implements a form of Named Return Value optimization modeled
3994 on the C++ optimization of the same name. The main difference is that
3995 we disregard any semantical considerations when applying it here, the
3996 counterpart being that we don't try to apply it to semantically loaded
3997 return types, i.e. types with the TYPE_BY_REFERENCE_P flag set.
3998
3999 We consider a function body of the following GENERIC form:
4000
4001 return_type R1;
4002 [...]
4003 RETURN_EXPR [<retval> = ...]
4004 [...]
4005 RETURN_EXPR [<retval> = R1]
4006 [...]
4007 return_type Ri;
4008 [...]
4009 RETURN_EXPR [<retval> = ...]
4010 [...]
4011 RETURN_EXPR [<retval> = Ri]
4012 [...]
4013
4014 where the Ri are not addressable and we try to fulfill a simple criterion
4015 that would make it possible to replace one or several Ri variables by the
4016 single RESULT_DECL of the function.
4017
4018 The first observation is that RETURN_EXPRs that don't directly reference
4019 any of the Ri variables on the RHS of their assignment are transparent wrt
4020 the optimization. This is because the Ri variables aren't addressable so
4021 any transformation applied to them doesn't affect the RHS; moreover, the
4022 assignment writes the full <retval> object so existing values are entirely
4023 discarded.
4024
4025 This property can be extended to some forms of RETURN_EXPRs that reference
4026 the Ri variables, for example CONSTRUCTORs, but isn't true in the general
4027 case, in particular when function calls are involved.
4028
4029 Therefore the algorithm is as follows:
4030
4031 1. Collect the list of candidates for a Named Return Value (Ri variables
4032 on the RHS of assignments of RETURN_EXPRs) as well as the list of the
4033 other expressions on the RHS of such assignments.
4034
4035 2. Prune the members of the first list (candidates) that are referenced
4036 by a member of the second list (expressions).
4037
4038 3. Extract a set of candidates with non-overlapping live ranges from the
4039 first list. These are the Named Return Values.
4040
4041 4. Adjust the relevant RETURN_EXPRs and replace the occurrences of the
4042 Named Return Values in the function with the RESULT_DECL.
4043
4044 If the function returns an unconstrained type, things are a bit different
4045 because the anonymous return object is allocated on the secondary stack
4046 and RESULT_DECL is only a pointer to it. Each return object can be of a
4047 different size and is allocated separately so we need not care about the
4048 addressability and the aforementioned overlapping issues. Therefore, we
4049 don't collect the other expressions and skip step #2 in the algorithm. */
4050
4051 struct nrv_data
4052 {
4053 bitmap nrv;
4054 tree result;
4055 Node_Id gnat_ret;
4056 hash_set<tree> *visited;
4057 };
4058
4059 /* Return true if T is a Named Return Value. */
4060
4061 static inline bool
is_nrv_p(bitmap nrv,tree t)4062 is_nrv_p (bitmap nrv, tree t)
4063 {
4064 return TREE_CODE (t) == VAR_DECL && bitmap_bit_p (nrv, DECL_UID (t));
4065 }
4066
4067 /* Helper function for walk_tree, used by finalize_nrv below. */
4068
4069 static tree
prune_nrv_r(tree * tp,int * walk_subtrees,void * data)4070 prune_nrv_r (tree *tp, int *walk_subtrees, void *data)
4071 {
4072 struct nrv_data *dp = (struct nrv_data *)data;
4073 tree t = *tp;
4074
4075 /* No need to walk into types or decls. */
4076 if (IS_TYPE_OR_DECL_P (t))
4077 *walk_subtrees = 0;
4078
4079 if (is_nrv_p (dp->nrv, t))
4080 bitmap_clear_bit (dp->nrv, DECL_UID (t));
4081
4082 return NULL_TREE;
4083 }
4084
4085 /* Prune Named Return Values in BLOCK and return true if there is still a
4086 Named Return Value in BLOCK or one of its sub-blocks. */
4087
4088 static bool
prune_nrv_in_block(bitmap nrv,tree block)4089 prune_nrv_in_block (bitmap nrv, tree block)
4090 {
4091 bool has_nrv = false;
4092 tree t;
4093
4094 /* First recurse on the sub-blocks. */
4095 for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
4096 has_nrv |= prune_nrv_in_block (nrv, t);
4097
4098 /* Then make sure to keep at most one NRV per block. */
4099 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
4100 if (is_nrv_p (nrv, t))
4101 {
4102 if (has_nrv)
4103 bitmap_clear_bit (nrv, DECL_UID (t));
4104 else
4105 has_nrv = true;
4106 }
4107
4108 return has_nrv;
4109 }
4110
4111 /* Helper function for walk_tree, used by finalize_nrv below. */
4112
4113 static tree
finalize_nrv_r(tree * tp,int * walk_subtrees,void * data)4114 finalize_nrv_r (tree *tp, int *walk_subtrees, void *data)
4115 {
4116 struct nrv_data *dp = (struct nrv_data *)data;
4117 tree t = *tp;
4118
4119 /* No need to walk into types. */
4120 if (TYPE_P (t))
4121 *walk_subtrees = 0;
4122
4123 /* Change RETURN_EXPRs of NRVs to just refer to the RESULT_DECL; this is a
4124 nop, but differs from using NULL_TREE in that it indicates that we care
4125 about the value of the RESULT_DECL. */
4126 else if (TREE_CODE (t) == RETURN_EXPR
4127 && TREE_CODE (TREE_OPERAND (t, 0)) == INIT_EXPR)
4128 {
4129 tree ret_val = TREE_OPERAND (TREE_OPERAND (t, 0), 1);
4130
4131 /* Strip useless conversions around the return value. */
4132 if (gnat_useless_type_conversion (ret_val))
4133 ret_val = TREE_OPERAND (ret_val, 0);
4134
4135 if (is_nrv_p (dp->nrv, ret_val))
4136 TREE_OPERAND (t, 0) = dp->result;
4137 }
4138
4139 /* Replace the DECL_EXPR of NRVs with an initialization of the RESULT_DECL,
4140 if needed. */
4141 else if (TREE_CODE (t) == DECL_EXPR
4142 && is_nrv_p (dp->nrv, DECL_EXPR_DECL (t)))
4143 {
4144 tree var = DECL_EXPR_DECL (t), init;
4145
4146 if (DECL_INITIAL (var))
4147 {
4148 init = build_binary_op (INIT_EXPR, NULL_TREE, dp->result,
4149 DECL_INITIAL (var));
4150 SET_EXPR_LOCATION (init, EXPR_LOCATION (t));
4151 DECL_INITIAL (var) = NULL_TREE;
4152 }
4153 else
4154 init = build_empty_stmt (EXPR_LOCATION (t));
4155 *tp = init;
4156
4157 /* Identify the NRV to the RESULT_DECL for debugging purposes. */
4158 SET_DECL_VALUE_EXPR (var, dp->result);
4159 DECL_HAS_VALUE_EXPR_P (var) = 1;
4160 /* ??? Kludge to avoid an assertion failure during inlining. */
4161 DECL_SIZE (var) = bitsize_unit_node;
4162 DECL_SIZE_UNIT (var) = size_one_node;
4163 }
4164
4165 /* And replace all uses of NRVs with the RESULT_DECL. */
4166 else if (is_nrv_p (dp->nrv, t))
4167 *tp = convert (TREE_TYPE (t), dp->result);
4168
4169 /* Avoid walking into the same tree more than once. Unfortunately, we
4170 can't just use walk_tree_without_duplicates because it would only
4171 call us for the first occurrence of NRVs in the function body. */
4172 if (dp->visited->add (*tp))
4173 *walk_subtrees = 0;
4174
4175 return NULL_TREE;
4176 }
4177
4178 /* Likewise, but used when the function returns an unconstrained type. */
4179
4180 static tree
finalize_nrv_unc_r(tree * tp,int * walk_subtrees,void * data)4181 finalize_nrv_unc_r (tree *tp, int *walk_subtrees, void *data)
4182 {
4183 struct nrv_data *dp = (struct nrv_data *)data;
4184 tree t = *tp;
4185
4186 /* No need to walk into types. */
4187 if (TYPE_P (t))
4188 *walk_subtrees = 0;
4189
4190 /* We need to see the DECL_EXPR of NRVs before any other references so we
4191 walk the body of BIND_EXPR before walking its variables. */
4192 else if (TREE_CODE (t) == BIND_EXPR)
4193 walk_tree (&BIND_EXPR_BODY (t), finalize_nrv_unc_r, data, NULL);
4194
4195 /* Change RETURN_EXPRs of NRVs to assign to the RESULT_DECL only the final
4196 return value built by the allocator instead of the whole construct. */
4197 else if (TREE_CODE (t) == RETURN_EXPR
4198 && TREE_CODE (TREE_OPERAND (t, 0)) == INIT_EXPR)
4199 {
4200 tree ret_val = TREE_OPERAND (TREE_OPERAND (t, 0), 1);
4201
4202 /* This is the construct returned by the allocator. */
4203 if (TREE_CODE (ret_val) == COMPOUND_EXPR
4204 && TREE_CODE (TREE_OPERAND (ret_val, 0)) == INIT_EXPR)
4205 {
4206 tree rhs = TREE_OPERAND (TREE_OPERAND (ret_val, 0), 1);
4207
4208 if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (ret_val)))
4209 ret_val = CONSTRUCTOR_ELT (rhs, 1)->value;
4210 else
4211 ret_val = rhs;
4212 }
4213
4214 /* Strip useless conversions around the return value. */
4215 if (gnat_useless_type_conversion (ret_val)
4216 || TREE_CODE (ret_val) == VIEW_CONVERT_EXPR)
4217 ret_val = TREE_OPERAND (ret_val, 0);
4218
4219 /* Strip unpadding around the return value. */
4220 if (TREE_CODE (ret_val) == COMPONENT_REF
4221 && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (ret_val, 0))))
4222 ret_val = TREE_OPERAND (ret_val, 0);
4223
4224 /* Assign the new return value to the RESULT_DECL. */
4225 if (is_nrv_p (dp->nrv, ret_val))
4226 TREE_OPERAND (TREE_OPERAND (t, 0), 1)
4227 = TREE_OPERAND (DECL_INITIAL (ret_val), 0);
4228 }
4229
4230 /* Adjust the DECL_EXPR of NRVs to call the allocator and save the result
4231 into a new variable. */
4232 else if (TREE_CODE (t) == DECL_EXPR
4233 && is_nrv_p (dp->nrv, DECL_EXPR_DECL (t)))
4234 {
4235 tree saved_current_function_decl = current_function_decl;
4236 tree var = DECL_EXPR_DECL (t);
4237 tree alloc, p_array, new_var, new_ret;
4238 vec<constructor_elt, va_gc> *v;
4239 vec_alloc (v, 2);
4240
4241 /* Create an artificial context to build the allocation. */
4242 current_function_decl = decl_function_context (var);
4243 start_stmt_group ();
4244 gnat_pushlevel ();
4245
4246 /* This will return a COMPOUND_EXPR with the allocation in the first
4247 arm and the final return value in the second arm. */
4248 alloc = build_allocator (TREE_TYPE (var), DECL_INITIAL (var),
4249 TREE_TYPE (dp->result),
4250 Procedure_To_Call (dp->gnat_ret),
4251 Storage_Pool (dp->gnat_ret),
4252 Empty, false);
4253
4254 /* The new variable is built as a reference to the allocated space. */
4255 new_var
4256 = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, DECL_NAME (var),
4257 build_reference_type (TREE_TYPE (var)));
4258 DECL_BY_REFERENCE (new_var) = 1;
4259
4260 if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (alloc)))
4261 {
4262 tree cst = TREE_OPERAND (alloc, 1);
4263
4264 /* The new initial value is a COMPOUND_EXPR with the allocation in
4265 the first arm and the value of P_ARRAY in the second arm. */
4266 DECL_INITIAL (new_var)
4267 = build2 (COMPOUND_EXPR, TREE_TYPE (new_var),
4268 TREE_OPERAND (alloc, 0),
4269 CONSTRUCTOR_ELT (cst, 0)->value);
4270
4271 /* Build a modified CONSTRUCTOR that references NEW_VAR. */
4272 p_array = TYPE_FIELDS (TREE_TYPE (alloc));
4273 CONSTRUCTOR_APPEND_ELT (v, p_array,
4274 fold_convert (TREE_TYPE (p_array), new_var));
4275 CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (p_array),
4276 CONSTRUCTOR_ELT (cst, 1)->value);
4277 new_ret = build_constructor (TREE_TYPE (alloc), v);
4278 }
4279 else
4280 {
4281 /* The new initial value is just the allocation. */
4282 DECL_INITIAL (new_var) = alloc;
4283 new_ret = fold_convert (TREE_TYPE (alloc), new_var);
4284 }
4285
4286 gnat_pushdecl (new_var, Empty);
4287
4288 /* Destroy the artificial context and insert the new statements. */
4289 gnat_zaplevel ();
4290 *tp = end_stmt_group ();
4291 current_function_decl = saved_current_function_decl;
4292
4293 /* Chain NEW_VAR immediately after VAR and ignore the latter. */
4294 DECL_CHAIN (new_var) = DECL_CHAIN (var);
4295 DECL_CHAIN (var) = new_var;
4296 DECL_IGNORED_P (var) = 1;
4297
4298 /* Save the new return value and the dereference of NEW_VAR. */
4299 DECL_INITIAL (var)
4300 = build2 (COMPOUND_EXPR, TREE_TYPE (var), new_ret,
4301 build1 (INDIRECT_REF, TREE_TYPE (var), new_var));
4302 /* ??? Kludge to avoid messing up during inlining. */
4303 DECL_CONTEXT (var) = NULL_TREE;
4304 }
4305
4306 /* And replace all uses of NRVs with the dereference of NEW_VAR. */
4307 else if (is_nrv_p (dp->nrv, t))
4308 *tp = TREE_OPERAND (DECL_INITIAL (t), 1);
4309
4310 /* Avoid walking into the same tree more than once. Unfortunately, we
4311 can't just use walk_tree_without_duplicates because it would only
4312 call us for the first occurrence of NRVs in the function body. */
4313 if (dp->visited->add (*tp))
4314 *walk_subtrees = 0;
4315
4316 return NULL_TREE;
4317 }
4318
4319 /* Apply FUNC to all the sub-trees of nested functions in NODE. FUNC is called
4320 with the DATA and the address of each sub-tree. If FUNC returns a non-NULL
4321 value, the traversal is stopped. */
4322
4323 static void
walk_nesting_tree(struct cgraph_node * node,walk_tree_fn func,void * data)4324 walk_nesting_tree (struct cgraph_node *node, walk_tree_fn func, void *data)
4325 {
4326 for (node = node->nested; node; node = node->next_nested)
4327 {
4328 walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl), func, data);
4329 walk_nesting_tree (node, func, data);
4330 }
4331 }
4332
4333 /* Finalize the Named Return Value optimization for FNDECL. The NRV bitmap
4334 contains the candidates for Named Return Value and OTHER is a list of
4335 the other return values. GNAT_RET is a representative return node. */
4336
4337 static void
finalize_nrv(tree fndecl,bitmap nrv,vec<tree,va_gc> * other,Node_Id gnat_ret)4338 finalize_nrv (tree fndecl, bitmap nrv, vec<tree, va_gc> *other, Node_Id gnat_ret)
4339 {
4340 struct nrv_data data;
4341 walk_tree_fn func;
4342 unsigned int i;
4343 tree iter;
4344
4345 /* We shouldn't be applying the optimization to return types that we aren't
4346 allowed to manipulate freely. */
4347 gcc_assert (!TYPE_IS_BY_REFERENCE_P (TREE_TYPE (TREE_TYPE (fndecl))));
4348
4349 /* Prune the candidates that are referenced by other return values. */
4350 data.nrv = nrv;
4351 data.result = NULL_TREE;
4352 data.gnat_ret = Empty;
4353 data.visited = NULL;
4354 FOR_EACH_VEC_SAFE_ELT (other, i, iter)
4355 walk_tree_without_duplicates (&iter, prune_nrv_r, &data);
4356 if (bitmap_empty_p (nrv))
4357 return;
4358
4359 /* Prune also the candidates that are referenced by nested functions. */
4360 walk_nesting_tree (cgraph_node::get_create (fndecl), prune_nrv_r, &data);
4361 if (bitmap_empty_p (nrv))
4362 return;
4363
4364 /* Extract a set of NRVs with non-overlapping live ranges. */
4365 if (!prune_nrv_in_block (nrv, DECL_INITIAL (fndecl)))
4366 return;
4367
4368 /* Adjust the relevant RETURN_EXPRs and replace the occurrences of NRVs. */
4369 data.nrv = nrv;
4370 data.result = DECL_RESULT (fndecl);
4371 data.gnat_ret = gnat_ret;
4372 data.visited = new hash_set<tree>;
4373 if (TYPE_RETURN_UNCONSTRAINED_P (TREE_TYPE (fndecl)))
4374 func = finalize_nrv_unc_r;
4375 else
4376 func = finalize_nrv_r;
4377 walk_tree (&DECL_SAVED_TREE (fndecl), func, &data, NULL);
4378 delete data.visited;
4379 }
4380
4381 /* Return true if RET_VAL can be used as a Named Return Value for the
4382 anonymous return object RET_OBJ. */
4383
4384 static bool
return_value_ok_for_nrv_p(tree ret_obj,tree ret_val)4385 return_value_ok_for_nrv_p (tree ret_obj, tree ret_val)
4386 {
4387 if (TREE_CODE (ret_val) != VAR_DECL)
4388 return false;
4389
4390 if (TREE_THIS_VOLATILE (ret_val))
4391 return false;
4392
4393 if (DECL_CONTEXT (ret_val) != current_function_decl)
4394 return false;
4395
4396 if (TREE_STATIC (ret_val))
4397 return false;
4398
4399 /* For the constrained case, test for addressability. */
4400 if (ret_obj && TREE_ADDRESSABLE (ret_val))
4401 return false;
4402
4403 /* For the constrained case, test for overalignment. */
4404 if (ret_obj && DECL_ALIGN (ret_val) > DECL_ALIGN (ret_obj))
4405 return false;
4406
4407 /* For the unconstrained case, test for bogus initialization. */
4408 if (!ret_obj
4409 && DECL_INITIAL (ret_val)
4410 && TREE_CODE (DECL_INITIAL (ret_val)) == NULL_EXPR)
4411 return false;
4412
4413 return true;
4414 }
4415
4416 /* Build a RETURN_EXPR. If RET_VAL is non-null, build a RETURN_EXPR around
4417 the assignment of RET_VAL to RET_OBJ. Otherwise build a bare RETURN_EXPR
4418 around RESULT_OBJ, which may be null in this case. */
4419
4420 static tree
build_return_expr(tree ret_obj,tree ret_val)4421 build_return_expr (tree ret_obj, tree ret_val)
4422 {
4423 tree result_expr;
4424
4425 if (ret_val)
4426 {
4427 /* The gimplifier explicitly enforces the following invariant:
4428
4429 RETURN_EXPR
4430 |
4431 INIT_EXPR
4432 / \
4433 / \
4434 RET_OBJ ...
4435
4436 As a consequence, type consistency dictates that we use the type
4437 of the RET_OBJ as the operation type. */
4438 tree operation_type = TREE_TYPE (ret_obj);
4439
4440 /* Convert the right operand to the operation type. Note that this is
4441 the transformation applied in the INIT_EXPR case of build_binary_op,
4442 with the assumption that the type cannot involve a placeholder. */
4443 if (operation_type != TREE_TYPE (ret_val))
4444 ret_val = convert (operation_type, ret_val);
4445
4446 /* We always can use an INIT_EXPR for the return object. */
4447 result_expr = build2 (INIT_EXPR, void_type_node, ret_obj, ret_val);
4448
4449 /* If the function returns an aggregate type, find out whether this is
4450 a candidate for Named Return Value. If so, record it. Otherwise,
4451 if this is an expression of some kind, record it elsewhere. */
4452 if (optimize
4453 && !optimize_debug
4454 && AGGREGATE_TYPE_P (operation_type)
4455 && !TYPE_IS_FAT_POINTER_P (operation_type)
4456 && TYPE_MODE (operation_type) == BLKmode
4457 && aggregate_value_p (operation_type, current_function_decl))
4458 {
4459 /* Strip useless conversions around the return value. */
4460 if (gnat_useless_type_conversion (ret_val))
4461 ret_val = TREE_OPERAND (ret_val, 0);
4462
4463 /* Now apply the test to the return value. */
4464 if (return_value_ok_for_nrv_p (ret_obj, ret_val))
4465 {
4466 if (!f_named_ret_val)
4467 f_named_ret_val = BITMAP_GGC_ALLOC ();
4468 bitmap_set_bit (f_named_ret_val, DECL_UID (ret_val));
4469 }
4470
4471 /* Note that we need not care about CONSTRUCTORs here, as they are
4472 totally transparent given the read-compose-write semantics of
4473 assignments from CONSTRUCTORs. */
4474 else if (EXPR_P (ret_val))
4475 vec_safe_push (f_other_ret_val, ret_val);
4476 }
4477 }
4478 else
4479 result_expr = ret_obj;
4480
4481 return build1 (RETURN_EXPR, void_type_node, result_expr);
4482 }
4483
4484 /* Subroutine of gnat_to_gnu to process gnat_node, an N_Subprogram_Body. We
4485 don't return anything. */
4486
4487 static void
Subprogram_Body_to_gnu(Node_Id gnat_node)4488 Subprogram_Body_to_gnu (Node_Id gnat_node)
4489 {
4490 /* Defining identifier of a parameter to the subprogram. */
4491 Entity_Id gnat_param;
4492 /* The defining identifier for the subprogram body. Note that if a
4493 specification has appeared before for this body, then the identifier
4494 occurring in that specification will also be a defining identifier and all
4495 the calls to this subprogram will point to that specification. */
4496 Entity_Id gnat_subprog_id
4497 = (Present (Corresponding_Spec (gnat_node))
4498 ? Corresponding_Spec (gnat_node) : Defining_Entity (gnat_node));
4499 /* The FUNCTION_DECL node corresponding to the subprogram spec. */
4500 tree gnu_subprog_decl;
4501 /* Its RESULT_DECL node. */
4502 tree gnu_result_decl;
4503 /* Its FUNCTION_TYPE node. */
4504 tree gnu_subprog_type;
4505 /* The TYPE_CI_CO_LIST of its FUNCTION_TYPE node, if any. */
4506 tree gnu_cico_list;
4507 /* The entry in the CI_CO_LIST that represents a function return, if any. */
4508 tree gnu_return_var_elmt = NULL_TREE;
4509 tree gnu_result;
4510 location_t locus;
4511 struct language_function *gnu_subprog_language;
4512 vec<parm_attr, va_gc> *cache;
4513
4514 /* If this is a generic object or if it has been eliminated,
4515 ignore it. */
4516 if (Ekind (gnat_subprog_id) == E_Generic_Procedure
4517 || Ekind (gnat_subprog_id) == E_Generic_Function
4518 || Is_Eliminated (gnat_subprog_id))
4519 return;
4520
4521 /* If this subprogram acts as its own spec, define it. Otherwise, just get
4522 the already-elaborated tree node. However, if this subprogram had its
4523 elaboration deferred, we will already have made a tree node for it. So
4524 treat it as not being defined in that case. Such a subprogram cannot
4525 have an address clause or a freeze node, so this test is safe, though it
4526 does disable some otherwise-useful error checking. */
4527 gnu_subprog_decl
4528 = gnat_to_gnu_entity (gnat_subprog_id, NULL_TREE,
4529 Acts_As_Spec (gnat_node)
4530 && !present_gnu_tree (gnat_subprog_id));
4531 DECL_FUNCTION_IS_DEF (gnu_subprog_decl) = true;
4532 gnu_result_decl = DECL_RESULT (gnu_subprog_decl);
4533 gnu_subprog_type = TREE_TYPE (gnu_subprog_decl);
4534 gnu_cico_list = TYPE_CI_CO_LIST (gnu_subprog_type);
4535 if (gnu_cico_list && TREE_VALUE (gnu_cico_list) == void_type_node)
4536 gnu_return_var_elmt = gnu_cico_list;
4537
4538 /* If the function returns by invisible reference, make it explicit in the
4539 function body. See gnat_to_gnu_entity, E_Subprogram_Type case. */
4540 if (TREE_ADDRESSABLE (gnu_subprog_type))
4541 {
4542 TREE_TYPE (gnu_result_decl)
4543 = build_reference_type (TREE_TYPE (gnu_result_decl));
4544 relayout_decl (gnu_result_decl);
4545 }
4546
4547 /* Set the line number in the decl to correspond to that of the body. */
4548 if (!Sloc_to_locus (Sloc (gnat_node), &locus, false, gnu_subprog_decl))
4549 locus = input_location;
4550 DECL_SOURCE_LOCATION (gnu_subprog_decl) = locus;
4551
4552 /* If the body comes from an expression function, arrange it to be inlined
4553 in almost all cases. */
4554 if (Was_Expression_Function (gnat_node))
4555 DECL_DISREGARD_INLINE_LIMITS (gnu_subprog_decl) = 1;
4556
4557 /* Try to create a bona-fide thunk and hand it over to the middle-end. */
4558 if (Is_Thunk (gnat_subprog_id)
4559 && maybe_make_gnu_thunk (gnat_subprog_id, gnu_subprog_decl))
4560 return;
4561
4562 /* Initialize the information structure for the function. */
4563 allocate_struct_function (gnu_subprog_decl, false);
4564 gnu_subprog_language = ggc_cleared_alloc<language_function> ();
4565 DECL_STRUCT_FUNCTION (gnu_subprog_decl)->language = gnu_subprog_language;
4566 DECL_STRUCT_FUNCTION (gnu_subprog_decl)->function_start_locus = locus;
4567 set_cfun (NULL);
4568
4569 begin_subprog_body (gnu_subprog_decl);
4570
4571 /* If there are copy-in/copy-out parameters, we need to ensure that they are
4572 properly copied out by the return statement. We do this by making a new
4573 block and converting any return into a goto to a label at the end of the
4574 block. */
4575 if (gnu_cico_list)
4576 {
4577 tree gnu_return_var = NULL_TREE;
4578
4579 vec_safe_push (gnu_return_label_stack,
4580 create_artificial_label (input_location));
4581
4582 start_stmt_group ();
4583 gnat_pushlevel ();
4584
4585 /* If this is a function with copy-in/copy-out parameters and which does
4586 not return by invisible reference, we also need a variable for the
4587 return value to be placed. */
4588 if (gnu_return_var_elmt && !TREE_ADDRESSABLE (gnu_subprog_type))
4589 {
4590 tree gnu_return_type
4591 = TREE_TYPE (TREE_PURPOSE (gnu_return_var_elmt));
4592
4593 gnu_return_var
4594 = create_var_decl (get_identifier ("RETVAL"), NULL_TREE,
4595 gnu_return_type, NULL_TREE,
4596 false, false, false, false, false,
4597 true, false, NULL, gnat_subprog_id);
4598 TREE_VALUE (gnu_return_var_elmt) = gnu_return_var;
4599 }
4600
4601 vec_safe_push (gnu_return_var_stack, gnu_return_var);
4602
4603 /* See whether there are parameters for which we don't have a GCC tree
4604 yet. These must be Out parameters. Make a VAR_DECL for them and
4605 put it into TYPE_CI_CO_LIST, which must contain an empty entry too.
4606 We can match up the entries because TYPE_CI_CO_LIST is in the order
4607 of the parameters. */
4608 for (gnat_param = First_Formal_With_Extras (gnat_subprog_id);
4609 Present (gnat_param);
4610 gnat_param = Next_Formal_With_Extras (gnat_param))
4611 if (!present_gnu_tree (gnat_param))
4612 {
4613 tree gnu_cico_entry = gnu_cico_list;
4614 tree gnu_decl;
4615
4616 /* Skip any entries that have been already filled in; they must
4617 correspond to In Out parameters. */
4618 while (gnu_cico_entry && TREE_VALUE (gnu_cico_entry))
4619 gnu_cico_entry = TREE_CHAIN (gnu_cico_entry);
4620
4621 /* Do any needed dereferences for by-ref objects. */
4622 gnu_decl = gnat_to_gnu_entity (gnat_param, NULL_TREE, true);
4623 gcc_assert (DECL_P (gnu_decl));
4624 if (DECL_BY_REF_P (gnu_decl))
4625 gnu_decl = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_decl);
4626
4627 /* Do any needed references for padded types. */
4628 TREE_VALUE (gnu_cico_entry)
4629 = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_entry)), gnu_decl);
4630 }
4631 }
4632 else
4633 vec_safe_push (gnu_return_label_stack, NULL_TREE);
4634
4635 /* Get a tree corresponding to the code for the subprogram. */
4636 start_stmt_group ();
4637 gnat_pushlevel ();
4638
4639 process_decls (Declarations (gnat_node), Empty, Empty, true, true);
4640
4641 /* Generate the code of the subprogram itself. A return statement will be
4642 present and any Out parameters will be handled there. */
4643 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));
4644 gnat_poplevel ();
4645 gnu_result = end_stmt_group ();
4646
4647 /* If we populated the parameter attributes cache, we need to make sure that
4648 the cached expressions are evaluated on all the possible paths leading to
4649 their uses. So we force their evaluation on entry of the function. */
4650 cache = gnu_subprog_language->parm_attr_cache;
4651 if (cache)
4652 {
4653 struct parm_attr_d *pa;
4654 int i;
4655
4656 start_stmt_group ();
4657
4658 FOR_EACH_VEC_ELT (*cache, i, pa)
4659 {
4660 if (pa->first)
4661 add_stmt_with_node_force (pa->first, gnat_node);
4662 if (pa->last)
4663 add_stmt_with_node_force (pa->last, gnat_node);
4664 if (pa->length)
4665 add_stmt_with_node_force (pa->length, gnat_node);
4666 }
4667
4668 add_stmt (gnu_result);
4669 gnu_result = end_stmt_group ();
4670
4671 gnu_subprog_language->parm_attr_cache = NULL;
4672 }
4673
4674 /* If we are dealing with a return from an Ada procedure with parameters
4675 passed by copy-in/copy-out, we need to return a record containing the
4676 final values of these parameters. If the list contains only one entry,
4677 return just that entry though.
4678
4679 For a full description of the copy-in/copy-out parameter mechanism, see
4680 the part of the gnat_to_gnu_entity routine dealing with the translation
4681 of subprograms.
4682
4683 We need to make a block that contains the definition of that label and
4684 the copying of the return value. It first contains the function, then
4685 the label and copy statement. */
4686 if (gnu_cico_list)
4687 {
4688 const Node_Id gnat_end_label
4689 = End_Label (Handled_Statement_Sequence (gnat_node));
4690
4691 gnu_return_var_stack->pop ();
4692
4693 add_stmt (gnu_result);
4694 add_stmt (build1 (LABEL_EXPR, void_type_node,
4695 gnu_return_label_stack->last ()));
4696
4697 /* If this is a function which returns by invisible reference, the
4698 return value has already been dealt with at the return statements,
4699 so we only need to indirectly copy out the parameters. */
4700 if (TREE_ADDRESSABLE (gnu_subprog_type))
4701 {
4702 tree gnu_ret_deref
4703 = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result_decl);
4704 tree t;
4705
4706 gcc_assert (TREE_VALUE (gnu_cico_list) == void_type_node);
4707
4708 for (t = TREE_CHAIN (gnu_cico_list); t; t = TREE_CHAIN (t))
4709 {
4710 tree gnu_field_deref
4711 = build_component_ref (gnu_ret_deref, TREE_PURPOSE (t), true);
4712 gnu_result = build2 (MODIFY_EXPR, void_type_node,
4713 gnu_field_deref, TREE_VALUE (t));
4714 add_stmt_with_node (gnu_result, gnat_end_label);
4715 }
4716 }
4717
4718 /* Otherwise, if this is a procedure or a function which does not return
4719 by invisible reference, we can do a direct block-copy out. */
4720 else
4721 {
4722 tree gnu_retval;
4723
4724 if (list_length (gnu_cico_list) == 1)
4725 gnu_retval = TREE_VALUE (gnu_cico_list);
4726 else
4727 gnu_retval
4728 = build_constructor_from_list (TREE_TYPE (gnu_subprog_type),
4729 gnu_cico_list);
4730
4731 gnu_result = build_return_expr (gnu_result_decl, gnu_retval);
4732 add_stmt_with_node (gnu_result, gnat_end_label);
4733 }
4734
4735 gnat_poplevel ();
4736 gnu_result = end_stmt_group ();
4737 }
4738
4739 gnu_return_label_stack->pop ();
4740
4741 /* Attempt setting the end_locus of our GCC body tree, typically a
4742 BIND_EXPR or STATEMENT_LIST, then the end_locus of our GCC subprogram
4743 declaration tree. */
4744 set_end_locus_from_node (gnu_result, gnat_node);
4745 set_end_locus_from_node (gnu_subprog_decl, gnat_node);
4746
4747 /* On SEH targets, install an exception handler around the main entry
4748 point to catch unhandled exceptions. */
4749 if (DECL_NAME (gnu_subprog_decl) == main_identifier_node
4750 && targetm_common.except_unwind_info (&global_options) == UI_SEH)
4751 {
4752 tree t;
4753 tree etype;
4754
4755 t = build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER),
4756 1, integer_zero_node);
4757 t = build_call_n_expr (unhandled_except_decl, 1, t);
4758
4759 etype = build_unary_op (ADDR_EXPR, NULL_TREE, unhandled_others_decl);
4760 etype = tree_cons (NULL_TREE, etype, NULL_TREE);
4761
4762 t = build2 (CATCH_EXPR, void_type_node, etype, t);
4763 gnu_result = build2 (TRY_CATCH_EXPR, TREE_TYPE (gnu_result),
4764 gnu_result, t);
4765 }
4766
4767 end_subprog_body (gnu_result);
4768
4769 /* Finally annotate the parameters and disconnect the trees for parameters
4770 that we have turned into variables since they are now unusable. */
4771 for (gnat_param = First_Formal_With_Extras (gnat_subprog_id);
4772 Present (gnat_param);
4773 gnat_param = Next_Formal_With_Extras (gnat_param))
4774 {
4775 tree gnu_param = get_gnu_tree (gnat_param);
4776 bool is_var_decl = (TREE_CODE (gnu_param) == VAR_DECL);
4777
4778 annotate_object (gnat_param, TREE_TYPE (gnu_param), NULL_TREE,
4779 DECL_BY_REF_P (gnu_param));
4780
4781 if (is_var_decl)
4782 save_gnu_tree (gnat_param, NULL_TREE, false);
4783 }
4784
4785 /* Disconnect the variable created for the return value. */
4786 if (gnu_return_var_elmt)
4787 TREE_VALUE (gnu_return_var_elmt) = void_type_node;
4788
4789 /* If the function returns an aggregate type and we have candidates for
4790 a Named Return Value, finalize the optimization. */
4791 if (optimize && !optimize_debug && gnu_subprog_language->named_ret_val)
4792 {
4793 finalize_nrv (gnu_subprog_decl,
4794 gnu_subprog_language->named_ret_val,
4795 gnu_subprog_language->other_ret_val,
4796 gnu_subprog_language->gnat_ret);
4797 gnu_subprog_language->named_ret_val = NULL;
4798 gnu_subprog_language->other_ret_val = NULL;
4799 }
4800
4801 /* If this is an inlined external function that has been marked uninlinable,
4802 drop the body and stop there. Otherwise compile the body. */
4803 if (DECL_EXTERNAL (gnu_subprog_decl) && DECL_UNINLINABLE (gnu_subprog_decl))
4804 DECL_SAVED_TREE (gnu_subprog_decl) = NULL_TREE;
4805 else
4806 rest_of_subprog_body_compilation (gnu_subprog_decl);
4807 }
4808
4809 /* The type of an atomic access. */
4810
4811 typedef enum { NOT_ATOMIC, SIMPLE_ATOMIC, OUTER_ATOMIC } atomic_acces_t;
4812
4813 /* Return true if GNAT_NODE references an Atomic entity. This is modeled on
4814 the Is_Atomic_Object predicate of the front-end, but additionally handles
4815 explicit dereferences. */
4816
4817 static bool
node_is_atomic(Node_Id gnat_node)4818 node_is_atomic (Node_Id gnat_node)
4819 {
4820 Entity_Id gnat_entity;
4821
4822 switch (Nkind (gnat_node))
4823 {
4824 case N_Identifier:
4825 case N_Expanded_Name:
4826 gnat_entity = Entity (gnat_node);
4827 if (Ekind (gnat_entity) != E_Variable)
4828 break;
4829 return Is_Atomic (gnat_entity) || Is_Atomic (Etype (gnat_entity));
4830
4831 case N_Selected_Component:
4832 return Is_Atomic (Etype (gnat_node))
4833 || Is_Atomic (Entity (Selector_Name (gnat_node)));
4834
4835 case N_Indexed_Component:
4836 return Is_Atomic (Etype (gnat_node))
4837 || Has_Atomic_Components (Etype (Prefix (gnat_node)))
4838 || (Is_Entity_Name (Prefix (gnat_node))
4839 && Has_Atomic_Components (Entity (Prefix (gnat_node))));
4840
4841 case N_Explicit_Dereference:
4842 return Is_Atomic (Etype (gnat_node));
4843
4844 default:
4845 break;
4846 }
4847
4848 return false;
4849 }
4850
4851 /* Return true if GNAT_NODE references a Volatile_Full_Access entity. This is
4852 modeled on the Is_Volatile_Full_Access_Object predicate of the front-end,
4853 but additionally handles explicit dereferences. */
4854
4855 static bool
node_is_volatile_full_access(Node_Id gnat_node)4856 node_is_volatile_full_access (Node_Id gnat_node)
4857 {
4858 Entity_Id gnat_entity;
4859
4860 switch (Nkind (gnat_node))
4861 {
4862 case N_Identifier:
4863 case N_Expanded_Name:
4864 gnat_entity = Entity (gnat_node);
4865 if (!Is_Object (gnat_entity))
4866 break;
4867 return Is_Volatile_Full_Access (gnat_entity)
4868 || Is_Volatile_Full_Access (Etype (gnat_entity));
4869
4870 case N_Selected_Component:
4871 return Is_Volatile_Full_Access (Etype (gnat_node))
4872 || Is_Volatile_Full_Access (Entity (Selector_Name (gnat_node)));
4873
4874 case N_Indexed_Component:
4875 case N_Explicit_Dereference:
4876 return Is_Volatile_Full_Access (Etype (gnat_node));
4877
4878 default:
4879 break;
4880 }
4881
4882 return false;
4883 }
4884
4885 /* Return true if GNAT_NODE references a component of a larger object. */
4886
4887 static inline bool
node_is_component(Node_Id gnat_node)4888 node_is_component (Node_Id gnat_node)
4889 {
4890 const Node_Kind k = Nkind (gnat_node);
4891 return
4892 (k == N_Indexed_Component || k == N_Selected_Component || k == N_Slice);
4893 }
4894
4895 /* Compute whether GNAT_NODE requires atomic access and set TYPE to the type
4896 of access and SYNC according to the associated synchronization setting.
4897
4898 We implement 3 different semantics of atomicity in this function:
4899
4900 1. the Ada 95/2005/2012 semantics of the Atomic aspect/pragma,
4901 2. the Ada 2020 semantics of the Atomic aspect/pragma,
4902 3. the semantics of the Volatile_Full_Access GNAT aspect/pragma.
4903
4904 They are mutually exclusive and the FE should have rejected conflicts. */
4905
4906 static void
get_atomic_access(Node_Id gnat_node,atomic_acces_t * type,bool * sync)4907 get_atomic_access (Node_Id gnat_node, atomic_acces_t *type, bool *sync)
4908 {
4909 Node_Id gnat_parent, gnat_temp;
4910 unsigned char attr_id;
4911
4912 /* First, scan the parent to filter out irrelevant cases. */
4913 gnat_parent = Parent (gnat_node);
4914 switch (Nkind (gnat_parent))
4915 {
4916 case N_Attribute_Reference:
4917 attr_id = Get_Attribute_Id (Attribute_Name (gnat_parent));
4918 /* Do not mess up machine code insertions. */
4919 if (attr_id == Attr_Asm_Input || attr_id == Attr_Asm_Output)
4920 goto not_atomic;
4921
4922 /* Nothing to do if we are the prefix of an attribute, since we do not
4923 want an atomic access for things like 'Size. */
4924
4925 /* ... fall through ... */
4926
4927 case N_Reference:
4928 /* The N_Reference node is like an attribute. */
4929 if (Prefix (gnat_parent) == gnat_node)
4930 goto not_atomic;
4931 break;
4932
4933 case N_Object_Renaming_Declaration:
4934 /* Nothing to do for the identifier in an object renaming declaration,
4935 the renaming itself does not need atomic access. */
4936 goto not_atomic;
4937
4938 default:
4939 break;
4940 }
4941
4942 /* Now strip any type conversion from GNAT_NODE. */
4943 if (Nkind (gnat_node) == N_Type_Conversion
4944 || Nkind (gnat_node) == N_Unchecked_Type_Conversion)
4945 gnat_node = Expression (gnat_node);
4946
4947 /* Up to Ada 2012, for Atomic itself, only reads and updates of the object as
4948 a whole require atomic access (RM C.6(15)). But, starting with Ada 2020,
4949 reads of or writes to a nonatomic subcomponent of the object also require
4950 atomic access (RM C.6(19)). */
4951 if (node_is_atomic (gnat_node))
4952 {
4953 bool as_a_whole = true;
4954
4955 /* If we are the prefix of the parent, then the access is partial. */
4956 for (gnat_temp = gnat_node, gnat_parent = Parent (gnat_temp);
4957 node_is_component (gnat_parent) && Prefix (gnat_parent) == gnat_temp;
4958 gnat_temp = gnat_parent, gnat_parent = Parent (gnat_temp))
4959 if (Ada_Version < Ada_2020 || node_is_atomic (gnat_parent))
4960 goto not_atomic;
4961 else
4962 as_a_whole = false;
4963
4964 /* We consider that partial accesses are not sequential actions and,
4965 therefore, do not require synchronization. */
4966 *type = SIMPLE_ATOMIC;
4967 *sync = as_a_whole ? Atomic_Sync_Required (gnat_node) : false;
4968 return;
4969 }
4970
4971 /* Look for an outer atomic access of a nonatomic subcomponent. Note that,
4972 for VFA, we do this before looking at the node itself because we need to
4973 access the outermost VFA object atomically, unlike for Atomic where it is
4974 the innermost atomic object (RM C.6(19)). */
4975 for (gnat_temp = gnat_node;
4976 node_is_component (gnat_temp);
4977 gnat_temp = Prefix (gnat_temp))
4978 if ((Ada_Version >= Ada_2020 && node_is_atomic (Prefix (gnat_temp)))
4979 || node_is_volatile_full_access (Prefix (gnat_temp)))
4980 {
4981 *type = OUTER_ATOMIC;
4982 *sync = false;
4983 return;
4984 }
4985
4986 /* Unlike Atomic, accessing a VFA object always requires atomic access. */
4987 if (node_is_volatile_full_access (gnat_node))
4988 {
4989 *type = SIMPLE_ATOMIC;
4990 *sync = false;
4991 return;
4992 }
4993
4994 not_atomic:
4995 *type = NOT_ATOMIC;
4996 *sync = false;
4997 }
4998
4999 /* Return true if GNAT_NODE requires simple atomic access and, if so, set SYNC
5000 according to the associated synchronization setting. */
5001
5002 static inline bool
simple_atomic_access_required_p(Node_Id gnat_node,bool * sync)5003 simple_atomic_access_required_p (Node_Id gnat_node, bool *sync)
5004 {
5005 atomic_acces_t type;
5006 get_atomic_access (gnat_node, &type, sync);
5007 return type == SIMPLE_ATOMIC;
5008 }
5009
5010 /* Create a temporary variable with PREFIX and TYPE, and return it. */
5011
5012 static tree
create_temporary(const char * prefix,tree type)5013 create_temporary (const char *prefix, tree type)
5014 {
5015 tree gnu_temp
5016 = create_var_decl (create_tmp_var_name (prefix), NULL_TREE,
5017 type, NULL_TREE,
5018 false, false, false, false, false,
5019 true, false, NULL, Empty);
5020 return gnu_temp;
5021 }
5022
5023 /* Create a temporary variable with PREFIX and initialize it with GNU_INIT.
5024 Put the initialization statement into GNU_INIT_STMT and annotate it with
5025 the SLOC of GNAT_NODE. Return the temporary variable. */
5026
5027 static tree
create_init_temporary(const char * prefix,tree gnu_init,tree * gnu_init_stmt,Node_Id gnat_node)5028 create_init_temporary (const char *prefix, tree gnu_init, tree *gnu_init_stmt,
5029 Node_Id gnat_node)
5030 {
5031 tree gnu_temp = create_temporary (prefix, TREE_TYPE (gnu_init));
5032
5033 *gnu_init_stmt = build_binary_op (INIT_EXPR, NULL_TREE, gnu_temp, gnu_init);
5034 set_expr_location_from_node (*gnu_init_stmt, gnat_node);
5035
5036 return gnu_temp;
5037 }
5038
5039 /* Subroutine of gnat_to_gnu to translate gnat_node, either an N_Function_Call
5040 or an N_Procedure_Call_Statement, to a GCC tree, which is returned.
5041 GNU_RESULT_TYPE_P is a pointer to where we should place the result type.
5042 If GNU_TARGET is non-null, this must be a function call on the RHS of a
5043 N_Assignment_Statement and the result is to be placed into that object.
5044 ATOMIC_ACCESS is the type of atomic access to be used for the assignment
5045 to GNU_TARGET. If, in addition, ATOMIC_SYNC is true, then the assignment
5046 to GNU_TARGET requires atomic synchronization. */
5047
5048 static tree
Call_to_gnu(Node_Id gnat_node,tree * gnu_result_type_p,tree gnu_target,atomic_acces_t atomic_access,bool atomic_sync)5049 Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
5050 atomic_acces_t atomic_access, bool atomic_sync)
5051 {
5052 const bool function_call = (Nkind (gnat_node) == N_Function_Call);
5053 const bool returning_value = (function_call && !gnu_target);
5054 /* The GCC node corresponding to the GNAT subprogram name. This can either
5055 be a FUNCTION_DECL node if we are dealing with a standard subprogram call,
5056 or an indirect reference expression (an INDIRECT_REF node) pointing to a
5057 subprogram. */
5058 tree gnu_subprog = gnat_to_gnu (Name (gnat_node));
5059 /* The FUNCTION_TYPE node giving the GCC type of the subprogram. */
5060 tree gnu_subprog_type = TREE_TYPE (gnu_subprog);
5061 /* The return type of the FUNCTION_TYPE. */
5062 tree gnu_result_type = TREE_TYPE (gnu_subprog_type);
5063 const bool frontend_builtin
5064 = (TREE_CODE (gnu_subprog) == FUNCTION_DECL
5065 && DECL_BUILT_IN_CLASS (gnu_subprog) == BUILT_IN_FRONTEND);
5066 auto_vec<tree, 16> gnu_actual_vec;
5067 tree gnu_name_list = NULL_TREE;
5068 tree gnu_stmt_list = NULL_TREE;
5069 tree gnu_after_list = NULL_TREE;
5070 tree gnu_retval = NULL_TREE;
5071 tree gnu_call, gnu_result;
5072 bool by_descriptor = false;
5073 bool went_into_elab_proc = false;
5074 bool pushed_binding_level = false;
5075 Entity_Id gnat_formal;
5076 Node_Id gnat_actual;
5077 atomic_acces_t aa_type;
5078 bool aa_sync;
5079
5080 gcc_assert (FUNC_OR_METHOD_TYPE_P (gnu_subprog_type));
5081
5082 /* If we are calling a stubbed function, raise Program_Error, but Elaborate
5083 all our args first. */
5084 if (TREE_CODE (gnu_subprog) == FUNCTION_DECL && DECL_STUBBED_P (gnu_subprog))
5085 {
5086 tree call_expr = build_call_raise (PE_Stubbed_Subprogram_Called,
5087 gnat_node, N_Raise_Program_Error);
5088
5089 for (gnat_actual = First_Actual (gnat_node);
5090 Present (gnat_actual);
5091 gnat_actual = Next_Actual (gnat_actual))
5092 add_stmt (gnat_to_gnu (gnat_actual));
5093
5094 if (returning_value)
5095 {
5096 *gnu_result_type_p = gnu_result_type;
5097 return build1 (NULL_EXPR, gnu_result_type, call_expr);
5098 }
5099
5100 return call_expr;
5101 }
5102
5103 if (TREE_CODE (gnu_subprog) == FUNCTION_DECL)
5104 {
5105 /* For a call to a nested function, check the inlining status. */
5106 if (decl_function_context (gnu_subprog))
5107 check_inlining_for_nested_subprog (gnu_subprog);
5108
5109 /* For a recursive call, avoid explosion due to recursive inlining. */
5110 if (gnu_subprog == current_function_decl)
5111 DECL_DISREGARD_INLINE_LIMITS (gnu_subprog) = 0;
5112 }
5113
5114 /* The only way we can be making a call via an access type is if Name is an
5115 explicit dereference. In that case, get the list of formal args from the
5116 type the access type is pointing to. Otherwise, get the formals from the
5117 entity being called. */
5118 if (Nkind (Name (gnat_node)) == N_Explicit_Dereference)
5119 {
5120 gnat_formal = First_Formal_With_Extras (Etype (Name (gnat_node)));
5121
5122 /* If the access type doesn't require foreign-compatible representation,
5123 be prepared for descriptors. */
5124 if (targetm.calls.custom_function_descriptors > 0
5125 && Can_Use_Internal_Rep
5126 (Underlying_Type (Etype (Prefix (Name (gnat_node))))))
5127 by_descriptor = true;
5128 }
5129 else if (Nkind (Name (gnat_node)) == N_Attribute_Reference)
5130 /* Assume here that this must be 'Elab_Body or 'Elab_Spec. */
5131 gnat_formal = Empty;
5132 else
5133 gnat_formal = First_Formal_With_Extras (Entity (Name (gnat_node)));
5134
5135 /* The lifetime of the temporaries created for the call ends right after the
5136 return value is copied, so we can give them the scope of the elaboration
5137 routine at top level. */
5138 if (!current_function_decl)
5139 {
5140 current_function_decl = get_elaboration_procedure ();
5141 went_into_elab_proc = true;
5142 }
5143
5144 /* First, create the temporary for the return value when:
5145
5146 1. There is no target and the function has copy-in/copy-out parameters,
5147 because we need to preserve the return value before copying back the
5148 parameters.
5149
5150 2. There is no target and the call is made for neither an object, nor a
5151 renaming declaration, nor a return statement, nor an allocator, and
5152 the return type has variable size because in this case the gimplifier
5153 cannot create the temporary, or more generally is an aggregate type,
5154 because the gimplifier would create the temporary in the outermost
5155 scope instead of locally. But there is an exception for an allocator
5156 of an unconstrained record type with default discriminant because we
5157 allocate the actual size in this case, unlike the other 3 cases, so
5158 we need a temporary to fetch the discriminant and we create it here.
5159
5160 3. There is a target and it is a slice or an array with fixed size,
5161 and the return type has variable size, because the gimplifier
5162 doesn't handle these cases.
5163
5164 4. There is no target and we have misaligned In Out or Out parameters
5165 passed by reference, because we need to preserve the return value
5166 before copying back the parameters. However, in this case, we'll
5167 defer creating the temporary, see below.
5168
5169 This must be done before we push a binding level around the call, since
5170 we will pop it before copying the return value. */
5171 if (function_call
5172 && ((!gnu_target && TYPE_CI_CO_LIST (gnu_subprog_type))
5173 || (!gnu_target
5174 && Nkind (Parent (gnat_node)) != N_Object_Declaration
5175 && Nkind (Parent (gnat_node)) != N_Object_Renaming_Declaration
5176 && Nkind (Parent (gnat_node)) != N_Simple_Return_Statement
5177 && (!(Nkind (Parent (gnat_node)) == N_Qualified_Expression
5178 && Nkind (Parent (Parent (gnat_node))) == N_Allocator)
5179 || type_is_padding_self_referential (gnu_result_type))
5180 && AGGREGATE_TYPE_P (gnu_result_type)
5181 && !TYPE_IS_FAT_POINTER_P (gnu_result_type))
5182 || (gnu_target
5183 && (TREE_CODE (gnu_target) == ARRAY_RANGE_REF
5184 || (TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE
5185 && TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target)))
5186 == INTEGER_CST))
5187 && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST)))
5188 {
5189 gnu_retval = create_temporary ("R", gnu_result_type);
5190 DECL_RETURN_VALUE_P (gnu_retval) = 1;
5191 }
5192
5193 /* If we don't need a value or have already created it, push a binding level
5194 around the call. This will narrow the lifetime of the temporaries we may
5195 need to make when translating the parameters as much as possible. */
5196 if (!returning_value || gnu_retval)
5197 {
5198 start_stmt_group ();
5199 gnat_pushlevel ();
5200 pushed_binding_level = true;
5201 }
5202
5203 /* Create the list of the actual parameters as GCC expects it, namely a
5204 chain of TREE_LIST nodes in which the TREE_VALUE field of each node
5205 is an expression and the TREE_PURPOSE field is null. But skip Out
5206 parameters not passed by reference and that need not be copied in. */
5207 for (gnat_actual = First_Actual (gnat_node);
5208 Present (gnat_actual);
5209 gnat_formal = Next_Formal_With_Extras (gnat_formal),
5210 gnat_actual = Next_Actual (gnat_actual))
5211 {
5212 Entity_Id gnat_formal_type = Etype (gnat_formal);
5213 tree gnu_formal_type = gnat_to_gnu_type (gnat_formal_type);
5214 tree gnu_formal = present_gnu_tree (gnat_formal)
5215 ? get_gnu_tree (gnat_formal) : NULL_TREE;
5216 const bool in_param = (Ekind (gnat_formal) == E_In_Parameter);
5217 const bool is_true_formal_parm
5218 = gnu_formal && TREE_CODE (gnu_formal) == PARM_DECL;
5219 const bool is_by_ref_formal_parm
5220 = is_true_formal_parm
5221 && (DECL_BY_REF_P (gnu_formal)
5222 || DECL_BY_COMPONENT_PTR_P (gnu_formal));
5223 /* In the In Out or Out case, we must suppress conversions that yield
5224 an lvalue but can nevertheless cause the creation of a temporary,
5225 because we need the real object in this case, either to pass its
5226 address if it's passed by reference or as target of the back copy
5227 done after the call if it uses the copy-in/copy-out mechanism.
5228 We do it in the In case too, except for an unchecked conversion
5229 to an elementary type or a constrained composite type because it
5230 alone can cause the actual to be misaligned and the addressability
5231 test is applied to the real object. */
5232 const bool suppress_type_conversion
5233 = ((Nkind (gnat_actual) == N_Unchecked_Type_Conversion
5234 && (!in_param
5235 || !is_by_ref_formal_parm
5236 || (Is_Composite_Type (Underlying_Type (gnat_formal_type))
5237 && !Is_Constrained (Underlying_Type (gnat_formal_type)))))
5238 || (Nkind (gnat_actual) == N_Type_Conversion
5239 && Is_Composite_Type (Underlying_Type (gnat_formal_type))));
5240 Node_Id gnat_name = suppress_type_conversion
5241 ? Expression (gnat_actual) : gnat_actual;
5242 tree gnu_name = gnat_to_gnu (gnat_name), gnu_name_type;
5243
5244 /* If it's possible we may need to use this expression twice, make sure
5245 that any side-effects are handled via SAVE_EXPRs; likewise if we need
5246 to force side-effects before the call. */
5247 if (!in_param && !is_by_ref_formal_parm)
5248 {
5249 tree init = NULL_TREE;
5250 gnu_name = gnat_stabilize_reference (gnu_name, true, &init);
5251 if (init)
5252 gnu_name
5253 = build_compound_expr (TREE_TYPE (gnu_name), init, gnu_name);
5254 }
5255
5256 /* If we are passing a non-addressable parameter by reference, pass the
5257 address of a copy. In the In Out or Out case, set up to copy back
5258 out after the call. */
5259 if (is_by_ref_formal_parm
5260 && (gnu_name_type = gnat_to_gnu_type (Etype (gnat_name)))
5261 && !addressable_p (gnu_name, gnu_name_type))
5262 {
5263 tree gnu_orig = gnu_name, gnu_temp, gnu_stmt;
5264
5265 /* Do not issue warnings for CONSTRUCTORs since this is not a copy
5266 but sort of an instantiation for them. */
5267 if (TREE_CODE (remove_conversions (gnu_name, true)) == CONSTRUCTOR)
5268 ;
5269
5270 /* If the formal is passed by reference, a copy is not allowed. */
5271 else if (TYPE_IS_BY_REFERENCE_P (gnu_formal_type)
5272 || Is_Aliased (gnat_formal))
5273 post_error ("misaligned actual cannot be passed by reference",
5274 gnat_actual);
5275
5276 /* If the mechanism was forced to by-ref, a copy is not allowed but
5277 we issue only a warning because this case is not strict Ada. */
5278 else if (DECL_FORCED_BY_REF_P (gnu_formal))
5279 post_error ("misaligned actual cannot be passed by reference??",
5280 gnat_actual);
5281
5282 /* If the actual type of the object is already the nominal type,
5283 we have nothing to do, except if the size is self-referential
5284 in which case we'll remove the unpadding below. */
5285 if (TREE_TYPE (gnu_name) == gnu_name_type
5286 && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_name_type)))
5287 ;
5288
5289 /* Otherwise remove the unpadding from all the objects. */
5290 else if (TREE_CODE (gnu_name) == COMPONENT_REF
5291 && TYPE_IS_PADDING_P
5292 (TREE_TYPE (TREE_OPERAND (gnu_name, 0))))
5293 gnu_orig = gnu_name = TREE_OPERAND (gnu_name, 0);
5294
5295 /* Otherwise convert to the nominal type of the object if needed.
5296 There are several cases in which we need to make the temporary
5297 using this type instead of the actual type of the object when
5298 they are distinct, because the expectations of the callee would
5299 otherwise not be met:
5300 - if it's a justified modular type,
5301 - if the actual type is a smaller form of it,
5302 - if it's a smaller form of the actual type. */
5303 else if ((TREE_CODE (gnu_name_type) == RECORD_TYPE
5304 && (TYPE_JUSTIFIED_MODULAR_P (gnu_name_type)
5305 || smaller_form_type_p (TREE_TYPE (gnu_name),
5306 gnu_name_type)))
5307 || (INTEGRAL_TYPE_P (gnu_name_type)
5308 && smaller_form_type_p (gnu_name_type,
5309 TREE_TYPE (gnu_name))))
5310 gnu_name = convert (gnu_name_type, gnu_name);
5311
5312 /* If this is an In Out or Out parameter and we're returning a value,
5313 we need to create a temporary for the return value because we must
5314 preserve it before copying back at the very end. */
5315 if (!in_param && returning_value && !gnu_retval)
5316 {
5317 gnu_retval = create_temporary ("R", gnu_result_type);
5318 DECL_RETURN_VALUE_P (gnu_retval) = 1;
5319 }
5320
5321 /* If we haven't pushed a binding level, push it now. This will
5322 narrow the lifetime of the temporary we are about to make as
5323 much as possible. */
5324 if (!pushed_binding_level && (!returning_value || gnu_retval))
5325 {
5326 start_stmt_group ();
5327 gnat_pushlevel ();
5328 pushed_binding_level = true;
5329 }
5330
5331 /* Create an explicit temporary holding the copy. */
5332 /* Do not initialize it for the _Init parameter of an initialization
5333 procedure since no data is meant to be passed in. */
5334 if (Ekind (gnat_formal) == E_Out_Parameter
5335 && Is_Entity_Name (Name (gnat_node))
5336 && Is_Init_Proc (Entity (Name (gnat_node))))
5337 gnu_name = gnu_temp = create_temporary ("A", TREE_TYPE (gnu_name));
5338
5339 /* Initialize it on the fly like for an implicit temporary in the
5340 other cases, as we don't necessarily have a statement list. */
5341 else
5342 {
5343 gnu_temp = create_init_temporary ("A", gnu_name, &gnu_stmt,
5344 gnat_actual);
5345 gnu_name = build_compound_expr (TREE_TYPE (gnu_name), gnu_stmt,
5346 gnu_temp);
5347 }
5348
5349 /* Set up to move the copy back to the original if needed. */
5350 if (!in_param)
5351 {
5352 /* If the original is a COND_EXPR whose first arm isn't meant to
5353 be further used, just deal with the second arm. This is very
5354 likely the conditional expression built for a check. */
5355 if (TREE_CODE (gnu_orig) == COND_EXPR
5356 && TREE_CODE (TREE_OPERAND (gnu_orig, 1)) == COMPOUND_EXPR
5357 && integer_zerop
5358 (TREE_OPERAND (TREE_OPERAND (gnu_orig, 1), 1)))
5359 gnu_orig = TREE_OPERAND (gnu_orig, 2);
5360
5361 gnu_stmt
5362 = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_orig, gnu_temp);
5363 set_expr_location_from_node (gnu_stmt, gnat_node);
5364
5365 append_to_statement_list (gnu_stmt, &gnu_after_list);
5366 }
5367 }
5368
5369 /* Start from the real object and build the actual. */
5370 tree gnu_actual = gnu_name;
5371
5372 /* If atomic access is required for an In or In Out actual parameter,
5373 build the atomic load. */
5374 if (is_true_formal_parm
5375 && !is_by_ref_formal_parm
5376 && Ekind (gnat_formal) != E_Out_Parameter
5377 && simple_atomic_access_required_p (gnat_actual, &aa_sync))
5378 gnu_actual = build_atomic_load (gnu_actual, aa_sync);
5379
5380 /* If this was a procedure call, we may not have removed any padding.
5381 So do it here for the part we will use as an input, if any. */
5382 if (Ekind (gnat_formal) != E_Out_Parameter
5383 && TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual)))
5384 gnu_actual
5385 = convert (get_unpadded_type (Etype (gnat_actual)), gnu_actual);
5386
5387 /* Put back the conversion we suppressed above in the computation of the
5388 real object. And even if we didn't suppress any conversion there, we
5389 may have suppressed a conversion to the Etype of the actual earlier,
5390 since the parent is a procedure call, so put it back here. Note that
5391 we might have a dummy type here if the actual is the dereference of a
5392 pointer to it, but that's OK if the formal is passed by reference. */
5393 tree gnu_actual_type = get_unpadded_type (Etype (gnat_actual));
5394 if (TYPE_IS_DUMMY_P (gnu_actual_type))
5395 gcc_assert (is_true_formal_parm && DECL_BY_REF_P (gnu_formal));
5396 else if (suppress_type_conversion
5397 && Nkind (gnat_actual) == N_Unchecked_Type_Conversion)
5398 gnu_actual = unchecked_convert (gnu_actual_type, gnu_actual,
5399 No_Truncation (gnat_actual));
5400 else
5401 gnu_actual = convert (gnu_actual_type, gnu_actual);
5402
5403 gigi_checking_assert (!Do_Range_Check (gnat_actual));
5404
5405 /* First see if the parameter is passed by reference. */
5406 if (is_true_formal_parm && DECL_BY_REF_P (gnu_formal))
5407 {
5408 if (!in_param)
5409 {
5410 /* In Out or Out parameters passed by reference don't use the
5411 copy-in/copy-out mechanism so the address of the real object
5412 must be passed to the function. */
5413 gnu_actual = gnu_name;
5414
5415 /* If we have a padded type, be sure we've removed padding. */
5416 if (TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual)))
5417 gnu_actual = convert (get_unpadded_type (Etype (gnat_actual)),
5418 gnu_actual);
5419
5420 /* If we have the constructed subtype of an aliased object
5421 with an unconstrained nominal subtype, the type of the
5422 actual includes the template, although it is formally
5423 constrained. So we need to convert it back to the real
5424 constructed subtype to retrieve the constrained part
5425 and takes its address. */
5426 if (TREE_CODE (TREE_TYPE (gnu_actual)) == RECORD_TYPE
5427 && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (gnu_actual))
5428 && Is_Constr_Subt_For_UN_Aliased (Etype (gnat_actual))
5429 && Is_Array_Type (Underlying_Type (Etype (gnat_actual))))
5430 gnu_actual = convert (gnu_actual_type, gnu_actual);
5431 }
5432
5433 /* There is no need to convert the actual to the formal's type before
5434 taking its address. The only exception is for unconstrained array
5435 types because of the way we build fat pointers. */
5436 if (TREE_CODE (gnu_formal_type) == UNCONSTRAINED_ARRAY_TYPE)
5437 {
5438 /* Put back the conversion we suppressed above for In Out or Out
5439 parameters, since it may set the bounds of the actual. */
5440 if (!in_param && suppress_type_conversion)
5441 gnu_actual = convert (gnu_actual_type, gnu_actual);
5442 gnu_actual = convert (gnu_formal_type, gnu_actual);
5443 }
5444
5445 /* Take the address of the object and convert to the proper pointer
5446 type. */
5447 gnu_formal_type = TREE_TYPE (gnu_formal);
5448 gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
5449 }
5450
5451 /* Then see if the parameter is an array passed to a foreign convention
5452 subprogram. */
5453 else if (is_true_formal_parm && DECL_BY_COMPONENT_PTR_P (gnu_formal))
5454 {
5455 gnu_actual = maybe_implicit_deref (gnu_actual);
5456 gnu_actual = maybe_unconstrained_array (gnu_actual);
5457
5458 /* Take the address of the object and convert to the proper pointer
5459 type. We'd like to actually compute the address of the beginning
5460 of the array using an ADDR_EXPR of an ARRAY_REF, but there's a
5461 possibility that the ARRAY_REF might return a constant and we'd be
5462 getting the wrong address. Neither approach is exactly correct,
5463 but this is the most likely to work in all cases. */
5464 gnu_formal_type = TREE_TYPE (gnu_formal);
5465 gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
5466 }
5467
5468 /* Otherwise the parameter is passed by copy. */
5469 else
5470 {
5471 tree gnu_size;
5472
5473 if (!in_param)
5474 gnu_name_list = tree_cons (NULL_TREE, gnu_name, gnu_name_list);
5475
5476 /* If we didn't create a PARM_DECL for the formal, this means that
5477 it is an Out parameter not passed by reference and that need not
5478 be copied in. In this case, the value of the actual need not be
5479 read. However, we still need to make sure that its side-effects
5480 are evaluated before the call, so we evaluate its address. */
5481 if (!is_true_formal_parm)
5482 {
5483 if (TREE_SIDE_EFFECTS (gnu_name))
5484 {
5485 tree addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_name);
5486 append_to_statement_list (addr, &gnu_stmt_list);
5487 }
5488 continue;
5489 }
5490
5491 gnu_actual = convert (gnu_formal_type, gnu_actual);
5492
5493 /* If this is 'Null_Parameter, pass a zero even though we are
5494 dereferencing it. */
5495 if (TREE_CODE (gnu_actual) == INDIRECT_REF
5496 && TREE_PRIVATE (gnu_actual)
5497 && (gnu_size = TYPE_SIZE (TREE_TYPE (gnu_actual)))
5498 && TREE_CODE (gnu_size) == INTEGER_CST
5499 && compare_tree_int (gnu_size, BITS_PER_WORD) <= 0)
5500 {
5501 tree type_for_size
5502 = gnat_type_for_size (TREE_INT_CST_LOW (gnu_size), 1);
5503 gnu_actual
5504 = unchecked_convert (DECL_ARG_TYPE (gnu_formal),
5505 build_int_cst (type_for_size, 0),
5506 false);
5507 }
5508
5509 /* If this is a front-end built-in function, there is no need to
5510 convert to the type used to pass the argument. */
5511 else if (!frontend_builtin)
5512 gnu_actual = convert (DECL_ARG_TYPE (gnu_formal), gnu_actual);
5513 }
5514
5515 gnu_actual_vec.safe_push (gnu_actual);
5516 }
5517
5518 if (frontend_builtin)
5519 {
5520 tree pred_cst = build_int_cst (integer_type_node, PRED_BUILTIN_EXPECT);
5521 enum internal_fn icode = IFN_BUILTIN_EXPECT;
5522
5523 switch (DECL_FE_FUNCTION_CODE (gnu_subprog))
5524 {
5525 case BUILT_IN_EXPECT:
5526 break;
5527 case BUILT_IN_LIKELY:
5528 gnu_actual_vec.safe_push (boolean_true_node);
5529 break;
5530 case BUILT_IN_UNLIKELY:
5531 gnu_actual_vec.safe_push (boolean_false_node);
5532 break;
5533 default:
5534 gcc_unreachable ();
5535 }
5536
5537 gnu_actual_vec.safe_push (pred_cst);
5538
5539 gnu_call
5540 = build_call_expr_internal_loc_array (UNKNOWN_LOCATION,
5541 icode,
5542 gnu_result_type,
5543 gnu_actual_vec.length (),
5544 gnu_actual_vec.begin ());
5545 }
5546 else
5547 {
5548 gnu_call
5549 = build_call_array_loc (UNKNOWN_LOCATION,
5550 gnu_result_type,
5551 build_unary_op (ADDR_EXPR, NULL_TREE,
5552 gnu_subprog),
5553 gnu_actual_vec.length (),
5554 gnu_actual_vec.begin ());
5555 CALL_EXPR_BY_DESCRIPTOR (gnu_call) = by_descriptor;
5556 }
5557
5558 set_expr_location_from_node (gnu_call, gnat_node);
5559
5560 /* If we have created a temporary for the return value, initialize it. */
5561 if (gnu_retval)
5562 {
5563 tree gnu_stmt
5564 = build_binary_op (INIT_EXPR, NULL_TREE, gnu_retval, gnu_call);
5565 set_expr_location_from_node (gnu_stmt, gnat_node);
5566 append_to_statement_list (gnu_stmt, &gnu_stmt_list);
5567 gnu_call = gnu_retval;
5568 }
5569
5570 /* If this is a subprogram with copy-in/copy-out parameters, we need to
5571 unpack the valued returned from the function into the In Out or Out
5572 parameters. We deal with the function return (if this is an Ada
5573 function) below. */
5574 if (TYPE_CI_CO_LIST (gnu_subprog_type))
5575 {
5576 /* List of FIELD_DECLs associated with the PARM_DECLs of the copy-in/
5577 copy-out parameters. */
5578 tree gnu_cico_list = TYPE_CI_CO_LIST (gnu_subprog_type);
5579 const int length = list_length (gnu_cico_list);
5580
5581 /* The call sequence must contain one and only one call, even though the
5582 function is pure. Save the result into a temporary if needed. */
5583 if (length > 1)
5584 {
5585 if (!gnu_retval)
5586 {
5587 tree gnu_stmt;
5588 gnu_call
5589 = create_init_temporary ("P", gnu_call, &gnu_stmt, gnat_node);
5590 append_to_statement_list (gnu_stmt, &gnu_stmt_list);
5591 }
5592
5593 gnu_name_list = nreverse (gnu_name_list);
5594 }
5595
5596 /* The first entry is for the actual return value if this is a
5597 function, so skip it. */
5598 if (function_call)
5599 gnu_cico_list = TREE_CHAIN (gnu_cico_list);
5600
5601 if (Nkind (Name (gnat_node)) == N_Explicit_Dereference)
5602 gnat_formal = First_Formal_With_Extras (Etype (Name (gnat_node)));
5603 else
5604 gnat_formal = First_Formal_With_Extras (Entity (Name (gnat_node)));
5605
5606 for (gnat_actual = First_Actual (gnat_node);
5607 Present (gnat_actual);
5608 gnat_formal = Next_Formal_With_Extras (gnat_formal),
5609 gnat_actual = Next_Actual (gnat_actual))
5610 /* If we are dealing with a copy-in/copy-out parameter, we must
5611 retrieve its value from the record returned in the call. */
5612 if (!(present_gnu_tree (gnat_formal)
5613 && TREE_CODE (get_gnu_tree (gnat_formal)) == PARM_DECL
5614 && (DECL_BY_REF_P (get_gnu_tree (gnat_formal))
5615 || DECL_BY_COMPONENT_PTR_P (get_gnu_tree (gnat_formal))))
5616 && Ekind (gnat_formal) != E_In_Parameter)
5617 {
5618 /* Get the value to assign to this In Out or Out parameter. It is
5619 either the result of the function if there is only a single such
5620 parameter or the appropriate field from the record returned. */
5621 tree gnu_result
5622 = length == 1
5623 ? gnu_call
5624 : build_component_ref (gnu_call, TREE_PURPOSE (gnu_cico_list),
5625 false);
5626
5627 /* If the actual is a conversion, get the inner expression, which
5628 will be the real destination, and convert the result to the
5629 type of the actual parameter. */
5630 tree gnu_actual
5631 = maybe_unconstrained_array (TREE_VALUE (gnu_name_list));
5632
5633 /* If the result is a padded type, remove the padding. */
5634 if (TYPE_IS_PADDING_P (TREE_TYPE (gnu_result)))
5635 gnu_result
5636 = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))),
5637 gnu_result);
5638
5639 /* If the actual is a type conversion, the real target object is
5640 denoted by the inner Expression and we need to convert the
5641 result to the associated type.
5642 We also need to convert our gnu assignment target to this type
5643 if the corresponding GNU_NAME was constructed from the GNAT
5644 conversion node and not from the inner Expression. */
5645 if (Nkind (gnat_actual) == N_Type_Conversion)
5646 {
5647 const Node_Id gnat_expr = Expression (gnat_actual);
5648
5649 gigi_checking_assert (!Do_Range_Check (gnat_expr));
5650
5651 gnu_result
5652 = convert_with_check (Etype (gnat_expr), gnu_result,
5653 Do_Overflow_Check (gnat_actual),
5654 Float_Truncate (gnat_actual),
5655 gnat_actual);
5656
5657 if (!Is_Composite_Type (Underlying_Type (Etype (gnat_formal))))
5658 gnu_actual = convert (TREE_TYPE (gnu_result), gnu_actual);
5659 }
5660
5661 /* Unchecked conversions as actuals for Out parameters are not
5662 allowed in user code because they are not variables, but do
5663 occur in front-end expansions. The associated GNU_NAME is
5664 always obtained from the inner expression in such cases. */
5665 else if (Nkind (gnat_actual) == N_Unchecked_Type_Conversion)
5666 gnu_result = unchecked_convert (TREE_TYPE (gnu_actual),
5667 gnu_result,
5668 No_Truncation (gnat_actual));
5669 else
5670 {
5671 gigi_checking_assert (!Do_Range_Check (gnat_actual));
5672
5673 if (!(!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_actual)))
5674 && TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_result)))))
5675 gnu_result = convert (TREE_TYPE (gnu_actual), gnu_result);
5676 }
5677
5678 get_atomic_access (gnat_actual, &aa_type, &aa_sync);
5679
5680 /* If an outer atomic access is required for an actual parameter,
5681 build the load-modify-store sequence. */
5682 if (aa_type == OUTER_ATOMIC)
5683 gnu_result
5684 = build_load_modify_store (gnu_actual, gnu_result, gnat_node);
5685
5686 /* Or else, if a simple atomic access is required, build the atomic
5687 store. */
5688 else if (aa_type == SIMPLE_ATOMIC)
5689 gnu_result
5690 = build_atomic_store (gnu_actual, gnu_result, aa_sync);
5691
5692 /* Otherwise build a regular assignment. */
5693 else
5694 gnu_result = build_binary_op (MODIFY_EXPR, NULL_TREE,
5695 gnu_actual, gnu_result);
5696
5697 if (EXPR_P (gnu_result))
5698 set_expr_location_from_node (gnu_result, gnat_node);
5699 append_to_statement_list (gnu_result, &gnu_stmt_list);
5700 gnu_cico_list = TREE_CHAIN (gnu_cico_list);
5701 gnu_name_list = TREE_CHAIN (gnu_name_list);
5702 }
5703 }
5704
5705 /* If this is a function call, the result is the call expression unless a
5706 target is specified, in which case we copy the result into the target
5707 and return the assignment statement. */
5708 if (function_call)
5709 {
5710 /* If this is a function with copy-in/copy-out parameters, extract the
5711 return value from it and update the return type. */
5712 if (TYPE_CI_CO_LIST (gnu_subprog_type))
5713 {
5714 tree gnu_elmt = TYPE_CI_CO_LIST (gnu_subprog_type);
5715 gnu_call
5716 = build_component_ref (gnu_call, TREE_PURPOSE (gnu_elmt), false);
5717 gnu_result_type = TREE_TYPE (gnu_call);
5718 }
5719
5720 /* If the function returns an unconstrained array or by direct reference,
5721 we have to dereference the pointer. */
5722 if (TYPE_RETURN_UNCONSTRAINED_P (gnu_subprog_type)
5723 || TYPE_RETURN_BY_DIRECT_REF_P (gnu_subprog_type))
5724 gnu_call = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_call);
5725
5726 if (gnu_target)
5727 {
5728 Node_Id gnat_parent = Parent (gnat_node);
5729 enum tree_code op_code;
5730
5731 gigi_checking_assert (!Do_Range_Check (gnat_node));
5732
5733 /* ??? If the return type has variable size, then force the return
5734 slot optimization as we would not be able to create a temporary.
5735 That's what has been done historically. */
5736 if (return_type_with_variable_size_p (gnu_result_type))
5737 op_code = INIT_EXPR;
5738 else
5739 op_code = MODIFY_EXPR;
5740
5741 /* Use the required method to move the result to the target. */
5742 if (atomic_access == OUTER_ATOMIC)
5743 gnu_call
5744 = build_load_modify_store (gnu_target, gnu_call, gnat_node);
5745 else if (atomic_access == SIMPLE_ATOMIC)
5746 gnu_call = build_atomic_store (gnu_target, gnu_call, atomic_sync);
5747 else
5748 gnu_call
5749 = build_binary_op (op_code, NULL_TREE, gnu_target, gnu_call);
5750
5751 if (EXPR_P (gnu_call))
5752 set_expr_location_from_node (gnu_call, gnat_parent);
5753 append_to_statement_list (gnu_call, &gnu_stmt_list);
5754 }
5755 else
5756 *gnu_result_type_p = get_unpadded_type (Etype (gnat_node));
5757 }
5758
5759 /* Otherwise, if this is a procedure call statement without copy-in/copy-out
5760 parameters, the result is just the call statement. */
5761 else if (!TYPE_CI_CO_LIST (gnu_subprog_type))
5762 append_to_statement_list (gnu_call, &gnu_stmt_list);
5763
5764 /* Finally, add the copy back statements, if any. */
5765 append_to_statement_list (gnu_after_list, &gnu_stmt_list);
5766
5767 if (went_into_elab_proc)
5768 current_function_decl = NULL_TREE;
5769
5770 /* If we have pushed a binding level, pop it and finish up the enclosing
5771 statement group. */
5772 if (pushed_binding_level)
5773 {
5774 add_stmt (gnu_stmt_list);
5775 gnat_poplevel ();
5776 gnu_result = end_stmt_group ();
5777 }
5778
5779 /* Otherwise, retrieve the statement list, if any. */
5780 else if (gnu_stmt_list)
5781 gnu_result = gnu_stmt_list;
5782
5783 /* Otherwise, just return the call expression. */
5784 else
5785 return gnu_call;
5786
5787 /* If we nevertheless need a value, make a COMPOUND_EXPR to return it.
5788 But first simplify if we have only one statement in the list. */
5789 if (returning_value)
5790 {
5791 tree first = expr_first (gnu_result), last = expr_last (gnu_result);
5792 if (first == last)
5793 gnu_result = first;
5794 gnu_result
5795 = build_compound_expr (TREE_TYPE (gnu_call), gnu_result, gnu_call);
5796 }
5797
5798 return gnu_result;
5799 }
5800
5801 /* Subroutine of gnat_to_gnu to translate gnat_node, an
5802 N_Handled_Sequence_Of_Statements, to a GCC tree, which is returned. */
5803
5804 static tree
Handled_Sequence_Of_Statements_to_gnu(Node_Id gnat_node)5805 Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
5806 {
5807 /* If just annotating, ignore all EH and cleanups. */
5808 const bool gcc_eh
5809 = (!type_annotate_only
5810 && Present (Exception_Handlers (gnat_node))
5811 && Back_End_Exceptions ());
5812 const bool fe_sjlj_eh
5813 = (!type_annotate_only
5814 && Present (Exception_Handlers (gnat_node))
5815 && Exception_Mechanism == Front_End_SJLJ);
5816 const bool at_end = !type_annotate_only && Present (At_End_Proc (gnat_node));
5817 const bool binding_for_block = (at_end || gcc_eh || fe_sjlj_eh);
5818 tree gnu_jmpsave_decl = NULL_TREE;
5819 tree gnu_jmpbuf_decl = NULL_TREE;
5820 tree gnu_inner_block; /* The statement(s) for the block itself. */
5821 tree gnu_result;
5822 tree gnu_expr;
5823 Node_Id gnat_temp;
5824
5825 /* The GCC exception handling mechanism can handle both ZCX and SJLJ schemes
5826 and the front-end has its own SJLJ mechanism. To call the GCC mechanism,
5827 we call add_cleanup, and when we leave the binding, end_stmt_group will
5828 create the TRY_FINALLY_EXPR construct.
5829
5830 ??? The region level calls down there have been specifically put in place
5831 for a ZCX context and currently the order in which things are emitted
5832 (region/handlers) is different from the SJLJ case. Instead of putting
5833 other calls with different conditions at other places for the SJLJ case,
5834 it seems cleaner to reorder things for the SJLJ case and generalize the
5835 condition to make it not ZCX specific.
5836
5837 If there are any exceptions or cleanup processing involved, we need an
5838 outer statement group (for front-end SJLJ) and binding level. */
5839 if (binding_for_block)
5840 {
5841 start_stmt_group ();
5842 gnat_pushlevel ();
5843 }
5844
5845 /* If using fe_sjlj_eh, make the variables for the setjmp buffer and save
5846 area for address of previous buffer. Do this first since we need to have
5847 the setjmp buf known for any decls in this block. */
5848 if (fe_sjlj_eh)
5849 {
5850 gnu_jmpsave_decl
5851 = create_var_decl (get_identifier ("JMPBUF_SAVE"), NULL_TREE,
5852 jmpbuf_ptr_type,
5853 build_call_n_expr (get_jmpbuf_decl, 0),
5854 false, false, false, false, false, true, false,
5855 NULL, gnat_node);
5856
5857 /* The __builtin_setjmp receivers will immediately reinstall it. Now
5858 because of the unstructured form of EH used by fe_sjlj_eh, there
5859 might be forward edges going to __builtin_setjmp receivers on which
5860 it is uninitialized, although they will never be actually taken. */
5861 TREE_NO_WARNING (gnu_jmpsave_decl) = 1;
5862 gnu_jmpbuf_decl
5863 = create_var_decl (get_identifier ("JMP_BUF"), NULL_TREE,
5864 jmpbuf_type,
5865 NULL_TREE,
5866 false, false, false, false, false, true, false,
5867 NULL, gnat_node);
5868
5869 set_block_jmpbuf_decl (gnu_jmpbuf_decl);
5870
5871 /* When we exit this block, restore the saved value. */
5872 add_cleanup (build_call_n_expr (set_jmpbuf_decl, 1, gnu_jmpsave_decl),
5873 Present (End_Label (gnat_node))
5874 ? End_Label (gnat_node) : gnat_node);
5875 }
5876
5877 /* If we are to call a function when exiting this block, add a cleanup
5878 to the binding level we made above. Note that add_cleanup is FIFO
5879 so we must register this cleanup after the EH cleanup just above. */
5880 if (at_end)
5881 {
5882 tree proc_decl = gnat_to_gnu (At_End_Proc (gnat_node));
5883
5884 /* When not optimizing, disable inlining of finalizers as this can
5885 create a more complex CFG in the parent function. */
5886 if (!optimize || optimize_debug)
5887 DECL_DECLARED_INLINE_P (proc_decl) = 0;
5888
5889 /* If there is no end label attached, we use the location of the At_End
5890 procedure because Expand_Cleanup_Actions might reset the location of
5891 the enclosing construct to that of an inner statement. */
5892 add_cleanup (build_call_n_expr (proc_decl, 0),
5893 Present (End_Label (gnat_node))
5894 ? End_Label (gnat_node) : At_End_Proc (gnat_node));
5895 }
5896
5897 /* Now build the tree for the declarations and statements inside this block.
5898 If this is SJLJ, set our jmp_buf as the current buffer. */
5899 start_stmt_group ();
5900
5901 if (fe_sjlj_eh)
5902 {
5903 gnu_expr = build_call_n_expr (set_jmpbuf_decl, 1,
5904 build_unary_op (ADDR_EXPR, NULL_TREE,
5905 gnu_jmpbuf_decl));
5906 set_expr_location_from_node (gnu_expr, gnat_node);
5907 add_stmt (gnu_expr);
5908 }
5909
5910 if (Present (First_Real_Statement (gnat_node)))
5911 process_decls (Statements (gnat_node), Empty,
5912 First_Real_Statement (gnat_node), true, true);
5913
5914 /* Generate code for each statement in the block. */
5915 for (gnat_temp = (Present (First_Real_Statement (gnat_node))
5916 ? First_Real_Statement (gnat_node)
5917 : First (Statements (gnat_node)));
5918 Present (gnat_temp); gnat_temp = Next (gnat_temp))
5919 add_stmt (gnat_to_gnu (gnat_temp));
5920
5921 gnu_inner_block = end_stmt_group ();
5922
5923 /* Now generate code for the two exception models, if either is relevant for
5924 this block. */
5925 if (fe_sjlj_eh)
5926 {
5927 tree *gnu_else_ptr = 0;
5928 tree gnu_handler;
5929
5930 /* Make a binding level for the exception handling declarations and code
5931 and set up gnu_except_ptr_stack for the handlers to use. */
5932 start_stmt_group ();
5933 gnat_pushlevel ();
5934
5935 vec_safe_push (gnu_except_ptr_stack,
5936 create_var_decl (get_identifier ("EXCEPT_PTR"), NULL_TREE,
5937 build_pointer_type (except_type_node),
5938 build_call_n_expr (get_excptr_decl, 0),
5939 false, false, false, false, false,
5940 true, false, NULL, gnat_node));
5941
5942 /* Generate code for each handler. The N_Exception_Handler case does the
5943 real work and returns a COND_EXPR for each handler, which we chain
5944 together here. */
5945 for (gnat_temp = First_Non_Pragma (Exception_Handlers (gnat_node));
5946 Present (gnat_temp); gnat_temp = Next_Non_Pragma (gnat_temp))
5947 {
5948 gnu_expr = gnat_to_gnu (gnat_temp);
5949
5950 /* If this is the first one, set it as the outer one. Otherwise,
5951 point the "else" part of the previous handler to us. Then point
5952 to our "else" part. */
5953 if (!gnu_else_ptr)
5954 add_stmt (gnu_expr);
5955 else
5956 *gnu_else_ptr = gnu_expr;
5957
5958 gnu_else_ptr = &COND_EXPR_ELSE (gnu_expr);
5959 }
5960
5961 /* If none of the exception handlers did anything, re-raise but do not
5962 defer abortion. */
5963 gnu_expr = build_call_n_expr (raise_nodefer_decl, 1,
5964 gnu_except_ptr_stack->last ());
5965 set_expr_location_from_node
5966 (gnu_expr,
5967 Present (End_Label (gnat_node)) ? End_Label (gnat_node) : gnat_node);
5968
5969 if (gnu_else_ptr)
5970 *gnu_else_ptr = gnu_expr;
5971 else
5972 add_stmt (gnu_expr);
5973
5974 /* End the binding level dedicated to the exception handlers and get the
5975 whole statement group. */
5976 gnu_except_ptr_stack->pop ();
5977 gnat_poplevel ();
5978 gnu_handler = end_stmt_group ();
5979
5980 /* If the setjmp returns 1, we restore our incoming longjmp value and
5981 then check the handlers. */
5982 start_stmt_group ();
5983 add_stmt_with_node (build_call_n_expr (set_jmpbuf_decl, 1,
5984 gnu_jmpsave_decl),
5985 gnat_node);
5986 add_stmt (gnu_handler);
5987 gnu_handler = end_stmt_group ();
5988
5989 /* This block is now "if (setjmp) ... <handlers> else <block>". */
5990 gnu_result = build3 (COND_EXPR, void_type_node,
5991 (build_call_n_expr
5992 (setjmp_decl, 1,
5993 build_unary_op (ADDR_EXPR, NULL_TREE,
5994 gnu_jmpbuf_decl))),
5995 gnu_handler, gnu_inner_block);
5996 }
5997 else if (gcc_eh)
5998 {
5999 tree gnu_handlers;
6000 location_t locus;
6001
6002 /* First make a block containing the handlers. */
6003 start_stmt_group ();
6004 for (gnat_temp = First_Non_Pragma (Exception_Handlers (gnat_node));
6005 Present (gnat_temp);
6006 gnat_temp = Next_Non_Pragma (gnat_temp))
6007 add_stmt (gnat_to_gnu (gnat_temp));
6008 gnu_handlers = end_stmt_group ();
6009
6010 /* Now make the TRY_CATCH_EXPR for the block. */
6011 gnu_result = build2 (TRY_CATCH_EXPR, void_type_node,
6012 gnu_inner_block, gnu_handlers);
6013 /* Set a location. We need to find a unique location for the dispatching
6014 code, otherwise we can get coverage or debugging issues. Try with
6015 the location of the end label. */
6016 if (Present (End_Label (gnat_node))
6017 && Sloc_to_locus (Sloc (End_Label (gnat_node)), &locus))
6018 SET_EXPR_LOCATION (gnu_result, locus);
6019 else
6020 /* Clear column information so that the exception handler of an
6021 implicit transient block does not incorrectly inherit the slocs
6022 of a decision, which would otherwise confuse control flow based
6023 coverage analysis tools. */
6024 set_expr_location_from_node (gnu_result, gnat_node, true);
6025 }
6026 else
6027 gnu_result = gnu_inner_block;
6028
6029 /* Now close our outer block, if we had to make one. */
6030 if (binding_for_block)
6031 {
6032 add_stmt (gnu_result);
6033 gnat_poplevel ();
6034 gnu_result = end_stmt_group ();
6035 }
6036
6037 return gnu_result;
6038 }
6039
6040 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Exception_Handler,
6041 to a GCC tree, which is returned. This is the variant for front-end sjlj
6042 exception handling. */
6043
6044 static tree
Exception_Handler_to_gnu_fe_sjlj(Node_Id gnat_node)6045 Exception_Handler_to_gnu_fe_sjlj (Node_Id gnat_node)
6046 {
6047 /* Unless this is "Others" or the special "Non-Ada" exception for Ada, make
6048 an "if" statement to select the proper exceptions. For "Others", exclude
6049 exceptions where Handled_By_Others is nonzero unless the All_Others flag
6050 is set. For "Non-ada", accept an exception if "Lang" is 'V'. */
6051 tree gnu_choice = boolean_false_node;
6052 tree gnu_body = build_stmt_group (Statements (gnat_node), false);
6053 Node_Id gnat_temp;
6054
6055 for (gnat_temp = First (Exception_Choices (gnat_node));
6056 gnat_temp; gnat_temp = Next (gnat_temp))
6057 {
6058 tree this_choice;
6059
6060 if (Nkind (gnat_temp) == N_Others_Choice)
6061 {
6062 if (All_Others (gnat_temp))
6063 this_choice = boolean_true_node;
6064 else
6065 this_choice
6066 = build_binary_op
6067 (EQ_EXPR, boolean_type_node,
6068 convert
6069 (integer_type_node,
6070 build_component_ref
6071 (build_unary_op
6072 (INDIRECT_REF, NULL_TREE,
6073 gnu_except_ptr_stack->last ()),
6074 not_handled_by_others_decl,
6075 false)),
6076 integer_zero_node);
6077 }
6078
6079 else if (Nkind (gnat_temp) == N_Identifier
6080 || Nkind (gnat_temp) == N_Expanded_Name)
6081 {
6082 Entity_Id gnat_ex_id = Entity (gnat_temp);
6083 tree gnu_expr;
6084
6085 /* Exception may be a renaming. Recover original exception which is
6086 the one elaborated and registered. */
6087 if (Present (Renamed_Object (gnat_ex_id)))
6088 gnat_ex_id = Renamed_Object (gnat_ex_id);
6089
6090 gnu_expr = gnat_to_gnu_entity (gnat_ex_id, NULL_TREE, false);
6091
6092 this_choice
6093 = build_binary_op
6094 (EQ_EXPR, boolean_type_node,
6095 gnu_except_ptr_stack->last (),
6096 convert (TREE_TYPE (gnu_except_ptr_stack->last ()),
6097 build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr)));
6098 }
6099 else
6100 gcc_unreachable ();
6101
6102 gnu_choice = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
6103 gnu_choice, this_choice);
6104 }
6105
6106 return build3 (COND_EXPR, void_type_node, gnu_choice, gnu_body, NULL_TREE);
6107 }
6108
6109 /* Return true if no statement in GNAT_LIST can alter the control flow. */
6110
6111 static bool
stmt_list_cannot_alter_control_flow_p(List_Id gnat_list)6112 stmt_list_cannot_alter_control_flow_p (List_Id gnat_list)
6113 {
6114 if (No (gnat_list))
6115 return true;
6116
6117 /* This is very conservative, we reject everything except for simple
6118 assignments between identifiers or literals. */
6119 for (Node_Id gnat_node = First (gnat_list);
6120 Present (gnat_node);
6121 gnat_node = Next (gnat_node))
6122 {
6123 if (Nkind (gnat_node) != N_Assignment_Statement)
6124 return false;
6125
6126 if (Nkind (Name (gnat_node)) != N_Identifier)
6127 return false;
6128
6129 Node_Kind nkind = Nkind (Expression (gnat_node));
6130 if (nkind != N_Identifier
6131 && nkind != N_Integer_Literal
6132 && nkind != N_Real_Literal)
6133 return false;
6134 }
6135
6136 return true;
6137 }
6138
6139 /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Exception_Handler,
6140 to a GCC tree, which is returned. This is the variant for GCC exception
6141 schemes. */
6142
6143 static tree
Exception_Handler_to_gnu_gcc(Node_Id gnat_node)6144 Exception_Handler_to_gnu_gcc (Node_Id gnat_node)
6145 {
6146 tree gnu_etypes_list = NULL_TREE;
6147
6148 /* We build a TREE_LIST of nodes representing what exception types this
6149 handler can catch, with special cases for others and all others cases.
6150
6151 Each exception type is actually identified by a pointer to the exception
6152 id, or to a dummy object for "others" and "all others". */
6153 for (Node_Id gnat_temp = First (Exception_Choices (gnat_node));
6154 gnat_temp;
6155 gnat_temp = Next (gnat_temp))
6156 {
6157 tree gnu_expr, gnu_etype;
6158
6159 if (Nkind (gnat_temp) == N_Others_Choice)
6160 {
6161 gnu_expr = All_Others (gnat_temp) ? all_others_decl : others_decl;
6162 gnu_etype = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);
6163 }
6164 else if (Nkind (gnat_temp) == N_Identifier
6165 || Nkind (gnat_temp) == N_Expanded_Name)
6166 {
6167 Entity_Id gnat_ex_id = Entity (gnat_temp);
6168
6169 /* Exception may be a renaming. Recover original exception which is
6170 the one elaborated and registered. */
6171 if (Present (Renamed_Object (gnat_ex_id)))
6172 gnat_ex_id = Renamed_Object (gnat_ex_id);
6173
6174 gnu_expr = gnat_to_gnu_entity (gnat_ex_id, NULL_TREE, false);
6175 gnu_etype = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);
6176 }
6177 else
6178 gcc_unreachable ();
6179
6180 /* The GCC interface expects NULL to be passed for catch all handlers, so
6181 it would be quite tempting to set gnu_etypes_list to NULL if gnu_etype
6182 is integer_zero_node. It would not work, however, because GCC's
6183 notion of "catch all" is stronger than our notion of "others". Until
6184 we correctly use the cleanup interface as well, doing that would
6185 prevent the "all others" handlers from being seen, because nothing
6186 can be caught beyond a catch all from GCC's point of view. */
6187 gnu_etypes_list = tree_cons (NULL_TREE, gnu_etype, gnu_etypes_list);
6188 }
6189
6190 start_stmt_group ();
6191 gnat_pushlevel ();
6192
6193 /* Expand a call to the begin_handler hook at the beginning of the
6194 handler, and arrange for a call to the end_handler hook to occur
6195 on every possible exit path. GDB sets a breakpoint in the
6196 begin_handler for catchpoints.
6197
6198 A v1 begin handler saves the cleanup from the exception object,
6199 and marks the exception as in use, so that it will not be
6200 released by other handlers. A v1 end handler restores the
6201 cleanup and releases the exception object, unless it is still
6202 claimed, or the exception is being propagated (reraised).
6203
6204 __builtin_eh_pointer references the exception occurrence being
6205 handled or propagated. Within the handler region, it is the
6206 former, but within the else branch of the EH_ELSE_EXPR, i.e. the
6207 exceptional cleanup path, it is the latter, so we must save the
6208 occurrence being handled early on, so that, should an exception
6209 be (re)raised, we can release the current exception, or figure
6210 out we're not to release it because we're propagating a reraise
6211 thereof.
6212
6213 We use local variables to retrieve the incoming value at handler
6214 entry time (EXPTR), the saved cleanup (EXCLN) and the token
6215 (EXVTK), and reuse them to feed the end_handler hook's argument
6216 at exit. */
6217
6218 /* CODE: void *EXPTR = __builtin_eh_pointer (0); */
6219 tree gnu_current_exc_ptr
6220 = build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER),
6221 1, integer_zero_node);
6222 tree exc_ptr
6223 = create_var_decl (get_identifier ("EXPTR"), NULL_TREE,
6224 ptr_type_node, gnu_current_exc_ptr,
6225 true, false, false, false, false, true, true,
6226 NULL, gnat_node);
6227
6228 tree prev_gnu_incoming_exc_ptr = gnu_incoming_exc_ptr;
6229 gnu_incoming_exc_ptr = exc_ptr;
6230
6231 /* begin_handler_decl must not throw, so we can use it as an
6232 initializer for a variable used in cleanups.
6233
6234 CODE: void *EXCLN = __gnat_begin_handler_v1 (EXPTR); */
6235 tree exc_cleanup
6236 = create_var_decl (get_identifier ("EXCLN"), NULL_TREE,
6237 ptr_type_node,
6238 build_call_n_expr (begin_handler_decl, 1,
6239 exc_ptr),
6240 true, false, false, false, false,
6241 true, true, NULL, gnat_node);
6242
6243 /* Declare and initialize the choice parameter, if present. */
6244 if (Present (Choice_Parameter (gnat_node)))
6245 {
6246 tree gnu_param
6247 = gnat_to_gnu_entity (Choice_Parameter (gnat_node), NULL_TREE, true);
6248
6249 /* CODE: __gnat_set_exception_parameter (&choice_param, EXPTR); */
6250 add_stmt (build_call_n_expr
6251 (set_exception_parameter_decl, 2,
6252 build_unary_op (ADDR_EXPR, NULL_TREE, gnu_param),
6253 gnu_incoming_exc_ptr));
6254 }
6255
6256 /* CODE: <handler proper> */
6257 add_stmt_list (Statements (gnat_node));
6258
6259 tree call = build_call_n_expr (end_handler_decl, 3,
6260 exc_ptr,
6261 exc_cleanup,
6262 null_pointer_node);
6263 /* If the handler can only end by falling off the end, don't bother
6264 with cleanups. */
6265 if (stmt_list_cannot_alter_control_flow_p (Statements (gnat_node)))
6266 /* CODE: __gnat_end_handler_v1 (EXPTR, EXCLN, NULL); */
6267 add_stmt_with_node (call, gnat_node);
6268 /* Otherwise, all of the above is after
6269 CODE: try {
6270
6271 The call above will appear after
6272 CODE: } finally {
6273
6274 And the code below will appear after
6275 CODE: } else {
6276
6277 The else block to a finally block is taken instead of the finally
6278 block when an exception propagates out of the try block. */
6279 else
6280 {
6281 start_stmt_group ();
6282 gnat_pushlevel ();
6283 /* CODE: void *EXPRP = __builtin_eh_handler (0); */
6284 tree prop_ptr
6285 = create_var_decl (get_identifier ("EXPRP"), NULL_TREE,
6286 ptr_type_node,
6287 build_call_expr (builtin_decl_explicit
6288 (BUILT_IN_EH_POINTER),
6289 1, integer_zero_node),
6290 true, false, false, false, false,
6291 true, true, NULL, gnat_node);
6292
6293 /* CODE: __gnat_end_handler_v1 (EXPTR, EXCLN, EXPRP); */
6294 tree ecall = build_call_n_expr (end_handler_decl, 3,
6295 exc_ptr,
6296 exc_cleanup,
6297 prop_ptr);
6298
6299 add_stmt_with_node (ecall, gnat_node);
6300
6301 /* CODE: } */
6302 gnat_poplevel ();
6303 tree eblk = end_stmt_group ();
6304 tree ehls = build2 (EH_ELSE_EXPR, void_type_node, call, eblk);
6305 add_cleanup (ehls, gnat_node);
6306 }
6307
6308 gnat_poplevel ();
6309
6310 gnu_incoming_exc_ptr = prev_gnu_incoming_exc_ptr;
6311
6312 return
6313 build2 (CATCH_EXPR, void_type_node, gnu_etypes_list, end_stmt_group ());
6314 }
6315
6316 /* Subroutine of gnat_to_gnu to generate code for an N_Compilation unit. */
6317
6318 static void
Compilation_Unit_to_gnu(Node_Id gnat_node)6319 Compilation_Unit_to_gnu (Node_Id gnat_node)
6320 {
6321 const Node_Id gnat_unit = Unit (gnat_node);
6322 const bool body_p = (Nkind (gnat_unit) == N_Package_Body
6323 || Nkind (gnat_unit) == N_Subprogram_Body);
6324 const Entity_Id gnat_unit_entity = Defining_Entity (gnat_unit);
6325 Entity_Id gnat_entity;
6326 Node_Id gnat_pragma, gnat_iter;
6327 /* Make the decl for the elaboration procedure. Emit debug info for it, so
6328 that users can break into their elaboration code in debuggers. Kludge:
6329 don't consider it as a definition so that we have a line map for its
6330 body, but no subprogram description in debug info. In addition, don't
6331 qualify it as artificial, even though it is not a user subprogram per se,
6332 in particular for specs. Unlike, say, clones created internally by the
6333 compiler, this subprogram materializes specific user code and flagging it
6334 artificial would take elab code away from gcov's analysis. */
6335 tree gnu_elab_proc_decl
6336 = create_subprog_decl
6337 (create_concat_name (gnat_unit_entity, body_p ? "elabb" : "elabs"),
6338 NULL_TREE, void_ftype, NULL_TREE,
6339 is_default, true, false, false, true, false, NULL, gnat_unit);
6340 struct elab_info *info;
6341
6342 vec_safe_push (gnu_elab_proc_stack, gnu_elab_proc_decl);
6343 DECL_ELABORATION_PROC_P (gnu_elab_proc_decl) = 1;
6344
6345 /* Initialize the information structure for the function. */
6346 allocate_struct_function (gnu_elab_proc_decl, false);
6347 set_cfun (NULL);
6348
6349 current_function_decl = NULL_TREE;
6350
6351 start_stmt_group ();
6352 gnat_pushlevel ();
6353
6354 /* For a body, first process the spec if there is one. */
6355 if (Nkind (gnat_unit) == N_Package_Body
6356 || (Nkind (gnat_unit) == N_Subprogram_Body && !Acts_As_Spec (gnat_node)))
6357 add_stmt (gnat_to_gnu (Library_Unit (gnat_node)));
6358
6359 if (type_annotate_only && gnat_node == Cunit (Main_Unit))
6360 {
6361 elaborate_all_entities (gnat_node);
6362
6363 if (Nkind (gnat_unit) == N_Subprogram_Declaration
6364 || Nkind (gnat_unit) == N_Generic_Package_Declaration
6365 || Nkind (gnat_unit) == N_Generic_Subprogram_Declaration)
6366 return;
6367 }
6368
6369 /* Then process any pragmas and declarations preceding the unit. */
6370 for (gnat_pragma = First (Context_Items (gnat_node));
6371 Present (gnat_pragma);
6372 gnat_pragma = Next (gnat_pragma))
6373 if (Nkind (gnat_pragma) == N_Pragma)
6374 add_stmt (gnat_to_gnu (gnat_pragma));
6375 process_decls (Declarations (Aux_Decls_Node (gnat_node)), Empty, Empty,
6376 true, true);
6377
6378 /* Process the unit itself. */
6379 add_stmt (gnat_to_gnu (gnat_unit));
6380
6381 /* Generate code for all the inlined subprograms. */
6382 for (gnat_entity = First_Inlined_Subprogram (gnat_node);
6383 Present (gnat_entity);
6384 gnat_entity = Next_Inlined_Subprogram (gnat_entity))
6385 {
6386 Node_Id gnat_body;
6387
6388 /* Without optimization, process only the required subprograms. */
6389 if (!optimize && !Has_Pragma_Inline_Always (gnat_entity))
6390 continue;
6391
6392 /* The set of inlined subprograms is computed from data recorded early
6393 during expansion and it can be a strict superset of the final set
6394 computed after semantic analysis, for example if a call to such a
6395 subprogram occurs in a pragma Assert and assertions are disabled.
6396 In that case, semantic analysis resets Is_Public to false but the
6397 entry for the subprogram in the inlining tables is stalled. */
6398 if (!Is_Public (gnat_entity))
6399 continue;
6400
6401 gnat_body = Parent (Declaration_Node (gnat_entity));
6402 if (Nkind (gnat_body) != N_Subprogram_Body)
6403 {
6404 /* ??? This happens when only the spec of a package is provided. */
6405 if (No (Corresponding_Body (gnat_body)))
6406 continue;
6407
6408 gnat_body
6409 = Parent (Declaration_Node (Corresponding_Body (gnat_body)));
6410 }
6411
6412 /* Define the entity first so we set DECL_EXTERNAL. */
6413 gnat_to_gnu_entity (gnat_entity, NULL_TREE, false);
6414 add_stmt (gnat_to_gnu (gnat_body));
6415 }
6416
6417 /* Process any pragmas and actions following the unit. */
6418 add_stmt_list (Pragmas_After (Aux_Decls_Node (gnat_node)));
6419 add_stmt_list (Actions (Aux_Decls_Node (gnat_node)));
6420 finalize_from_limited_with ();
6421
6422 /* Then process the expressions of pragma Compile_Time_{Error|Warning} to
6423 annotate types referenced therein if they have not been annotated. */
6424 for (int i = 0; gnat_compile_time_expr_list.iterate (i, &gnat_iter); i++)
6425 (void) gnat_to_gnu_external (gnat_iter);
6426 gnat_compile_time_expr_list.release ();
6427
6428 /* Save away what we've made so far and finish it up. */
6429 set_current_block_context (gnu_elab_proc_decl);
6430 gnat_poplevel ();
6431 DECL_SAVED_TREE (gnu_elab_proc_decl) = end_stmt_group ();
6432 set_end_locus_from_node (gnu_elab_proc_decl, gnat_unit);
6433 gnu_elab_proc_stack->pop ();
6434
6435 /* Record this potential elaboration procedure for later processing. */
6436 info = ggc_alloc<elab_info> ();
6437 info->next = elab_info_list;
6438 info->elab_proc = gnu_elab_proc_decl;
6439 info->gnat_node = gnat_node;
6440 elab_info_list = info;
6441
6442 /* Force the processing for all nodes that remain in the queue. */
6443 process_deferred_decl_context (true);
6444 }
6445
6446 /* Mark COND, a boolean expression, as predicating a call to a noreturn
6447 function, i.e. predict that it is very likely false, and return it.
6448
6449 The compiler will automatically predict the last edge leading to a call
6450 to a noreturn function as very unlikely taken. This function makes it
6451 possible to extend the prediction to predecessors in case the condition
6452 is made up of several short-circuit operators. */
6453
6454 static tree
build_noreturn_cond(tree cond)6455 build_noreturn_cond (tree cond)
6456 {
6457 tree pred_cst = build_int_cst (integer_type_node, PRED_NORETURN);
6458 return
6459 build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_BUILTIN_EXPECT,
6460 boolean_type_node, 3, cond,
6461 boolean_false_node, pred_cst);
6462 }
6463
6464 /* Subroutine of gnat_to_gnu to translate GNAT_RANGE, a node representing a
6465 range of values, into GNU_LOW and GNU_HIGH bounds. */
6466
6467 static void
Range_to_gnu(Node_Id gnat_range,tree * gnu_low,tree * gnu_high)6468 Range_to_gnu (Node_Id gnat_range, tree *gnu_low, tree *gnu_high)
6469 {
6470 /* GNAT_RANGE is either an N_Range or an identifier denoting a subtype. */
6471 switch (Nkind (gnat_range))
6472 {
6473 case N_Range:
6474 *gnu_low = gnat_to_gnu (Low_Bound (gnat_range));
6475 *gnu_high = gnat_to_gnu (High_Bound (gnat_range));
6476 break;
6477
6478 case N_Expanded_Name:
6479 case N_Identifier:
6480 {
6481 tree gnu_range_type = get_unpadded_type (Entity (gnat_range));
6482 tree gnu_range_base_type = get_base_type (gnu_range_type);
6483
6484 *gnu_low
6485 = convert (gnu_range_base_type, TYPE_MIN_VALUE (gnu_range_type));
6486 *gnu_high
6487 = convert (gnu_range_base_type, TYPE_MAX_VALUE (gnu_range_type));
6488 }
6489 break;
6490
6491 default:
6492 gcc_unreachable ();
6493 }
6494 }
6495
6496 /* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Raise_xxx_Error,
6497 to a GCC tree and return it. GNU_RESULT_TYPE_P is a pointer to where
6498 we should place the result type. */
6499
6500 static tree
Raise_Error_to_gnu(Node_Id gnat_node,tree * gnu_result_type_p)6501 Raise_Error_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
6502 {
6503 const Node_Kind kind = Nkind (gnat_node);
6504 const int reason = UI_To_Int (Reason (gnat_node));
6505 const Node_Id gnat_cond = Condition (gnat_node);
6506 const bool with_extra_info
6507 = Exception_Extra_Info
6508 && !No_Exception_Handlers_Set ()
6509 && No (get_exception_label (kind));
6510 tree gnu_result = NULL_TREE, gnu_cond = NULL_TREE;
6511
6512 /* The following processing is not required for correctness. Its purpose is
6513 to give more precise error messages and to record some information. */
6514 switch (reason)
6515 {
6516 case CE_Access_Check_Failed:
6517 if (with_extra_info)
6518 gnu_result = build_call_raise_column (reason, gnat_node, kind);
6519 break;
6520
6521 case CE_Index_Check_Failed:
6522 case CE_Range_Check_Failed:
6523 case CE_Invalid_Data:
6524 if (Present (gnat_cond) && Nkind (gnat_cond) == N_Op_Not)
6525 {
6526 Node_Id gnat_index, gnat_type;
6527 tree gnu_type, gnu_index, gnu_low_bound, gnu_high_bound, disp;
6528 bool neg_p;
6529 struct loop_info_d *loop;
6530
6531 switch (Nkind (Right_Opnd (gnat_cond)))
6532 {
6533 case N_In:
6534 Range_to_gnu (Right_Opnd (Right_Opnd (gnat_cond)),
6535 &gnu_low_bound, &gnu_high_bound);
6536 break;
6537
6538 case N_Op_Ge:
6539 gnu_low_bound = gnat_to_gnu (Right_Opnd (Right_Opnd (gnat_cond)));
6540 gnu_high_bound = NULL_TREE;
6541 break;
6542
6543 case N_Op_Le:
6544 gnu_low_bound = NULL_TREE;
6545 gnu_high_bound = gnat_to_gnu (Right_Opnd (Right_Opnd (gnat_cond)));
6546 break;
6547
6548 default:
6549 goto common;
6550 }
6551
6552 gnat_index = Left_Opnd (Right_Opnd (gnat_cond));
6553 gnat_type = Etype (gnat_index);
6554 gnu_type = maybe_character_type (get_unpadded_type (gnat_type));
6555 gnu_index = gnat_to_gnu (gnat_index);
6556
6557 if (TREE_TYPE (gnu_index) != gnu_type)
6558 {
6559 if (gnu_low_bound)
6560 gnu_low_bound = convert (gnu_type, gnu_low_bound);
6561 if (gnu_high_bound)
6562 gnu_high_bound = convert (gnu_type, gnu_high_bound);
6563 gnu_index = convert (gnu_type, gnu_index);
6564 }
6565
6566 if (with_extra_info
6567 && gnu_low_bound
6568 && gnu_high_bound
6569 && Known_Esize (gnat_type)
6570 && UI_To_Int (Esize (gnat_type)) <= 32)
6571 gnu_result
6572 = build_call_raise_range (reason, gnat_node, kind, gnu_index,
6573 gnu_low_bound, gnu_high_bound);
6574
6575 /* If optimization is enabled and we are inside a loop, we try to
6576 compute invariant conditions for checks applied to the iteration
6577 variable, i.e. conditions that are independent of the variable
6578 and necessary in order for the checks to fail in the course of
6579 some iteration. If we succeed, we consider an alternative:
6580
6581 1. If loop unswitching is enabled, we prepend these conditions
6582 to the original conditions of the checks. This will make it
6583 possible for the loop unswitching pass to replace the loop
6584 with two loops, one of which has the checks eliminated and
6585 the other has the original checks reinstated, and a prologue
6586 implementing a run-time selection. The former loop will be
6587 for example suitable for vectorization.
6588
6589 2. Otherwise, we instead append the conditions to the original
6590 conditions of the checks. At worse, if the conditions cannot
6591 be evaluated at compile time, they will be evaluated as true
6592 at run time only when the checks have already failed, thus
6593 contributing negatively only to the size of the executable.
6594 But the hope is that these invariant conditions be evaluated
6595 at compile time to false, thus taking away the entire checks
6596 with them. */
6597 if (optimize
6598 && inside_loop_p ()
6599 && (!gnu_low_bound
6600 || (gnu_low_bound = gnat_invariant_expr (gnu_low_bound)))
6601 && (!gnu_high_bound
6602 || (gnu_high_bound = gnat_invariant_expr (gnu_high_bound)))
6603 && (loop = find_loop_for (gnu_index, &disp, &neg_p)))
6604 {
6605 struct range_check_info_d *rci = ggc_alloc<range_check_info_d> ();
6606 rci->low_bound = gnu_low_bound;
6607 rci->high_bound = gnu_high_bound;
6608 rci->disp = disp;
6609 rci->neg_p = neg_p;
6610 rci->type = gnu_type;
6611 rci->inserted_cond
6612 = build1 (SAVE_EXPR, boolean_type_node, boolean_true_node);
6613 vec_safe_push (loop->checks, rci);
6614 gnu_cond = build_noreturn_cond (gnat_to_gnu (gnat_cond));
6615 if (optimize >= 3)
6616 gnu_cond = build_binary_op (TRUTH_ANDIF_EXPR,
6617 boolean_type_node,
6618 rci->inserted_cond,
6619 gnu_cond);
6620 else
6621 gnu_cond = build_binary_op (TRUTH_ANDIF_EXPR,
6622 boolean_type_node,
6623 gnu_cond,
6624 rci->inserted_cond);
6625 }
6626 }
6627 break;
6628
6629 default:
6630 break;
6631 }
6632
6633 /* The following processing does the common work. */
6634 common:
6635 if (!gnu_result)
6636 gnu_result = build_call_raise (reason, gnat_node, kind);
6637 set_expr_location_from_node (gnu_result, gnat_node);
6638
6639 *gnu_result_type_p = get_unpadded_type (Etype (gnat_node));
6640
6641 /* If the type is VOID, this is a statement, so we need to generate the code
6642 for the call. Handle a condition, if there is one. */
6643 if (VOID_TYPE_P (*gnu_result_type_p))
6644 {
6645 if (Present (gnat_cond))
6646 {
6647 if (!gnu_cond)
6648 gnu_cond = gnat_to_gnu (gnat_cond);
6649 gnu_result = build3 (COND_EXPR, void_type_node, gnu_cond, gnu_result,
6650 alloc_stmt_list ());
6651 }
6652 }
6653 else
6654 gnu_result = build1 (NULL_EXPR, *gnu_result_type_p, gnu_result);
6655
6656 return gnu_result;
6657 }
6658
6659 /* Return true if GNAT_NODE is on the LHS of an assignment or an actual
6660 parameter of a call. */
6661
6662 static bool
lhs_or_actual_p(Node_Id gnat_node)6663 lhs_or_actual_p (Node_Id gnat_node)
6664 {
6665 const Node_Id gnat_parent = Parent (gnat_node);
6666 const Node_Kind kind = Nkind (gnat_parent);
6667
6668 if (kind == N_Assignment_Statement && Name (gnat_parent) == gnat_node)
6669 return true;
6670
6671 if ((kind == N_Procedure_Call_Statement || kind == N_Function_Call)
6672 && Name (gnat_parent) != gnat_node)
6673 return true;
6674
6675 if (kind == N_Parameter_Association)
6676 return true;
6677
6678 return false;
6679 }
6680
6681 /* Return true if either GNAT_NODE or a view of GNAT_NODE is on the LHS
6682 of an assignment or an actual parameter of a call. */
6683
6684 static bool
present_in_lhs_or_actual_p(Node_Id gnat_node)6685 present_in_lhs_or_actual_p (Node_Id gnat_node)
6686 {
6687 if (lhs_or_actual_p (gnat_node))
6688 return true;
6689
6690 const Node_Kind kind = Nkind (Parent (gnat_node));
6691
6692 if ((kind == N_Type_Conversion || kind == N_Unchecked_Type_Conversion)
6693 && lhs_or_actual_p (Parent (gnat_node)))
6694 return true;
6695
6696 return false;
6697 }
6698
6699 /* Return true if GNAT_NODE, an unchecked type conversion, is a no-op as far
6700 as gigi is concerned. This is used to avoid conversions on the LHS. */
6701
6702 static bool
unchecked_conversion_nop(Node_Id gnat_node)6703 unchecked_conversion_nop (Node_Id gnat_node)
6704 {
6705 Entity_Id from_type, to_type;
6706
6707 /* The conversion must be on the LHS of an assignment or an actual parameter
6708 of a call. Otherwise, even if the conversion was essentially a no-op, it
6709 could de facto ensure type consistency and this should be preserved. */
6710 if (!lhs_or_actual_p (gnat_node))
6711 return false;
6712
6713 from_type = Etype (Expression (gnat_node));
6714
6715 /* We're interested in artificial conversions generated by the front-end
6716 to make private types explicit, e.g. in Expand_Assign_Array. */
6717 if (!Is_Private_Type (from_type))
6718 return false;
6719
6720 from_type = Underlying_Type (from_type);
6721 to_type = Etype (gnat_node);
6722
6723 /* The direct conversion to the underlying type is a no-op. */
6724 if (to_type == from_type)
6725 return true;
6726
6727 /* For an array subtype, the conversion to the PAIT is a no-op. */
6728 if (Ekind (from_type) == E_Array_Subtype
6729 && to_type == Packed_Array_Impl_Type (from_type))
6730 return true;
6731
6732 /* For a record subtype, the conversion to the type is a no-op. */
6733 if (Ekind (from_type) == E_Record_Subtype
6734 && to_type == Etype (from_type))
6735 return true;
6736
6737 return false;
6738 }
6739
6740 /* Return true if GNAT_NODE represents a statement. */
6741
6742 static bool
statement_node_p(Node_Id gnat_node)6743 statement_node_p (Node_Id gnat_node)
6744 {
6745 const Node_Kind kind = Nkind (gnat_node);
6746
6747 if (kind == N_Label)
6748 return true;
6749
6750 if (IN (kind, N_Statement_Other_Than_Procedure_Call))
6751 return true;
6752
6753 if (kind == N_Procedure_Call_Statement)
6754 return true;
6755
6756 if (IN (kind, N_Raise_xxx_Error) && Ekind (Etype (gnat_node)) == E_Void)
6757 return true;
6758
6759 return false;
6760 }
6761
6762 /* This function is the driver of the GNAT to GCC tree transformation process.
6763 It is the entry point of the tree transformer. GNAT_NODE is the root of
6764 some GNAT tree. Return the root of the corresponding GCC tree. If this
6765 is an expression, return the GCC equivalent of the expression. If this
6766 is a statement, return the statement or add it to the current statement
6767 group, in which case anything returned is to be interpreted as occurring
6768 after anything added. */
6769
6770 tree
gnat_to_gnu(Node_Id gnat_node)6771 gnat_to_gnu (Node_Id gnat_node)
6772 {
6773 const Node_Kind kind = Nkind (gnat_node);
6774 bool went_into_elab_proc = false;
6775 tree gnu_result = error_mark_node; /* Default to no value. */
6776 tree gnu_result_type = void_type_node;
6777 tree gnu_expr, gnu_lhs, gnu_rhs;
6778 Node_Id gnat_temp;
6779 atomic_acces_t aa_type;
6780 bool aa_sync;
6781
6782 /* Save node number for error message and set location information. */
6783 Current_Error_Node = gnat_node;
6784 Sloc_to_locus (Sloc (gnat_node), &input_location);
6785
6786 /* If we are only annotating types and this node is a statement, return
6787 an empty statement list. */
6788 if (type_annotate_only && statement_node_p (gnat_node))
6789 return alloc_stmt_list ();
6790
6791 /* If we are only annotating types and this node is a subexpression, return
6792 a NULL_EXPR, but filter out nodes appearing in the expressions attached
6793 to packed array implementation types. */
6794 if (type_annotate_only
6795 && IN (kind, N_Subexpr)
6796 && !(((IN (kind, N_Op) && kind != N_Op_Expon)
6797 || kind == N_Type_Conversion)
6798 && Is_Integer_Type (Etype (gnat_node)))
6799 && !(kind == N_Attribute_Reference
6800 && (Get_Attribute_Id (Attribute_Name (gnat_node)) == Attr_Length
6801 || Get_Attribute_Id (Attribute_Name (gnat_node)) == Attr_Size)
6802 && Is_Constrained (Etype (Prefix (gnat_node)))
6803 && !Is_Constr_Subt_For_U_Nominal (Etype (Prefix (gnat_node))))
6804 && kind != N_Expanded_Name
6805 && kind != N_Identifier
6806 && !Compile_Time_Known_Value (gnat_node))
6807 return build1 (NULL_EXPR, get_unpadded_type (Etype (gnat_node)),
6808 build_call_raise (CE_Range_Check_Failed, gnat_node,
6809 N_Raise_Constraint_Error));
6810
6811 if ((statement_node_p (gnat_node) && kind != N_Null_Statement)
6812 || kind == N_Handled_Sequence_Of_Statements
6813 || kind == N_Implicit_Label_Declaration)
6814 {
6815 tree current_elab_proc = get_elaboration_procedure ();
6816
6817 /* If this is a statement and we are at top level, it must be part of
6818 the elaboration procedure, so mark us as being in that procedure. */
6819 if (!current_function_decl)
6820 {
6821 current_function_decl = current_elab_proc;
6822 went_into_elab_proc = true;
6823 }
6824
6825 /* If we are in the elaboration procedure, check if we are violating a
6826 No_Elaboration_Code restriction by having a statement there. Don't
6827 check for a possible No_Elaboration_Code restriction violation on
6828 N_Handled_Sequence_Of_Statements, as we want to signal an error on
6829 every nested real statement instead. This also avoids triggering
6830 spurious errors on dummy (empty) sequences created by the front-end
6831 for package bodies in some cases. */
6832 if (current_function_decl == current_elab_proc
6833 && kind != N_Handled_Sequence_Of_Statements
6834 && kind != N_Implicit_Label_Declaration)
6835 Check_Elaboration_Code_Allowed (gnat_node);
6836 }
6837
6838 switch (kind)
6839 {
6840 /********************************/
6841 /* Chapter 2: Lexical Elements */
6842 /********************************/
6843
6844 case N_Identifier:
6845 case N_Expanded_Name:
6846 case N_Operator_Symbol:
6847 case N_Defining_Identifier:
6848 case N_Defining_Operator_Symbol:
6849 gnu_result = Identifier_to_gnu (gnat_node, &gnu_result_type);
6850
6851 /* If atomic access is required on the RHS, build the atomic load. */
6852 if (simple_atomic_access_required_p (gnat_node, &aa_sync)
6853 && !present_in_lhs_or_actual_p (gnat_node))
6854 gnu_result = build_atomic_load (gnu_result, aa_sync);
6855 break;
6856
6857 case N_Integer_Literal:
6858 {
6859 tree gnu_type;
6860
6861 /* Get the type of the result, looking inside any padding and
6862 justified modular types. Then get the value in that type. */
6863 gnu_type = gnu_result_type = get_unpadded_type (Etype (gnat_node));
6864
6865 if (TREE_CODE (gnu_type) == RECORD_TYPE
6866 && TYPE_JUSTIFIED_MODULAR_P (gnu_type))
6867 gnu_type = TREE_TYPE (TYPE_FIELDS (gnu_type));
6868
6869 gnu_result = UI_To_gnu (Intval (gnat_node), gnu_type);
6870
6871 /* If the result overflows (meaning it doesn't fit in its base type),
6872 abort, unless this is for a named number because that's not fatal.
6873 We would like to check that the value is within the range of the
6874 subtype, but that causes problems with subtypes whose usage will
6875 raise Constraint_Error and also with biased representation. */
6876 if (TREE_OVERFLOW (gnu_result))
6877 {
6878 if (Nkind (Parent (gnat_node)) == N_Number_Declaration)
6879 gnu_result = error_mark_node;
6880 else
6881 gcc_unreachable ();
6882 }
6883 }
6884 break;
6885
6886 case N_Character_Literal:
6887 /* If a Entity is present, it means that this was one of the
6888 literals in a user-defined character type. In that case,
6889 just return the value in the CONST_DECL. Otherwise, use the
6890 character code. In that case, the base type should be an
6891 INTEGER_TYPE, but we won't bother checking for that. */
6892 gnu_result_type = get_unpadded_type (Etype (gnat_node));
6893 if (Present (Entity (gnat_node)))
6894 gnu_result = DECL_INITIAL (get_gnu_tree (Entity (gnat_node)));
6895 else
6896 gnu_result
6897 = build_int_cst (gnu_result_type,
6898 UI_To_CC (Char_Literal_Value (gnat_node)));
6899 break;
6900
6901 case N_Real_Literal:
6902 gnu_result_type = get_unpadded_type (Etype (gnat_node));
6903
6904 /* If this is of a fixed-point type, the value we want is the value of
6905 the corresponding integer. */
6906 if (Is_Fixed_Point_Type (Underlying_Type (Etype (gnat_node))))
6907 {
6908 gnu_result = UI_To_gnu (Corresponding_Integer_Value (gnat_node),
6909 gnu_result_type);
6910 gcc_assert (!TREE_OVERFLOW (gnu_result));
6911 }
6912
6913 else
6914 {
6915 Ureal ur_realval = Realval (gnat_node);
6916
6917 /* First convert the value to a machine number if it isn't already.
6918 That will force the base to 2 for non-zero values and simplify
6919 the rest of the logic. */
6920 if (!Is_Machine_Number (gnat_node))
6921 ur_realval
6922 = Machine (Base_Type (Underlying_Type (Etype (gnat_node))),
6923 ur_realval, Round_Even, gnat_node);
6924
6925 if (UR_Is_Zero (ur_realval))
6926 gnu_result = build_real (gnu_result_type, dconst0);
6927 else
6928 {
6929 REAL_VALUE_TYPE tmp;
6930
6931 gnu_result = UI_To_gnu (Numerator (ur_realval), gnu_result_type);
6932
6933 /* The base must be 2 as Machine guarantees this, so we scale
6934 the value, which we know can fit in the mantissa of the type
6935 (hence the use of that type above). */
6936 gcc_assert (Rbase (ur_realval) == 2);
6937 real_ldexp (&tmp, &TREE_REAL_CST (gnu_result),
6938 - UI_To_Int (Denominator (ur_realval)));
6939 gnu_result = build_real (gnu_result_type, tmp);
6940 }
6941
6942 /* Now see if we need to negate the result. Do it this way to
6943 properly handle -0. */
6944 if (UR_Is_Negative (Realval (gnat_node)))
6945 gnu_result
6946 = build_unary_op (NEGATE_EXPR, get_base_type (gnu_result_type),
6947 gnu_result);
6948 }
6949
6950 break;
6951
6952 case N_String_Literal:
6953 gnu_result_type = get_unpadded_type (Etype (gnat_node));
6954 if (TYPE_PRECISION (TREE_TYPE (gnu_result_type)) == HOST_BITS_PER_CHAR)
6955 {
6956 String_Id gnat_string = Strval (gnat_node);
6957 int length = String_Length (gnat_string);
6958 int i;
6959 char *string;
6960 if (length >= ALLOCA_THRESHOLD)
6961 string = XNEWVEC (char, length + 1);
6962 else
6963 string = (char *) alloca (length + 1);
6964
6965 /* Build the string with the characters in the literal. Note
6966 that Ada strings are 1-origin. */
6967 for (i = 0; i < length; i++)
6968 string[i] = Get_String_Char (gnat_string, i + 1);
6969
6970 /* Put a null at the end of the string in case it's in a context
6971 where GCC will want to treat it as a C string. */
6972 string[i] = 0;
6973
6974 gnu_result = build_string (length, string);
6975
6976 /* Strings in GCC don't normally have types, but we want
6977 this to not be converted to the array type. */
6978 TREE_TYPE (gnu_result) = gnu_result_type;
6979
6980 if (length >= ALLOCA_THRESHOLD)
6981 free (string);
6982 }
6983 else
6984 {
6985 /* Build a list consisting of each character, then make
6986 the aggregate. */
6987 String_Id gnat_string = Strval (gnat_node);
6988 int length = String_Length (gnat_string);
6989 int i;
6990 tree gnu_idx = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_result_type));
6991 tree gnu_one_node = convert (TREE_TYPE (gnu_idx), integer_one_node);
6992 vec<constructor_elt, va_gc> *gnu_vec;
6993 vec_alloc (gnu_vec, length);
6994
6995 for (i = 0; i < length; i++)
6996 {
6997 tree t = build_int_cst (TREE_TYPE (gnu_result_type),
6998 Get_String_Char (gnat_string, i + 1));
6999
7000 CONSTRUCTOR_APPEND_ELT (gnu_vec, gnu_idx, t);
7001 gnu_idx = int_const_binop (PLUS_EXPR, gnu_idx, gnu_one_node);
7002 }
7003
7004 gnu_result = gnat_build_constructor (gnu_result_type, gnu_vec);
7005 }
7006 break;
7007
7008 case N_Pragma:
7009 gnu_result = Pragma_to_gnu (gnat_node);
7010 break;
7011
7012 /**************************************/
7013 /* Chapter 3: Declarations and Types */
7014 /**************************************/
7015
7016 case N_Subtype_Declaration:
7017 case N_Full_Type_Declaration:
7018 case N_Incomplete_Type_Declaration:
7019 case N_Private_Type_Declaration:
7020 case N_Private_Extension_Declaration:
7021 case N_Task_Type_Declaration:
7022 process_type (Defining_Entity (gnat_node));
7023 gnu_result = alloc_stmt_list ();
7024 break;
7025
7026 case N_Object_Declaration:
7027 case N_Number_Declaration:
7028 case N_Exception_Declaration:
7029 gnat_temp = Defining_Entity (gnat_node);
7030 gnu_result = alloc_stmt_list ();
7031
7032 /* If we are just annotating types and this object has an unconstrained
7033 or task type, don't elaborate it. */
7034 if (type_annotate_only
7035 && (((Is_Array_Type (Etype (gnat_temp))
7036 || Is_Record_Type (Etype (gnat_temp)))
7037 && !Is_Constrained (Etype (gnat_temp)))
7038 || Is_Concurrent_Type (Etype (gnat_temp))))
7039 break;
7040
7041 if (Present (Expression (gnat_node))
7042 && !(kind == N_Object_Declaration && No_Initialization (gnat_node))
7043 && (!type_annotate_only
7044 || Compile_Time_Known_Value (Expression (gnat_node))))
7045 {
7046 gigi_checking_assert (!Do_Range_Check (Expression (gnat_node)));
7047
7048 gnu_expr = gnat_to_gnu (Expression (gnat_node));
7049
7050 if (TREE_CODE (gnu_expr) == ERROR_MARK)
7051 {
7052 /* If this is a named number for which we cannot manipulate
7053 the value, just skip the declaration altogether. */
7054 if (kind == N_Number_Declaration)
7055 break;
7056 else if (type_annotate_only)
7057 gnu_expr = NULL_TREE;
7058 }
7059 }
7060 else
7061 gnu_expr = NULL_TREE;
7062
7063 /* If this is a deferred constant with an address clause, we ignore the
7064 full view since the clause is on the partial view and we cannot have
7065 2 different GCC trees for the object. The only bits of the full view
7066 we will use is the initializer, but it will be directly fetched. */
7067 if (Ekind (gnat_temp) == E_Constant
7068 && Present (Address_Clause (gnat_temp))
7069 && Present (Full_View (gnat_temp)))
7070 save_gnu_tree (Full_View (gnat_temp), error_mark_node, true);
7071
7072 /* If this object has its elaboration delayed, we must force evaluation
7073 of GNU_EXPR now and save it for the freeze point. Note that we need
7074 not do anything special at the global level since the lifetime of the
7075 temporary is fully contained within the elaboration routine. */
7076 if (Present (Freeze_Node (gnat_temp)))
7077 {
7078 if (gnu_expr)
7079 {
7080 gnu_result = gnat_save_expr (gnu_expr);
7081 save_gnu_tree (gnat_node, gnu_result, true);
7082 }
7083 }
7084 else
7085 gnat_to_gnu_entity (gnat_temp, gnu_expr, true);
7086 break;
7087
7088 case N_Object_Renaming_Declaration:
7089 gnat_temp = Defining_Entity (gnat_node);
7090 gnu_result = alloc_stmt_list ();
7091
7092 /* Don't do anything if this renaming is handled by the front end and it
7093 does not need debug info. Note that we consider renamings don't need
7094 debug info when optimizing: our way to describe them has a
7095 memory/elaboration footprint.
7096
7097 Don't do anything neither if we are just annotating types and this
7098 object has a composite or task type, don't elaborate it. */
7099 if ((!Is_Renaming_Of_Object (gnat_temp)
7100 || (Needs_Debug_Info (gnat_temp)
7101 && !optimize
7102 && can_materialize_object_renaming_p
7103 (Renamed_Object (gnat_temp))))
7104 && ! (type_annotate_only
7105 && (Is_Array_Type (Etype (gnat_temp))
7106 || Is_Record_Type (Etype (gnat_temp))
7107 || Is_Concurrent_Type (Etype (gnat_temp)))))
7108 {
7109 tree gnu_temp
7110 = gnat_to_gnu_entity (gnat_temp,
7111 gnat_to_gnu (Renamed_Object (gnat_temp)),
7112 true);
7113 /* See case 2 of renaming in gnat_to_gnu_entity. */
7114 if (TREE_SIDE_EFFECTS (gnu_temp))
7115 gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_temp);
7116 }
7117 break;
7118
7119 case N_Exception_Renaming_Declaration:
7120 gnat_temp = Defining_Entity (gnat_node);
7121 gnu_result = alloc_stmt_list ();
7122
7123 /* See the above case for the rationale. */
7124 if (Present (Renamed_Entity (gnat_temp)))
7125 {
7126 tree gnu_temp
7127 = gnat_to_gnu_entity (gnat_temp,
7128 gnat_to_gnu (Renamed_Entity (gnat_temp)),
7129 true);
7130 if (TREE_SIDE_EFFECTS (gnu_temp))
7131 gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_temp);
7132 }
7133 break;
7134
7135 case N_Subprogram_Renaming_Declaration:
7136 {
7137 const Node_Id gnat_renaming = Defining_Entity (gnat_node);
7138 const Node_Id gnat_renamed = Renamed_Entity (gnat_renaming);
7139
7140 gnu_result = alloc_stmt_list ();
7141
7142 /* Materializing renamed subprograms will only benefit the debugging
7143 information as they aren't referenced in the generated code. So
7144 skip them when they aren't needed. Avoid doing this if:
7145
7146 - there is a freeze node: in this case the renamed entity is not
7147 elaborated yet,
7148 - the renamed subprogram is intrinsic: it will not be available in
7149 the debugging information (note that both or only one of the
7150 renaming and the renamed subprograms can be intrinsic). */
7151 if (!type_annotate_only
7152 && Needs_Debug_Info (gnat_renaming)
7153 && No (Freeze_Node (gnat_renaming))
7154 && Present (gnat_renamed)
7155 && (Ekind (gnat_renamed) == E_Function
7156 || Ekind (gnat_renamed) == E_Procedure)
7157 && !Is_Intrinsic_Subprogram (gnat_renaming)
7158 && !Is_Intrinsic_Subprogram (gnat_renamed))
7159 gnat_to_gnu_entity (gnat_renaming, gnat_to_gnu (gnat_renamed), true);
7160 break;
7161 }
7162
7163 case N_Implicit_Label_Declaration:
7164 gnat_to_gnu_entity (Defining_Entity (gnat_node), NULL_TREE, true);
7165 gnu_result = alloc_stmt_list ();
7166 break;
7167
7168 case N_Package_Renaming_Declaration:
7169 /* These are fully handled in the front end. */
7170 /* ??? For package renamings, find a way to use GENERIC namespaces so
7171 that we get proper debug information for them. */
7172 gnu_result = alloc_stmt_list ();
7173 break;
7174
7175 /*************************************/
7176 /* Chapter 4: Names and Expressions */
7177 /*************************************/
7178
7179 case N_Explicit_Dereference:
7180 /* Make sure the designated type is complete before dereferencing. */
7181 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7182 gnu_result = gnat_to_gnu (Prefix (gnat_node));
7183 gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
7184
7185 /* If atomic access is required on the RHS, build the atomic load. */
7186 if (simple_atomic_access_required_p (gnat_node, &aa_sync)
7187 && !present_in_lhs_or_actual_p (gnat_node))
7188 gnu_result = build_atomic_load (gnu_result, aa_sync);
7189 break;
7190
7191 case N_Indexed_Component:
7192 {
7193 tree gnu_array_object
7194 = gnat_to_gnu (adjust_for_implicit_deref (Prefix (gnat_node)));
7195 tree gnu_type;
7196 int ndim;
7197 int i;
7198 Node_Id *gnat_expr_array;
7199
7200 gnu_array_object = maybe_implicit_deref (gnu_array_object);
7201
7202 /* Convert vector inputs to their representative array type, to fit
7203 what the code below expects. */
7204 if (VECTOR_TYPE_P (TREE_TYPE (gnu_array_object)))
7205 {
7206 if (present_in_lhs_or_actual_p (gnat_node))
7207 gnat_mark_addressable (gnu_array_object);
7208 gnu_array_object = maybe_vector_array (gnu_array_object);
7209 }
7210
7211 gnu_array_object = maybe_unconstrained_array (gnu_array_object);
7212
7213 /* If we got a padded type, remove it too. */
7214 if (TYPE_IS_PADDING_P (TREE_TYPE (gnu_array_object)))
7215 gnu_array_object
7216 = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_array_object))),
7217 gnu_array_object);
7218
7219 /* The failure of this assertion will very likely come from a missing
7220 expansion for a packed array access. */
7221 gcc_assert (TREE_CODE (TREE_TYPE (gnu_array_object)) == ARRAY_TYPE);
7222
7223 /* First compute the number of dimensions of the array, then
7224 fill the expression array, the order depending on whether
7225 this is a Convention_Fortran array or not. */
7226 for (ndim = 1, gnu_type = TREE_TYPE (gnu_array_object);
7227 TREE_CODE (TREE_TYPE (gnu_type)) == ARRAY_TYPE
7228 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type));
7229 ndim++, gnu_type = TREE_TYPE (gnu_type))
7230 ;
7231
7232 gnat_expr_array = XALLOCAVEC (Node_Id, ndim);
7233
7234 if (TYPE_CONVENTION_FORTRAN_P (TREE_TYPE (gnu_array_object)))
7235 for (i = ndim - 1, gnat_temp = First (Expressions (gnat_node));
7236 i >= 0;
7237 i--, gnat_temp = Next (gnat_temp))
7238 gnat_expr_array[i] = gnat_temp;
7239 else
7240 for (i = 0, gnat_temp = First (Expressions (gnat_node));
7241 i < ndim;
7242 i++, gnat_temp = Next (gnat_temp))
7243 gnat_expr_array[i] = gnat_temp;
7244
7245 /* Start with the prefix and build the successive references. */
7246 gnu_result = gnu_array_object;
7247
7248 for (i = 0, gnu_type = TREE_TYPE (gnu_array_object);
7249 i < ndim;
7250 i++, gnu_type = TREE_TYPE (gnu_type))
7251 {
7252 gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);
7253 gnat_temp = gnat_expr_array[i];
7254 gnu_expr = maybe_character_value (gnat_to_gnu (gnat_temp));
7255
7256 gnu_result
7257 = build_binary_op (ARRAY_REF, NULL_TREE, gnu_result, gnu_expr);
7258 }
7259
7260 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7261
7262 /* If atomic access is required on the RHS, build the atomic load. */
7263 if (simple_atomic_access_required_p (gnat_node, &aa_sync)
7264 && !present_in_lhs_or_actual_p (gnat_node))
7265 gnu_result = build_atomic_load (gnu_result, aa_sync);
7266 }
7267 break;
7268
7269 case N_Slice:
7270 {
7271 tree gnu_array_object
7272 = gnat_to_gnu (adjust_for_implicit_deref (Prefix (gnat_node)));
7273
7274 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7275
7276 gnu_array_object = maybe_implicit_deref (gnu_array_object);
7277 gnu_array_object = maybe_unconstrained_array (gnu_array_object);
7278
7279 gnu_expr = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_result_type));
7280 gnu_expr = maybe_character_value (gnu_expr);
7281
7282 /* If this is a slice with non-constant size of an array with constant
7283 size, set the maximum size for the allocation of temporaries. */
7284 if (!TREE_CONSTANT (TYPE_SIZE_UNIT (gnu_result_type))
7285 && TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (gnu_array_object))))
7286 TYPE_ARRAY_MAX_SIZE (gnu_result_type)
7287 = TYPE_SIZE_UNIT (TREE_TYPE (gnu_array_object));
7288
7289 gnu_result = build_binary_op (ARRAY_RANGE_REF, gnu_result_type,
7290 gnu_array_object, gnu_expr);
7291 }
7292 break;
7293
7294 case N_Selected_Component:
7295 {
7296 Entity_Id gnat_prefix
7297 = adjust_for_implicit_deref (Prefix (gnat_node));
7298 Entity_Id gnat_field = Entity (Selector_Name (gnat_node));
7299 tree gnu_prefix = gnat_to_gnu (gnat_prefix);
7300
7301 gnu_prefix = maybe_implicit_deref (gnu_prefix);
7302
7303 /* gnat_to_gnu_entity does not save the GNU tree made for renamed
7304 discriminants so avoid making recursive calls on each reference
7305 to them by following the appropriate link directly here. */
7306 if (Ekind (gnat_field) == E_Discriminant)
7307 {
7308 /* For discriminant references in tagged types always substitute
7309 the corresponding discriminant as the actual component. */
7310 if (Is_Tagged_Type (Underlying_Type (Etype (gnat_prefix))))
7311 while (Present (Corresponding_Discriminant (gnat_field)))
7312 gnat_field = Corresponding_Discriminant (gnat_field);
7313
7314 /* For discriminant references in untagged types always substitute
7315 the corresponding stored discriminant. */
7316 else if (Present (Corresponding_Discriminant (gnat_field)))
7317 gnat_field = Original_Record_Component (gnat_field);
7318 }
7319
7320 /* Handle extracting the real or imaginary part of a complex.
7321 The real part is the first field and the imaginary the last. */
7322 if (TREE_CODE (TREE_TYPE (gnu_prefix)) == COMPLEX_TYPE)
7323 gnu_result = build_unary_op (Present (Next_Entity (gnat_field))
7324 ? REALPART_EXPR : IMAGPART_EXPR,
7325 NULL_TREE, gnu_prefix);
7326 else
7327 {
7328 tree gnu_field = gnat_to_gnu_field_decl (gnat_field);
7329
7330 gnu_result
7331 = build_component_ref (gnu_prefix, gnu_field,
7332 (Nkind (Parent (gnat_node))
7333 == N_Attribute_Reference)
7334 && lvalue_required_for_attribute_p
7335 (Parent (gnat_node)));
7336 }
7337
7338 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7339
7340 /* If atomic access is required on the RHS, build the atomic load. */
7341 if (simple_atomic_access_required_p (gnat_node, &aa_sync)
7342 && !present_in_lhs_or_actual_p (gnat_node))
7343 gnu_result = build_atomic_load (gnu_result, aa_sync);
7344 }
7345 break;
7346
7347 case N_Attribute_Reference:
7348 {
7349 /* The attribute designator. */
7350 const int attr = Get_Attribute_Id (Attribute_Name (gnat_node));
7351
7352 /* The Elab_Spec and Elab_Body attributes are special in that Prefix
7353 is a unit, not an object with a GCC equivalent. */
7354 if (attr == Attr_Elab_Spec || attr == Attr_Elab_Body)
7355 return
7356 create_subprog_decl (create_concat_name
7357 (Entity (Prefix (gnat_node)),
7358 attr == Attr_Elab_Body ? "elabb" : "elabs"),
7359 NULL_TREE, void_ftype, NULL_TREE, is_default,
7360 true, true, true, true, false, NULL,
7361 gnat_node);
7362
7363 gnu_result = Attribute_to_gnu (gnat_node, &gnu_result_type, attr);
7364 }
7365 break;
7366
7367 case N_Reference:
7368 /* Like 'Access as far as we are concerned. */
7369 gnu_result = gnat_to_gnu (Prefix (gnat_node));
7370 gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_result);
7371 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7372 break;
7373
7374 case N_Aggregate:
7375 case N_Extension_Aggregate:
7376 {
7377 tree gnu_aggr_type;
7378
7379 /* Check that this aggregate has not slipped through the cracks. */
7380 gcc_assert (!Expansion_Delayed (gnat_node));
7381
7382 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7383
7384 if (TREE_CODE (gnu_result_type) == RECORD_TYPE
7385 && TYPE_CONTAINS_TEMPLATE_P (gnu_result_type))
7386 gnu_aggr_type
7387 = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_result_type)));
7388 else if (TREE_CODE (gnu_result_type) == VECTOR_TYPE)
7389 gnu_aggr_type = TYPE_REPRESENTATIVE_ARRAY (gnu_result_type);
7390 else
7391 gnu_aggr_type = gnu_result_type;
7392
7393 if (Null_Record_Present (gnat_node))
7394 gnu_result = gnat_build_constructor (gnu_aggr_type, NULL);
7395
7396 else if (TREE_CODE (gnu_aggr_type) == RECORD_TYPE
7397 || TREE_CODE (gnu_aggr_type) == UNION_TYPE)
7398 gnu_result
7399 = assoc_to_constructor (Etype (gnat_node),
7400 First (Component_Associations (gnat_node)),
7401 gnu_aggr_type);
7402 else if (TREE_CODE (gnu_aggr_type) == ARRAY_TYPE)
7403 gnu_result = pos_to_constructor (First (Expressions (gnat_node)),
7404 gnu_aggr_type);
7405 else if (TREE_CODE (gnu_aggr_type) == COMPLEX_TYPE)
7406 gnu_result
7407 = build_binary_op
7408 (COMPLEX_EXPR, gnu_aggr_type,
7409 gnat_to_gnu (Expression (First
7410 (Component_Associations (gnat_node)))),
7411 gnat_to_gnu (Expression
7412 (Next
7413 (First (Component_Associations (gnat_node))))));
7414 else
7415 gcc_unreachable ();
7416
7417 gnu_result = convert (gnu_result_type, gnu_result);
7418 }
7419 break;
7420
7421 case N_Null:
7422 if (TARGET_VTABLE_USES_DESCRIPTORS
7423 && Ekind (Etype (gnat_node)) == E_Access_Subprogram_Type
7424 && Is_Dispatch_Table_Entity (Etype (gnat_node)))
7425 gnu_result = null_fdesc_node;
7426 else
7427 gnu_result = null_pointer_node;
7428 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7429 break;
7430
7431 case N_Type_Conversion:
7432 case N_Qualified_Expression:
7433 gnu_expr = maybe_character_value (gnat_to_gnu (Expression (gnat_node)));
7434 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7435
7436 /* If this is a qualified expression for a tagged type, we mark the type
7437 as used. Because of polymorphism, this might be the only reference to
7438 the tagged type in the program while objects have it as dynamic type.
7439 The debugger needs to see it to display these objects properly. */
7440 if (kind == N_Qualified_Expression && Is_Tagged_Type (Etype (gnat_node)))
7441 used_types_insert (gnu_result_type);
7442
7443 gigi_checking_assert (!Do_Range_Check (Expression (gnat_node)));
7444
7445 gnu_result
7446 = convert_with_check (Etype (gnat_node), gnu_expr,
7447 Do_Overflow_Check (gnat_node),
7448 kind == N_Type_Conversion
7449 && Float_Truncate (gnat_node), gnat_node);
7450 break;
7451
7452 case N_Unchecked_Type_Conversion:
7453 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7454 gnu_expr = maybe_character_value (gnat_to_gnu (Expression (gnat_node)));
7455
7456 /* Skip further processing if the conversion is deemed a no-op. */
7457 if (unchecked_conversion_nop (gnat_node))
7458 {
7459 gnu_result = gnu_expr;
7460 gnu_result_type = TREE_TYPE (gnu_result);
7461 break;
7462 }
7463
7464 /* If the result is a pointer type, see if we are improperly
7465 converting to a stricter alignment. */
7466 if (STRICT_ALIGNMENT && POINTER_TYPE_P (gnu_result_type)
7467 && Is_Access_Type (Etype (gnat_node)))
7468 {
7469 unsigned int align = known_alignment (gnu_expr);
7470 tree gnu_obj_type = TREE_TYPE (gnu_result_type);
7471 unsigned int oalign = TYPE_ALIGN (gnu_obj_type);
7472
7473 if (align != 0 && align < oalign && !TYPE_ALIGN_OK (gnu_obj_type))
7474 post_error_ne_tree_2
7475 ("?source alignment (^) '< alignment of & (^)",
7476 gnat_node, Designated_Type (Etype (gnat_node)),
7477 size_int (align / BITS_PER_UNIT), oalign / BITS_PER_UNIT);
7478 }
7479
7480 /* If we are converting a descriptor to a function pointer, first
7481 build the pointer. */
7482 if (TARGET_VTABLE_USES_DESCRIPTORS
7483 && TREE_TYPE (gnu_expr) == fdesc_type_node
7484 && POINTER_TYPE_P (gnu_result_type))
7485 gnu_expr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);
7486
7487 gnu_result = unchecked_convert (gnu_result_type, gnu_expr,
7488 No_Truncation (gnat_node));
7489 break;
7490
7491 case N_In:
7492 case N_Not_In:
7493 {
7494 tree gnu_obj = gnat_to_gnu (Left_Opnd (gnat_node));
7495 tree gnu_low, gnu_high;
7496
7497 Range_to_gnu (Right_Opnd (gnat_node), &gnu_low, &gnu_high);
7498 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7499
7500 tree gnu_op_type = maybe_character_type (TREE_TYPE (gnu_obj));
7501 if (TREE_TYPE (gnu_obj) != gnu_op_type)
7502 {
7503 gnu_obj = convert (gnu_op_type, gnu_obj);
7504 gnu_low = convert (gnu_op_type, gnu_low);
7505 gnu_high = convert (gnu_op_type, gnu_high);
7506 }
7507
7508 /* If LOW and HIGH are identical, perform an equality test. Otherwise,
7509 ensure that GNU_OBJ is evaluated only once and perform a full range
7510 test. */
7511 if (operand_equal_p (gnu_low, gnu_high, 0))
7512 gnu_result
7513 = build_binary_op (EQ_EXPR, gnu_result_type, gnu_obj, gnu_low);
7514 else
7515 {
7516 tree t1, t2;
7517 gnu_obj = gnat_protect_expr (gnu_obj);
7518 t1 = build_binary_op (GE_EXPR, gnu_result_type, gnu_obj, gnu_low);
7519 if (EXPR_P (t1))
7520 set_expr_location_from_node (t1, gnat_node);
7521 t2 = build_binary_op (LE_EXPR, gnu_result_type, gnu_obj, gnu_high);
7522 if (EXPR_P (t2))
7523 set_expr_location_from_node (t2, gnat_node);
7524 gnu_result
7525 = build_binary_op (TRUTH_ANDIF_EXPR, gnu_result_type, t1, t2);
7526 }
7527
7528 if (kind == N_Not_In)
7529 gnu_result
7530 = invert_truthvalue_loc (EXPR_LOCATION (gnu_result), gnu_result);
7531 }
7532 break;
7533
7534 case N_Op_Divide:
7535 gnu_lhs = gnat_to_gnu (Left_Opnd (gnat_node));
7536 gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node));
7537 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7538 gnu_result = build_binary_op (FLOAT_TYPE_P (gnu_result_type)
7539 ? RDIV_EXPR
7540 : (Rounded_Result (gnat_node)
7541 ? ROUND_DIV_EXPR : TRUNC_DIV_EXPR),
7542 gnu_result_type, gnu_lhs, gnu_rhs);
7543 break;
7544
7545 case N_Op_Eq:
7546 case N_Op_Ne:
7547 case N_Op_Lt:
7548 case N_Op_Le:
7549 case N_Op_Gt:
7550 case N_Op_Ge:
7551 case N_Op_Add:
7552 case N_Op_Subtract:
7553 case N_Op_Multiply:
7554 case N_Op_Mod:
7555 case N_Op_Rem:
7556 case N_Op_Rotate_Left:
7557 case N_Op_Rotate_Right:
7558 case N_Op_Shift_Left:
7559 case N_Op_Shift_Right:
7560 case N_Op_Shift_Right_Arithmetic:
7561 case N_Op_And:
7562 case N_Op_Or:
7563 case N_Op_Xor:
7564 case N_And_Then:
7565 case N_Or_Else:
7566 {
7567 enum tree_code code = gnu_codes[kind];
7568 bool ignore_lhs_overflow = false;
7569 location_t saved_location = input_location;
7570 tree gnu_type, gnu_max_shift = NULL_TREE;
7571
7572 /* Fix operations set up for boolean types in GNU_CODES above. */
7573 if (Is_Modular_Integer_Type (Underlying_Type (Etype (gnat_node))))
7574 switch (kind)
7575 {
7576 case N_Op_And:
7577 code = BIT_AND_EXPR;
7578 break;
7579 case N_Op_Or:
7580 code = BIT_IOR_EXPR;
7581 break;
7582 case N_Op_Xor:
7583 code = BIT_XOR_EXPR;
7584 break;
7585 default:
7586 break;
7587 }
7588
7589 gnu_lhs = gnat_to_gnu (Left_Opnd (gnat_node));
7590 gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node));
7591 gnu_type = gnu_result_type = get_unpadded_type (Etype (gnat_node));
7592
7593 /* If this is a shift, take the count as unsigned since that is what
7594 most machines do and will generate simpler adjustments below. */
7595 if (IN (kind, N_Op_Shift))
7596 {
7597 tree gnu_count_type
7598 = gnat_unsigned_type_for (get_base_type (TREE_TYPE (gnu_rhs)));
7599 gnu_rhs = convert (gnu_count_type, gnu_rhs);
7600 gnu_max_shift
7601 = convert (TREE_TYPE (gnu_rhs), TYPE_SIZE (gnu_type));
7602 }
7603
7604 /* Pending generic support for efficient vector logical operations in
7605 GCC, convert vectors to their representative array type view and
7606 fallthrough. */
7607 gnu_lhs = maybe_vector_array (gnu_lhs);
7608 gnu_rhs = maybe_vector_array (gnu_rhs);
7609
7610 /* If this is a comparison operator, convert any references to an
7611 unconstrained array value into a reference to the actual array. */
7612 if (TREE_CODE_CLASS (code) == tcc_comparison)
7613 {
7614 gnu_lhs = maybe_unconstrained_array (gnu_lhs);
7615 gnu_rhs = maybe_unconstrained_array (gnu_rhs);
7616
7617 tree gnu_op_type = maybe_character_type (TREE_TYPE (gnu_lhs));
7618 if (TREE_TYPE (gnu_lhs) != gnu_op_type)
7619 {
7620 gnu_lhs = convert (gnu_op_type, gnu_lhs);
7621 gnu_rhs = convert (gnu_op_type, gnu_rhs);
7622 }
7623 }
7624
7625 /* If this is a shift whose count is not guaranteed to be correct,
7626 we need to adjust the shift count. */
7627 if ((kind == N_Op_Rotate_Left || kind == N_Op_Rotate_Right)
7628 && !Shift_Count_OK (gnat_node))
7629 gnu_rhs = build_binary_op (TRUNC_MOD_EXPR, TREE_TYPE (gnu_rhs),
7630 gnu_rhs, gnu_max_shift);
7631 else if (kind == N_Op_Shift_Right_Arithmetic
7632 && !Shift_Count_OK (gnat_node))
7633 gnu_rhs
7634 = build_binary_op (MIN_EXPR, TREE_TYPE (gnu_rhs),
7635 build_binary_op (MINUS_EXPR,
7636 TREE_TYPE (gnu_rhs),
7637 gnu_max_shift,
7638 build_int_cst
7639 (TREE_TYPE (gnu_rhs), 1)),
7640 gnu_rhs);
7641
7642 /* For right shifts, the type says what kind of shift to do,
7643 so we may need to choose a different type. In this case,
7644 we have to ignore integer overflow lest it propagates all
7645 the way down and causes a CE to be explicitly raised. */
7646 if (kind == N_Op_Shift_Right && !TYPE_UNSIGNED (gnu_type))
7647 {
7648 gnu_type = gnat_unsigned_type_for (gnu_type);
7649 ignore_lhs_overflow = true;
7650 }
7651 else if (kind == N_Op_Shift_Right_Arithmetic
7652 && TYPE_UNSIGNED (gnu_type))
7653 {
7654 gnu_type = gnat_signed_type_for (gnu_type);
7655 ignore_lhs_overflow = true;
7656 }
7657
7658 if (gnu_type != gnu_result_type)
7659 {
7660 tree gnu_old_lhs = gnu_lhs;
7661 gnu_lhs = convert (gnu_type, gnu_lhs);
7662 if (TREE_CODE (gnu_lhs) == INTEGER_CST && ignore_lhs_overflow)
7663 TREE_OVERFLOW (gnu_lhs) = TREE_OVERFLOW (gnu_old_lhs);
7664 gnu_rhs = convert (gnu_type, gnu_rhs);
7665 }
7666
7667 /* For signed integer addition, subtraction and multiplication, do an
7668 overflow check if required. */
7669 if (Do_Overflow_Check (gnat_node)
7670 && (code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR)
7671 && !TYPE_UNSIGNED (gnu_type)
7672 && !FLOAT_TYPE_P (gnu_type))
7673 gnu_result
7674 = build_binary_op_trapv (code, gnu_type, gnu_lhs, gnu_rhs,
7675 gnat_node);
7676 else
7677 {
7678 /* Some operations, e.g. comparisons of arrays, generate complex
7679 trees that need to be annotated while they are being built. */
7680 input_location = saved_location;
7681 gnu_result = build_binary_op (code, gnu_type, gnu_lhs, gnu_rhs);
7682 }
7683
7684 /* If this is a logical shift with the shift count not verified,
7685 we must return zero if it is too large. We cannot compensate
7686 beforehand in this case. */
7687 if ((kind == N_Op_Shift_Left || kind == N_Op_Shift_Right)
7688 && !Shift_Count_OK (gnat_node))
7689 gnu_result
7690 = build_cond_expr (gnu_type,
7691 build_binary_op (GE_EXPR, boolean_type_node,
7692 gnu_rhs, gnu_max_shift),
7693 build_int_cst (gnu_type, 0),
7694 gnu_result);
7695 }
7696 break;
7697
7698 case N_If_Expression:
7699 {
7700 tree gnu_cond = gnat_to_gnu (First (Expressions (gnat_node)));
7701 tree gnu_true = gnat_to_gnu (Next (First (Expressions (gnat_node))));
7702 tree gnu_false
7703 = gnat_to_gnu (Next (Next (First (Expressions (gnat_node)))));
7704
7705 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7706 gnu_result
7707 = build_cond_expr (gnu_result_type, gnu_cond, gnu_true, gnu_false);
7708 }
7709 break;
7710
7711 case N_Op_Plus:
7712 gnu_result = gnat_to_gnu (Right_Opnd (gnat_node));
7713 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7714 break;
7715
7716 case N_Op_Not:
7717 /* This case can apply to a boolean or a modular type.
7718 Fall through for a boolean operand since GNU_CODES is set
7719 up to handle this. */
7720 if (Is_Modular_Integer_Type (Underlying_Type (Etype (gnat_node))))
7721 {
7722 gnu_expr = gnat_to_gnu (Right_Opnd (gnat_node));
7723 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7724 gnu_result = build_unary_op (BIT_NOT_EXPR, gnu_result_type,
7725 gnu_expr);
7726 break;
7727 }
7728
7729 /* ... fall through ... */
7730
7731 case N_Op_Minus:
7732 case N_Op_Abs:
7733 gnu_expr = gnat_to_gnu (Right_Opnd (gnat_node));
7734 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7735
7736 /* For signed integer negation and absolute value, do an overflow check
7737 if required. */
7738 if (Do_Overflow_Check (gnat_node)
7739 && !TYPE_UNSIGNED (gnu_result_type)
7740 && !FLOAT_TYPE_P (gnu_result_type))
7741 gnu_result
7742 = build_unary_op_trapv (gnu_codes[kind], gnu_result_type, gnu_expr,
7743 gnat_node);
7744 else
7745 gnu_result
7746 = build_unary_op (gnu_codes[kind], gnu_result_type, gnu_expr);
7747 break;
7748
7749 case N_Allocator:
7750 {
7751 tree gnu_type, gnu_init;
7752 bool ignore_init_type;
7753
7754 gnat_temp = Expression (gnat_node);
7755
7756 /* The expression can be either an N_Identifier or an Expanded_Name,
7757 which must represent a type, or a N_Qualified_Expression, which
7758 contains both the type and an initial value for the object. */
7759 if (Nkind (gnat_temp) == N_Identifier
7760 || Nkind (gnat_temp) == N_Expanded_Name)
7761 {
7762 ignore_init_type = false;
7763 gnu_init = NULL_TREE;
7764 gnu_type = gnat_to_gnu_type (Entity (gnat_temp));
7765 }
7766
7767 else if (Nkind (gnat_temp) == N_Qualified_Expression)
7768 {
7769 Entity_Id gnat_desig_type
7770 = Designated_Type (Underlying_Type (Etype (gnat_node)));
7771
7772 /* The flag is effectively only set on the base types. */
7773 ignore_init_type
7774 = Has_Constrained_Partial_View (Base_Type (gnat_desig_type));
7775
7776 gnu_init = gnat_to_gnu (Expression (gnat_temp));
7777 gnu_init = maybe_unconstrained_array (gnu_init);
7778
7779 gigi_checking_assert (!Do_Range_Check (Expression (gnat_temp)));
7780
7781 if (Is_Elementary_Type (gnat_desig_type)
7782 || Is_Constrained (gnat_desig_type))
7783 gnu_type = gnat_to_gnu_type (gnat_desig_type);
7784 else
7785 {
7786 gnu_type = gnat_to_gnu_type (Etype (Expression (gnat_temp)));
7787 if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
7788 gnu_type = TREE_TYPE (gnu_init);
7789 }
7790
7791 /* See the N_Qualified_Expression case for the rationale. */
7792 if (Is_Tagged_Type (gnat_desig_type))
7793 used_types_insert (gnu_type);
7794
7795 gnu_init = convert (gnu_type, gnu_init);
7796 }
7797 else
7798 gcc_unreachable ();
7799
7800 gnu_result_type = get_unpadded_type (Etype (gnat_node));
7801 return build_allocator (gnu_type, gnu_init, gnu_result_type,
7802 Procedure_To_Call (gnat_node),
7803 Storage_Pool (gnat_node), gnat_node,
7804 ignore_init_type);
7805 }
7806 break;
7807
7808 /**************************/
7809 /* Chapter 5: Statements */
7810 /**************************/
7811
7812 case N_Label:
7813 gnu_result = build1 (LABEL_EXPR, void_type_node,
7814 gnat_to_gnu (Identifier (gnat_node)));
7815 break;
7816
7817 case N_Null_Statement:
7818 /* When not optimizing, turn null statements from source into gotos to
7819 the next statement that the middle-end knows how to preserve. */
7820 if (!optimize && Comes_From_Source (gnat_node))
7821 {
7822 tree stmt, label = create_label_decl (NULL_TREE, gnat_node);
7823 DECL_IGNORED_P (label) = 1;
7824 start_stmt_group ();
7825 stmt = build1 (GOTO_EXPR, void_type_node, label);
7826 set_expr_location_from_node (stmt, gnat_node);
7827 add_stmt (stmt);
7828 stmt = build1 (LABEL_EXPR, void_type_node, label);
7829 set_expr_location_from_node (stmt, gnat_node);
7830 add_stmt (stmt);
7831 gnu_result = end_stmt_group ();
7832 }
7833 else
7834 gnu_result = alloc_stmt_list ();
7835 break;
7836
7837 case N_Assignment_Statement:
7838 /* Get the LHS and RHS of the statement and convert any reference to an
7839 unconstrained array into a reference to the underlying array. */
7840 gnu_lhs = maybe_unconstrained_array (gnat_to_gnu (Name (gnat_node)));
7841
7842 /* If the type has a size that overflows, convert this into raise of
7843 Storage_Error: execution shouldn't have gotten here anyway. */
7844 if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs))) == INTEGER_CST
7845 && !valid_constant_size_p (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs))))
7846 gnu_result = build_call_raise (SE_Object_Too_Large, gnat_node,
7847 N_Raise_Storage_Error);
7848 else if (Nkind (Expression (gnat_node)) == N_Function_Call)
7849 {
7850 get_atomic_access (Name (gnat_node), &aa_type, &aa_sync);
7851 gnu_result
7852 = Call_to_gnu (Expression (gnat_node), &gnu_result_type, gnu_lhs,
7853 aa_type, aa_sync);
7854 }
7855 else
7856 {
7857 const Node_Id gnat_expr = Expression (gnat_node);
7858 const Entity_Id gnat_type
7859 = Underlying_Type (Etype (Name (gnat_node)));
7860 const bool regular_array_type_p
7861 = (Is_Array_Type (gnat_type) && !Is_Bit_Packed_Array (gnat_type));
7862 const bool use_memset_p
7863 = (regular_array_type_p
7864 && Nkind (gnat_expr) == N_Aggregate
7865 && Is_Others_Aggregate (gnat_expr));
7866
7867 /* If we'll use memset, we need to find the inner expression. */
7868 if (use_memset_p)
7869 {
7870 Node_Id gnat_inner
7871 = Expression (First (Component_Associations (gnat_expr)));
7872 while (Nkind (gnat_inner) == N_Aggregate
7873 && Is_Others_Aggregate (gnat_inner))
7874 gnat_inner
7875 = Expression (First (Component_Associations (gnat_inner)));
7876 gnu_rhs = gnat_to_gnu (gnat_inner);
7877 }
7878 else
7879 gnu_rhs = maybe_unconstrained_array (gnat_to_gnu (gnat_expr));
7880
7881 gigi_checking_assert (!Do_Range_Check (gnat_expr));
7882
7883 get_atomic_access (Name (gnat_node), &aa_type, &aa_sync);
7884
7885 /* If an outer atomic access is required on the LHS, build the load-
7886 modify-store sequence. */
7887 if (aa_type == OUTER_ATOMIC)
7888 gnu_result = build_load_modify_store (gnu_lhs, gnu_rhs, gnat_node);
7889
7890 /* Or else, if a simple atomic access is required, build the atomic
7891 store. */
7892 else if (aa_type == SIMPLE_ATOMIC)
7893 gnu_result = build_atomic_store (gnu_lhs, gnu_rhs, aa_sync);
7894
7895 /* Or else, use memset when the conditions are met. This has already
7896 been validated by Aggr_Assignment_OK_For_Backend in the front-end
7897 and the RHS is thus guaranteed to be of the appropriate form. */
7898 else if (use_memset_p)
7899 {
7900 tree value
7901 = real_zerop (gnu_rhs)
7902 ? integer_zero_node
7903 : fold_convert (integer_type_node, gnu_rhs);
7904 tree dest = build_fold_addr_expr (gnu_lhs);
7905 tree t = builtin_decl_explicit (BUILT_IN_MEMSET);
7906 /* Be extra careful not to write too much data. */
7907 tree size;
7908 if (TREE_CODE (gnu_lhs) == COMPONENT_REF)
7909 size = DECL_SIZE_UNIT (TREE_OPERAND (gnu_lhs, 1));
7910 else if (DECL_P (gnu_lhs))
7911 size = DECL_SIZE_UNIT (gnu_lhs);
7912 else
7913 size = TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs));
7914 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, gnu_lhs);
7915 if (TREE_CODE (value) == INTEGER_CST && !integer_zerop (value))
7916 {
7917 tree mask
7918 = build_int_cst (integer_type_node,
7919 ((HOST_WIDE_INT) 1 << BITS_PER_UNIT) - 1);
7920 value = int_const_binop (BIT_AND_EXPR, value, mask);
7921 }
7922 gnu_result = build_call_expr (t, 3, dest, value, size);
7923 }
7924
7925 /* Otherwise build a regular assignment. */
7926 else
7927 gnu_result
7928 = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_lhs, gnu_rhs);
7929
7930 /* If the assignment type is a regular array and the two sides are
7931 not completely disjoint, play safe and use memmove. But don't do
7932 it for a bit-packed array as it might not be byte-aligned. */
7933 if (TREE_CODE (gnu_result) == MODIFY_EXPR
7934 && regular_array_type_p
7935 && !(Forwards_OK (gnat_node) && Backwards_OK (gnat_node)))
7936 {
7937 tree to = TREE_OPERAND (gnu_result, 0);
7938 tree from = TREE_OPERAND (gnu_result, 1);
7939 tree type = TREE_TYPE (from);
7940 tree size
7941 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (type), from);
7942 tree to_ptr = build_fold_addr_expr (to);
7943 tree from_ptr = build_fold_addr_expr (from);
7944 tree t = builtin_decl_explicit (BUILT_IN_MEMMOVE);
7945 gnu_result = build_call_expr (t, 3, to_ptr, from_ptr, size);
7946 }
7947 }
7948 break;
7949
7950 case N_If_Statement:
7951 {
7952 tree *gnu_else_ptr; /* Point to put next "else if" or "else". */
7953
7954 /* Make the outer COND_EXPR. Avoid non-determinism. */
7955 gnu_result = build3 (COND_EXPR, void_type_node,
7956 gnat_to_gnu (Condition (gnat_node)),
7957 NULL_TREE, NULL_TREE);
7958 COND_EXPR_THEN (gnu_result)
7959 = build_stmt_group (Then_Statements (gnat_node), false);
7960 TREE_SIDE_EFFECTS (gnu_result) = 1;
7961 gnu_else_ptr = &COND_EXPR_ELSE (gnu_result);
7962
7963 /* Now make a COND_EXPR for each of the "else if" parts. Put each
7964 into the previous "else" part and point to where to put any
7965 outer "else". Also avoid non-determinism. */
7966 if (Present (Elsif_Parts (gnat_node)))
7967 for (gnat_temp = First (Elsif_Parts (gnat_node));
7968 Present (gnat_temp); gnat_temp = Next (gnat_temp))
7969 {
7970 gnu_expr = build3 (COND_EXPR, void_type_node,
7971 gnat_to_gnu (Condition (gnat_temp)),
7972 NULL_TREE, NULL_TREE);
7973 COND_EXPR_THEN (gnu_expr)
7974 = build_stmt_group (Then_Statements (gnat_temp), false);
7975 TREE_SIDE_EFFECTS (gnu_expr) = 1;
7976 set_expr_location_from_node (gnu_expr, gnat_temp);
7977 *gnu_else_ptr = gnu_expr;
7978 gnu_else_ptr = &COND_EXPR_ELSE (gnu_expr);
7979 }
7980
7981 *gnu_else_ptr = build_stmt_group (Else_Statements (gnat_node), false);
7982 }
7983 break;
7984
7985 case N_Case_Statement:
7986 gnu_result = Case_Statement_to_gnu (gnat_node);
7987 break;
7988
7989 case N_Loop_Statement:
7990 gnu_result = Loop_Statement_to_gnu (gnat_node);
7991 break;
7992
7993 case N_Block_Statement:
7994 /* The only way to enter the block is to fall through to it. */
7995 if (stmt_group_may_fallthru ())
7996 {
7997 start_stmt_group ();
7998 gnat_pushlevel ();
7999 process_decls (Declarations (gnat_node), Empty, Empty, true, true);
8000 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));
8001 gnat_poplevel ();
8002 gnu_result = end_stmt_group ();
8003 }
8004 else
8005 gnu_result = alloc_stmt_list ();
8006 break;
8007
8008 case N_Exit_Statement:
8009 gnu_result
8010 = build2 (EXIT_STMT, void_type_node,
8011 (Present (Condition (gnat_node))
8012 ? gnat_to_gnu (Condition (gnat_node)) : NULL_TREE),
8013 (Present (Name (gnat_node))
8014 ? get_gnu_tree (Entity (Name (gnat_node)))
8015 : LOOP_STMT_LABEL (gnu_loop_stack->last ()->stmt)));
8016 break;
8017
8018 case N_Simple_Return_Statement:
8019 {
8020 tree gnu_ret_obj, gnu_ret_val;
8021
8022 /* If the subprogram is a function, we must return the expression. */
8023 if (Present (Expression (gnat_node)))
8024 {
8025 tree gnu_subprog_type = TREE_TYPE (current_function_decl);
8026
8027 /* If this function has copy-in/copy-out parameters parameters and
8028 doesn't return by invisible reference, get the real object for
8029 the return. See Subprogram_Body_to_gnu. */
8030 if (TYPE_CI_CO_LIST (gnu_subprog_type)
8031 && !TREE_ADDRESSABLE (gnu_subprog_type))
8032 gnu_ret_obj = gnu_return_var_stack->last ();
8033 else
8034 gnu_ret_obj = DECL_RESULT (current_function_decl);
8035
8036 /* Get the GCC tree for the expression to be returned. */
8037 gnu_ret_val = gnat_to_gnu (Expression (gnat_node));
8038
8039 /* Do not remove the padding from GNU_RET_VAL if the inner type is
8040 self-referential since we want to allocate the fixed size. */
8041 if (TREE_CODE (gnu_ret_val) == COMPONENT_REF
8042 && type_is_padding_self_referential
8043 (TREE_TYPE (TREE_OPERAND (gnu_ret_val, 0))))
8044 gnu_ret_val = TREE_OPERAND (gnu_ret_val, 0);
8045
8046 /* If the function returns by direct reference, return a pointer
8047 to the return value. */
8048 if (TYPE_RETURN_BY_DIRECT_REF_P (gnu_subprog_type)
8049 || By_Ref (gnat_node))
8050 gnu_ret_val = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_ret_val);
8051
8052 /* Otherwise, if it returns an unconstrained array, we have to
8053 allocate a new version of the result and return it. */
8054 else if (TYPE_RETURN_UNCONSTRAINED_P (gnu_subprog_type))
8055 {
8056 gnu_ret_val = maybe_unconstrained_array (gnu_ret_val);
8057
8058 /* And find out whether this is a candidate for Named Return
8059 Value. If so, record it. */
8060 if (optimize
8061 && !optimize_debug
8062 && !TYPE_CI_CO_LIST (gnu_subprog_type))
8063 {
8064 tree ret_val = gnu_ret_val;
8065
8066 /* Strip useless conversions around the return value. */
8067 if (gnat_useless_type_conversion (ret_val))
8068 ret_val = TREE_OPERAND (ret_val, 0);
8069
8070 /* Strip unpadding around the return value. */
8071 if (TREE_CODE (ret_val) == COMPONENT_REF
8072 && TYPE_IS_PADDING_P
8073 (TREE_TYPE (TREE_OPERAND (ret_val, 0))))
8074 ret_val = TREE_OPERAND (ret_val, 0);
8075
8076 /* Now apply the test to the return value. */
8077 if (return_value_ok_for_nrv_p (NULL_TREE, ret_val))
8078 {
8079 if (!f_named_ret_val)
8080 f_named_ret_val = BITMAP_GGC_ALLOC ();
8081 bitmap_set_bit (f_named_ret_val, DECL_UID (ret_val));
8082 if (!f_gnat_ret)
8083 f_gnat_ret = gnat_node;
8084 }
8085 }
8086
8087 gnu_ret_val = build_allocator (TREE_TYPE (gnu_ret_val),
8088 gnu_ret_val,
8089 TREE_TYPE (gnu_ret_obj),
8090 Procedure_To_Call (gnat_node),
8091 Storage_Pool (gnat_node),
8092 gnat_node, false);
8093 }
8094
8095 /* Otherwise, if it returns by invisible reference, dereference
8096 the pointer it is passed using the type of the return value
8097 and build the copy operation manually. This ensures that we
8098 don't copy too much data, for example if the return type is
8099 unconstrained with a maximum size. */
8100 else if (TREE_ADDRESSABLE (gnu_subprog_type))
8101 {
8102 tree gnu_ret_deref
8103 = build_unary_op (INDIRECT_REF, TREE_TYPE (gnu_ret_val),
8104 gnu_ret_obj);
8105 gnu_result = build2 (INIT_EXPR, void_type_node,
8106 gnu_ret_deref, gnu_ret_val);
8107 add_stmt_with_node (gnu_result, gnat_node);
8108 gnu_ret_val = NULL_TREE;
8109 }
8110 }
8111
8112 else
8113 gnu_ret_obj = gnu_ret_val = NULL_TREE;
8114
8115 /* If we have a return label defined, convert this into a branch to
8116 that label. The return proper will be handled elsewhere. */
8117 if (gnu_return_label_stack->last ())
8118 {
8119 if (gnu_ret_val)
8120 add_stmt (build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_ret_obj,
8121 gnu_ret_val));
8122
8123 gnu_result = build1 (GOTO_EXPR, void_type_node,
8124 gnu_return_label_stack->last ());
8125
8126 /* When not optimizing, make sure the return is preserved. */
8127 if (!optimize && Comes_From_Source (gnat_node))
8128 DECL_ARTIFICIAL (gnu_return_label_stack->last ()) = 0;
8129 }
8130
8131 /* Otherwise, build a regular return. */
8132 else
8133 gnu_result = build_return_expr (gnu_ret_obj, gnu_ret_val);
8134 }
8135 break;
8136
8137 case N_Goto_Statement:
8138 gnu_expr = gnat_to_gnu (Name (gnat_node));
8139 gnu_result = build1 (GOTO_EXPR, void_type_node, gnu_expr);
8140 TREE_USED (gnu_expr) = 1;
8141 break;
8142
8143 /***************************/
8144 /* Chapter 6: Subprograms */
8145 /***************************/
8146
8147 case N_Subprogram_Declaration:
8148 /* Unless there is a freeze node, declare the entity. We consider
8149 this a definition even though we're not generating code for the
8150 subprogram because we will be making the corresponding GCC node.
8151 When there is a freeze node, it is considered the definition of
8152 the subprogram and we do nothing until after it is encountered.
8153 That's an efficiency issue: the types involved in the profile
8154 are far more likely to be frozen between the declaration and
8155 the freeze node than before the declaration, so we save some
8156 updates of the GCC node by waiting until the freeze node.
8157 The counterpart is that we assume that there is no reference
8158 to the subprogram between the declaration and the freeze node
8159 in the expanded code; otherwise, it will be interpreted as an
8160 external reference and very likely give rise to a link failure. */
8161 if (No (Freeze_Node (Defining_Entity (Specification (gnat_node)))))
8162 gnat_to_gnu_entity (Defining_Entity (Specification (gnat_node)),
8163 NULL_TREE, true);
8164 gnu_result = alloc_stmt_list ();
8165 break;
8166
8167 case N_Abstract_Subprogram_Declaration:
8168 /* This subprogram doesn't exist for code generation purposes, but we
8169 have to elaborate the types of any parameters and result, unless
8170 they are imported types (nothing to generate in this case).
8171
8172 The parameter list may contain types with freeze nodes, e.g. not null
8173 subtypes, so the subprogram itself may carry a freeze node, in which
8174 case its elaboration must be deferred. */
8175
8176 /* Process the parameter types first. */
8177 if (No (Freeze_Node (Defining_Entity (Specification (gnat_node)))))
8178 for (gnat_temp
8179 = First_Formal_With_Extras
8180 (Defining_Entity (Specification (gnat_node)));
8181 Present (gnat_temp);
8182 gnat_temp = Next_Formal_With_Extras (gnat_temp))
8183 if (Is_Itype (Etype (gnat_temp))
8184 && !From_Limited_With (Etype (gnat_temp)))
8185 gnat_to_gnu_entity (Etype (gnat_temp), NULL_TREE, false);
8186
8187 /* Then the result type, set to Standard_Void_Type for procedures. */
8188 {
8189 Entity_Id gnat_temp_type
8190 = Etype (Defining_Entity (Specification (gnat_node)));
8191
8192 if (Is_Itype (gnat_temp_type) && !From_Limited_With (gnat_temp_type))
8193 gnat_to_gnu_entity (Etype (gnat_temp_type), NULL_TREE, false);
8194 }
8195
8196 gnu_result = alloc_stmt_list ();
8197 break;
8198
8199 case N_Defining_Program_Unit_Name:
8200 /* For a child unit identifier go up a level to get the specification.
8201 We get this when we try to find the spec of a child unit package
8202 that is the compilation unit being compiled. */
8203 gnu_result = gnat_to_gnu (Parent (gnat_node));
8204 break;
8205
8206 case N_Subprogram_Body:
8207 Subprogram_Body_to_gnu (gnat_node);
8208 gnu_result = alloc_stmt_list ();
8209 break;
8210
8211 case N_Function_Call:
8212 case N_Procedure_Call_Statement:
8213 gnu_result = Call_to_gnu (gnat_node, &gnu_result_type, NULL_TREE,
8214 NOT_ATOMIC, false);
8215 break;
8216
8217 /************************/
8218 /* Chapter 7: Packages */
8219 /************************/
8220
8221 case N_Package_Declaration:
8222 gnu_result = gnat_to_gnu (Specification (gnat_node));
8223 break;
8224
8225 case N_Package_Specification:
8226
8227 start_stmt_group ();
8228 process_decls (Visible_Declarations (gnat_node),
8229 Private_Declarations (gnat_node), Empty, true, true);
8230 gnu_result = end_stmt_group ();
8231 break;
8232
8233 case N_Package_Body:
8234
8235 /* If this is the body of a generic package - do nothing. */
8236 if (Ekind (Corresponding_Spec (gnat_node)) == E_Generic_Package)
8237 {
8238 gnu_result = alloc_stmt_list ();
8239 break;
8240 }
8241
8242 start_stmt_group ();
8243 process_decls (Declarations (gnat_node), Empty, Empty, true, true);
8244
8245 if (Present (Handled_Statement_Sequence (gnat_node)))
8246 add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));
8247
8248 gnu_result = end_stmt_group ();
8249 break;
8250
8251 /********************************/
8252 /* Chapter 8: Visibility Rules */
8253 /********************************/
8254
8255 case N_Use_Package_Clause:
8256 case N_Use_Type_Clause:
8257 /* Nothing to do here - but these may appear in list of declarations. */
8258 gnu_result = alloc_stmt_list ();
8259 break;
8260
8261 /*********************/
8262 /* Chapter 9: Tasks */
8263 /*********************/
8264
8265 case N_Protected_Type_Declaration:
8266 gnu_result = alloc_stmt_list ();
8267 break;
8268
8269 case N_Single_Task_Declaration:
8270 gnat_to_gnu_entity (Defining_Entity (gnat_node), NULL_TREE, true);
8271 gnu_result = alloc_stmt_list ();
8272 break;
8273
8274 /*********************************************************/
8275 /* Chapter 10: Program Structure and Compilation Issues */
8276 /*********************************************************/
8277
8278 case N_Compilation_Unit:
8279 /* This is not called for the main unit on which gigi is invoked. */
8280 Compilation_Unit_to_gnu (gnat_node);
8281 gnu_result = alloc_stmt_list ();
8282 break;
8283
8284 case N_Subunit:
8285 gnu_result = gnat_to_gnu (Proper_Body (gnat_node));
8286 break;
8287
8288 case N_Entry_Body:
8289 case N_Protected_Body:
8290 case N_Task_Body:
8291 /* These nodes should only be present when annotating types. */
8292 gcc_assert (type_annotate_only);
8293 process_decls (Declarations (gnat_node), Empty, Empty, true, true);
8294 gnu_result = alloc_stmt_list ();
8295 break;
8296
8297 case N_Subprogram_Body_Stub:
8298 case N_Package_Body_Stub:
8299 case N_Protected_Body_Stub:
8300 case N_Task_Body_Stub:
8301 /* Simply process whatever unit is being inserted. */
8302 if (Present (Library_Unit (gnat_node)))
8303 gnu_result = gnat_to_gnu (Unit (Library_Unit (gnat_node)));
8304 else
8305 {
8306 gcc_assert (type_annotate_only);
8307 gnu_result = alloc_stmt_list ();
8308 }
8309 break;
8310
8311 /***************************/
8312 /* Chapter 11: Exceptions */
8313 /***************************/
8314
8315 case N_Handled_Sequence_Of_Statements:
8316 /* If there is an At_End procedure attached to this node, and the EH
8317 mechanism is front-end, we must have at least a corresponding At_End
8318 handler, unless the No_Exception_Handlers restriction is set. */
8319 gcc_assert (type_annotate_only
8320 || !Front_End_Exceptions ()
8321 || No (At_End_Proc (gnat_node))
8322 || Present (Exception_Handlers (gnat_node))
8323 || No_Exception_Handlers_Set ());
8324
8325 gnu_result = Handled_Sequence_Of_Statements_to_gnu (gnat_node);
8326 break;
8327
8328 case N_Exception_Handler:
8329 if (Back_End_Exceptions ())
8330 gnu_result = Exception_Handler_to_gnu_gcc (gnat_node);
8331 else if (Exception_Mechanism == Front_End_SJLJ)
8332 gnu_result = Exception_Handler_to_gnu_fe_sjlj (gnat_node);
8333 else
8334 gcc_unreachable ();
8335 break;
8336
8337 case N_Raise_Statement:
8338 /* Only for reraise in back-end exceptions mode. */
8339 gcc_assert (No (Name (gnat_node)) && Back_End_Exceptions ());
8340
8341 start_stmt_group ();
8342
8343 add_stmt_with_node (build_call_n_expr (reraise_zcx_decl, 1,
8344 gnu_incoming_exc_ptr),
8345 gnat_node);
8346
8347 gnu_result = end_stmt_group ();
8348 break;
8349
8350 case N_Push_Constraint_Error_Label:
8351 gnu_constraint_error_label_stack.safe_push (Exception_Label (gnat_node));
8352 break;
8353
8354 case N_Push_Storage_Error_Label:
8355 gnu_storage_error_label_stack.safe_push (Exception_Label (gnat_node));
8356 break;
8357
8358 case N_Push_Program_Error_Label:
8359 gnu_program_error_label_stack.safe_push (Exception_Label (gnat_node));
8360 break;
8361
8362 case N_Pop_Constraint_Error_Label:
8363 gnat_temp = gnu_constraint_error_label_stack.pop ();
8364 if (Present (gnat_temp)
8365 && !TREE_USED (gnat_to_gnu_entity (gnat_temp, NULL_TREE, false)))
8366 Warn_If_No_Local_Raise (gnat_temp);
8367 break;
8368
8369 case N_Pop_Storage_Error_Label:
8370 gnat_temp = gnu_storage_error_label_stack.pop ();
8371 if (Present (gnat_temp)
8372 && !TREE_USED (gnat_to_gnu_entity (gnat_temp, NULL_TREE, false)))
8373 Warn_If_No_Local_Raise (gnat_temp);
8374 break;
8375
8376 case N_Pop_Program_Error_Label:
8377 gnat_temp = gnu_program_error_label_stack.pop ();
8378 if (Present (gnat_temp)
8379 && !TREE_USED (gnat_to_gnu_entity (gnat_temp, NULL_TREE, false)))
8380 Warn_If_No_Local_Raise (gnat_temp);
8381 break;
8382
8383 /******************************/
8384 /* Chapter 12: Generic Units */
8385 /******************************/
8386
8387 case N_Generic_Function_Renaming_Declaration:
8388 case N_Generic_Package_Renaming_Declaration:
8389 case N_Generic_Procedure_Renaming_Declaration:
8390 case N_Generic_Package_Declaration:
8391 case N_Generic_Subprogram_Declaration:
8392 case N_Package_Instantiation:
8393 case N_Procedure_Instantiation:
8394 case N_Function_Instantiation:
8395 /* These nodes can appear on a declaration list but there is nothing to
8396 to be done with them. */
8397 gnu_result = alloc_stmt_list ();
8398 break;
8399
8400 /**************************************************/
8401 /* Chapter 13: Representation Clauses and */
8402 /* Implementation-Dependent Features */
8403 /**************************************************/
8404
8405 case N_Attribute_Definition_Clause:
8406 gnu_result = alloc_stmt_list ();
8407
8408 /* The only one we need to deal with is 'Address since, for the others,
8409 the front-end puts the information elsewhere. */
8410 if (Get_Attribute_Id (Chars (gnat_node)) != Attr_Address)
8411 break;
8412
8413 /* And we only deal with 'Address if the object has a Freeze node. */
8414 gnat_temp = Entity (Name (gnat_node));
8415 if (Freeze_Node (gnat_temp))
8416 {
8417 tree gnu_address = gnat_to_gnu (Expression (gnat_node)), gnu_temp;
8418
8419 /* Get the value to use as the address and save it as the equivalent
8420 for the object; when it is frozen, gnat_to_gnu_entity will do the
8421 right thing. For a subprogram, put the naked address but build a
8422 meaningfull expression for an object in case its address is taken
8423 before the Freeze node is encountered; this can happen if the type
8424 of the object is limited and it is initialized with the result of
8425 a function call. */
8426 if (Is_Subprogram (gnat_temp))
8427 gnu_temp = gnu_address;
8428 else
8429 {
8430 tree gnu_type = gnat_to_gnu_type (Etype (gnat_temp));
8431 /* Drop atomic and volatile qualifiers for the expression. */
8432 gnu_type = TYPE_MAIN_VARIANT (gnu_type);
8433 gnu_type
8434 = build_reference_type_for_mode (gnu_type, ptr_mode, true);
8435 gnu_address = convert (gnu_type, gnu_address);
8436 gnu_temp
8437 = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_address);
8438 }
8439
8440 save_gnu_tree (gnat_temp, gnu_temp, true);
8441 }
8442 break;
8443
8444 case N_Enumeration_Representation_Clause:
8445 case N_Record_Representation_Clause:
8446 case N_At_Clause:
8447 /* We do nothing with these. SEM puts the information elsewhere. */
8448 gnu_result = alloc_stmt_list ();
8449 break;
8450
8451 case N_Code_Statement:
8452 if (!type_annotate_only)
8453 {
8454 tree gnu_template = gnat_to_gnu (Asm_Template (gnat_node));
8455 tree gnu_inputs = NULL_TREE, gnu_outputs = NULL_TREE;
8456 tree gnu_clobbers = NULL_TREE, tail;
8457 bool allows_mem, allows_reg, fake;
8458 int ninputs, noutputs, i;
8459 const char **oconstraints;
8460 const char *constraint;
8461 char *clobber;
8462
8463 /* First retrieve the 3 operand lists built by the front-end. */
8464 Setup_Asm_Outputs (gnat_node);
8465 while (Present (gnat_temp = Asm_Output_Variable ()))
8466 {
8467 tree gnu_value = gnat_to_gnu (gnat_temp);
8468 tree gnu_constr = build_tree_list (NULL_TREE, gnat_to_gnu
8469 (Asm_Output_Constraint ()));
8470
8471 gnu_outputs = tree_cons (gnu_constr, gnu_value, gnu_outputs);
8472 Next_Asm_Output ();
8473 }
8474
8475 Setup_Asm_Inputs (gnat_node);
8476 while (Present (gnat_temp = Asm_Input_Value ()))
8477 {
8478 tree gnu_value = gnat_to_gnu (gnat_temp);
8479 tree gnu_constr = build_tree_list (NULL_TREE, gnat_to_gnu
8480 (Asm_Input_Constraint ()));
8481
8482 gnu_inputs = tree_cons (gnu_constr, gnu_value, gnu_inputs);
8483 Next_Asm_Input ();
8484 }
8485
8486 Clobber_Setup (gnat_node);
8487 while ((clobber = Clobber_Get_Next ()))
8488 gnu_clobbers
8489 = tree_cons (NULL_TREE,
8490 build_string (strlen (clobber) + 1, clobber),
8491 gnu_clobbers);
8492
8493 /* Then perform some standard checking and processing on the
8494 operands. In particular, mark them addressable if needed. */
8495 gnu_outputs = nreverse (gnu_outputs);
8496 noutputs = list_length (gnu_outputs);
8497 gnu_inputs = nreverse (gnu_inputs);
8498 ninputs = list_length (gnu_inputs);
8499 oconstraints = XALLOCAVEC (const char *, noutputs);
8500
8501 for (i = 0, tail = gnu_outputs; tail; ++i, tail = TREE_CHAIN (tail))
8502 {
8503 tree output = TREE_VALUE (tail);
8504 constraint
8505 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
8506 oconstraints[i] = constraint;
8507
8508 if (parse_output_constraint (&constraint, i, ninputs, noutputs,
8509 &allows_mem, &allows_reg, &fake))
8510 {
8511 /* If the operand is going to end up in memory,
8512 mark it addressable. Note that we don't test
8513 allows_mem like in the input case below; this
8514 is modeled on the C front-end. */
8515 if (!allows_reg)
8516 {
8517 output = remove_conversions (output, false);
8518 if (TREE_CODE (output) == CONST_DECL
8519 && DECL_CONST_CORRESPONDING_VAR (output))
8520 output = DECL_CONST_CORRESPONDING_VAR (output);
8521 if (!gnat_mark_addressable (output))
8522 output = error_mark_node;
8523 }
8524 }
8525 else
8526 output = error_mark_node;
8527
8528 TREE_VALUE (tail) = output;
8529 }
8530
8531 for (i = 0, tail = gnu_inputs; tail; ++i, tail = TREE_CHAIN (tail))
8532 {
8533 tree input = TREE_VALUE (tail);
8534 constraint
8535 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
8536
8537 if (parse_input_constraint (&constraint, i, ninputs, noutputs,
8538 0, oconstraints,
8539 &allows_mem, &allows_reg))
8540 {
8541 /* If the operand is going to end up in memory,
8542 mark it addressable. */
8543 if (!allows_reg && allows_mem)
8544 {
8545 input = remove_conversions (input, false);
8546 if (TREE_CODE (input) == CONST_DECL
8547 && DECL_CONST_CORRESPONDING_VAR (input))
8548 input = DECL_CONST_CORRESPONDING_VAR (input);
8549 if (!gnat_mark_addressable (input))
8550 input = error_mark_node;
8551 }
8552 }
8553 else
8554 input = error_mark_node;
8555
8556 TREE_VALUE (tail) = input;
8557 }
8558
8559 gnu_result = build5 (ASM_EXPR, void_type_node,
8560 gnu_template, gnu_outputs,
8561 gnu_inputs, gnu_clobbers, NULL_TREE);
8562 ASM_VOLATILE_P (gnu_result) = Is_Asm_Volatile (gnat_node);
8563 }
8564 else
8565 gnu_result = alloc_stmt_list ();
8566
8567 break;
8568
8569 /****************/
8570 /* Added Nodes */
8571 /****************/
8572
8573 /* Markers are created by the ABE mechanism to capture information which
8574 is either unavailable of expensive to recompute. Markers do not have
8575 and runtime semantics, and should be ignored. */
8576
8577 case N_Call_Marker:
8578 case N_Variable_Reference_Marker:
8579 gnu_result = alloc_stmt_list ();
8580 break;
8581
8582 case N_Expression_With_Actions:
8583 /* This construct doesn't define a scope so we don't push a binding
8584 level around the statement list, but we wrap it in a SAVE_EXPR to
8585 protect it from unsharing. Elaborate the expression as part of the
8586 same statement group as the actions so that the type declaration
8587 gets inserted there as well. This ensures that the type elaboration
8588 code is issued past the actions computing values on which it might
8589 depend. */
8590 start_stmt_group ();
8591 add_stmt_list (Actions (gnat_node));
8592 gnu_expr = gnat_to_gnu (Expression (gnat_node));
8593 gnu_result = end_stmt_group ();
8594
8595 gnu_result = build1 (SAVE_EXPR, void_type_node, gnu_result);
8596 TREE_SIDE_EFFECTS (gnu_result) = 1;
8597
8598 gnu_result
8599 = build_compound_expr (TREE_TYPE (gnu_expr), gnu_result, gnu_expr);
8600 gnu_result_type = get_unpadded_type (Etype (gnat_node));
8601 break;
8602
8603 case N_Freeze_Entity:
8604 start_stmt_group ();
8605 process_freeze_entity (gnat_node);
8606 process_decls (Actions (gnat_node), Empty, Empty, true, true);
8607 gnu_result = end_stmt_group ();
8608 break;
8609
8610 case N_Freeze_Generic_Entity:
8611 gnu_result = alloc_stmt_list ();
8612 break;
8613
8614 case N_Itype_Reference:
8615 if (!present_gnu_tree (Itype (gnat_node)))
8616 process_type (Itype (gnat_node));
8617 gnu_result = alloc_stmt_list ();
8618 break;
8619
8620 case N_Free_Statement:
8621 if (!type_annotate_only)
8622 {
8623 tree gnu_ptr
8624 = gnat_to_gnu (adjust_for_implicit_deref (Expression (gnat_node)));
8625 tree gnu_ptr_type = TREE_TYPE (gnu_ptr);
8626 tree gnu_obj_type, gnu_actual_obj_type;
8627
8628 /* If this is a thin pointer, we must first dereference it to create
8629 a fat pointer, then go back below to a thin pointer. The reason
8630 for this is that we need to have a fat pointer someplace in order
8631 to properly compute the size. */
8632 if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
8633 gnu_ptr = build_unary_op (ADDR_EXPR, NULL_TREE,
8634 build_unary_op (INDIRECT_REF, NULL_TREE,
8635 gnu_ptr));
8636
8637 /* If this is a fat pointer, the object must have been allocated with
8638 the template in front of the array. So pass the template address,
8639 and get the total size; do it by converting to a thin pointer. */
8640 if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_ptr)))
8641 gnu_ptr
8642 = convert (build_pointer_type
8643 (TYPE_OBJECT_RECORD_TYPE
8644 (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (gnu_ptr)))),
8645 gnu_ptr);
8646
8647 gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr));
8648
8649 /* If this is a thin pointer, the object must have been allocated with
8650 the template in front of the array. So pass the template address,
8651 and get the total size. */
8652 if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
8653 gnu_ptr
8654 = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
8655 gnu_ptr,
8656 fold_build1 (NEGATE_EXPR, sizetype,
8657 byte_position
8658 (DECL_CHAIN
8659 TYPE_FIELDS ((gnu_obj_type)))));
8660
8661 /* If we have a special dynamic constrained subtype on the node, use
8662 it to compute the size; otherwise, use the designated subtype. */
8663 if (Present (Actual_Designated_Subtype (gnat_node)))
8664 {
8665 gnu_actual_obj_type
8666 = gnat_to_gnu_type (Actual_Designated_Subtype (gnat_node));
8667
8668 if (TYPE_IS_FAT_OR_THIN_POINTER_P (gnu_ptr_type))
8669 gnu_actual_obj_type
8670 = build_unc_object_type_from_ptr (gnu_ptr_type,
8671 gnu_actual_obj_type,
8672 get_identifier ("DEALLOC"),
8673 false);
8674 }
8675 else
8676 gnu_actual_obj_type = gnu_obj_type;
8677
8678 tree gnu_size = TYPE_SIZE_UNIT (gnu_actual_obj_type);
8679 gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_ptr);
8680
8681 gnu_result
8682 = build_call_alloc_dealloc (gnu_ptr, gnu_size, gnu_obj_type,
8683 Procedure_To_Call (gnat_node),
8684 Storage_Pool (gnat_node),
8685 gnat_node);
8686 }
8687 break;
8688
8689 case N_Raise_Constraint_Error:
8690 case N_Raise_Program_Error:
8691 case N_Raise_Storage_Error:
8692 if (type_annotate_only)
8693 gnu_result = alloc_stmt_list ();
8694 else
8695 gnu_result = Raise_Error_to_gnu (gnat_node, &gnu_result_type);
8696 break;
8697
8698 case N_Validate_Unchecked_Conversion:
8699 /* The only validation we currently do on an unchecked conversion is
8700 that of aliasing assumptions. */
8701 if (flag_strict_aliasing)
8702 gnat_validate_uc_list.safe_push (gnat_node);
8703 gnu_result = alloc_stmt_list ();
8704 break;
8705
8706 case N_Function_Specification:
8707 case N_Procedure_Specification:
8708 case N_Op_Concat:
8709 case N_Component_Association:
8710 /* These nodes should only be present when annotating types. */
8711 gcc_assert (type_annotate_only);
8712 gnu_result = alloc_stmt_list ();
8713 break;
8714
8715 default:
8716 /* Other nodes are not supposed to reach here. */
8717 gcc_unreachable ();
8718 }
8719
8720 /* If we pushed the processing of the elaboration routine, pop it back. */
8721 if (went_into_elab_proc)
8722 current_function_decl = NULL_TREE;
8723
8724 /* When not optimizing, turn boolean rvalues B into B != false tests
8725 so that we can put the location information of the reference to B on
8726 the inequality operator for better debug info. */
8727 if (!optimize
8728 && TREE_CODE (gnu_result) != INTEGER_CST
8729 && TREE_CODE (gnu_result) != TYPE_DECL
8730 && (kind == N_Identifier
8731 || kind == N_Expanded_Name
8732 || kind == N_Explicit_Dereference
8733 || kind == N_Indexed_Component
8734 || kind == N_Selected_Component)
8735 && TREE_CODE (get_base_type (gnu_result_type)) == BOOLEAN_TYPE
8736 && !lvalue_required_p (gnat_node, gnu_result_type, false, false)
8737 && Nkind (Parent (gnat_node)) != N_Variant_Part)
8738 {
8739 gnu_result
8740 = build_binary_op (NE_EXPR, gnu_result_type,
8741 convert (gnu_result_type, gnu_result),
8742 convert (gnu_result_type, boolean_false_node));
8743 if (TREE_CODE (gnu_result) != INTEGER_CST)
8744 set_gnu_expr_location_from_node (gnu_result, gnat_node);
8745 }
8746
8747 /* Set the location information on the result if it's not a simple name
8748 or something that contains a simple name, for example a tag, because
8749 we don"t want all the references to get the location of the first use.
8750 Note that we may have no result if we tried to build a CALL_EXPR node
8751 to a procedure with no side-effects and optimization is enabled. */
8752 else if (kind != N_Identifier
8753 && !(kind == N_Selected_Component
8754 && Chars (Selector_Name (gnat_node)) == Name_uTag)
8755 && gnu_result
8756 && EXPR_P (gnu_result))
8757 set_gnu_expr_location_from_node (gnu_result, gnat_node);
8758
8759 /* If we're supposed to return something of void_type, it means we have
8760 something we're elaborating for effect, so just return. */
8761 if (TREE_CODE (gnu_result_type) == VOID_TYPE)
8762 return gnu_result;
8763
8764 /* If the result is a constant that overflowed, raise Constraint_Error. */
8765 if (TREE_CODE (gnu_result) == INTEGER_CST && TREE_OVERFLOW (gnu_result))
8766 {
8767 post_error ("?`Constraint_Error` will be raised at run time", gnat_node);
8768 gnu_result
8769 = build1 (NULL_EXPR, gnu_result_type,
8770 build_call_raise (CE_Overflow_Check_Failed, gnat_node,
8771 N_Raise_Constraint_Error));
8772 }
8773
8774 /* If the result has side-effects and is of an unconstrained type, protect
8775 the expression in case it will be referenced multiple times, i.e. for
8776 its value and to compute the size of an object. But do it neither for
8777 an object nor a renaming declaration, nor a return statement of a call
8778 to a function that returns an unconstrained record type with default
8779 discriminant, because there is no size to be computed in these cases
8780 and this will create a useless temporary. We must do this before any
8781 conversions. */
8782 if (TREE_SIDE_EFFECTS (gnu_result)
8783 && (TREE_CODE (gnu_result_type) == UNCONSTRAINED_ARRAY_TYPE
8784 || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type)))
8785 && !(TREE_CODE (gnu_result) == CALL_EXPR
8786 && type_is_padding_self_referential (TREE_TYPE (gnu_result))
8787 && (Nkind (Parent (gnat_node)) == N_Object_Declaration
8788 || Nkind (Parent (gnat_node)) == N_Object_Renaming_Declaration
8789 || Nkind (Parent (gnat_node)) == N_Simple_Return_Statement)))
8790 gnu_result = gnat_protect_expr (gnu_result);
8791
8792 /* Now convert the result to the result type, unless we are in one of the
8793 following cases:
8794
8795 1. If this is the LHS of an assignment or an actual parameter of a
8796 call, return the result almost unmodified since the RHS will have
8797 to be converted to our type in that case, unless the result type
8798 has a simpler size. Likewise if there is just a no-op unchecked
8799 conversion in-between. Similarly, don't convert integral types
8800 that are the operands of an unchecked conversion since we need
8801 to ignore those conversions (for 'Valid).
8802
8803 2. If we have a label (which doesn't have any well-defined type), a
8804 field or an error, return the result almost unmodified. Similarly,
8805 if the two types are record types with the same name, don't convert.
8806 This will be the case when we are converting from a packable version
8807 of a type to its original type and we need those conversions to be
8808 NOPs in order for assignments into these types to work properly.
8809
8810 3. If the type is void or if we have no result, return error_mark_node
8811 to show we have no result.
8812
8813 4. If this is a call to a function that returns with variable size and
8814 the call is used as the expression in either an object or a renaming
8815 declaration, return the result unmodified because we want to use the
8816 return slot optimization in this case.
8817
8818 5. If this is a reference to an unconstrained array which is used as the
8819 prefix of an attribute reference that requires an lvalue, return the
8820 result unmodified because we want to return the original bounds.
8821
8822 6. Finally, if the type of the result is already correct. */
8823
8824 if (Present (Parent (gnat_node))
8825 && (lhs_or_actual_p (gnat_node)
8826 || (Nkind (Parent (gnat_node)) == N_Unchecked_Type_Conversion
8827 && unchecked_conversion_nop (Parent (gnat_node)))
8828 || (Nkind (Parent (gnat_node)) == N_Unchecked_Type_Conversion
8829 && !AGGREGATE_TYPE_P (gnu_result_type)
8830 && !AGGREGATE_TYPE_P (TREE_TYPE (gnu_result))))
8831 && !(TYPE_SIZE (gnu_result_type)
8832 && TYPE_SIZE (TREE_TYPE (gnu_result))
8833 && (AGGREGATE_TYPE_P (gnu_result_type)
8834 == AGGREGATE_TYPE_P (TREE_TYPE (gnu_result)))
8835 && ((TREE_CODE (TYPE_SIZE (gnu_result_type)) == INTEGER_CST
8836 && (TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_result)))
8837 != INTEGER_CST))
8838 || (TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST
8839 && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))
8840 && (CONTAINS_PLACEHOLDER_P
8841 (TYPE_SIZE (TREE_TYPE (gnu_result))))))
8842 && !(TREE_CODE (gnu_result_type) == RECORD_TYPE
8843 && TYPE_JUSTIFIED_MODULAR_P (gnu_result_type))))
8844 {
8845 /* Remove padding only if the inner object is of self-referential
8846 size: in that case it must be an object of unconstrained type
8847 with a default discriminant and we want to avoid copying too
8848 much data. */
8849 if (type_is_padding_self_referential (TREE_TYPE (gnu_result)))
8850 gnu_result = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))),
8851 gnu_result);
8852 }
8853
8854 else if (TREE_CODE (gnu_result) == LABEL_DECL
8855 || TREE_CODE (gnu_result) == FIELD_DECL
8856 || TREE_CODE (gnu_result) == ERROR_MARK
8857 || (TYPE_NAME (gnu_result_type)
8858 == TYPE_NAME (TREE_TYPE (gnu_result))
8859 && TREE_CODE (gnu_result_type) == RECORD_TYPE
8860 && TREE_CODE (TREE_TYPE (gnu_result)) == RECORD_TYPE))
8861 {
8862 /* Remove any padding. */
8863 if (TYPE_IS_PADDING_P (TREE_TYPE (gnu_result)))
8864 gnu_result = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))),
8865 gnu_result);
8866 }
8867
8868 else if (gnu_result == error_mark_node || gnu_result_type == void_type_node)
8869 gnu_result = error_mark_node;
8870
8871 else if (TREE_CODE (gnu_result) == CALL_EXPR
8872 && Present (Parent (gnat_node))
8873 && (Nkind (Parent (gnat_node)) == N_Object_Declaration
8874 || Nkind (Parent (gnat_node)) == N_Object_Renaming_Declaration)
8875 && return_type_with_variable_size_p (TREE_TYPE (gnu_result)))
8876 ;
8877
8878 else if (TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF
8879 && Present (Parent (gnat_node))
8880 && Nkind (Parent (gnat_node)) == N_Attribute_Reference
8881 && lvalue_required_for_attribute_p (Parent (gnat_node)))
8882 ;
8883
8884 else if (TREE_TYPE (gnu_result) != gnu_result_type)
8885 gnu_result = convert (gnu_result_type, gnu_result);
8886
8887 /* We don't need any NOP_EXPR or NON_LVALUE_EXPR on the result. */
8888 while ((TREE_CODE (gnu_result) == NOP_EXPR
8889 || TREE_CODE (gnu_result) == NON_LVALUE_EXPR)
8890 && TREE_TYPE (TREE_OPERAND (gnu_result, 0)) == TREE_TYPE (gnu_result))
8891 gnu_result = TREE_OPERAND (gnu_result, 0);
8892
8893 return gnu_result;
8894 }
8895
8896 /* Similar to gnat_to_gnu, but discard any object that might be created in
8897 the course of the translation of GNAT_NODE, which must be an "external"
8898 expression in the sense that it will be elaborated elsewhere. */
8899
8900 tree
gnat_to_gnu_external(Node_Id gnat_node)8901 gnat_to_gnu_external (Node_Id gnat_node)
8902 {
8903 const int save_force_global = force_global;
8904 bool went_into_elab_proc = false;
8905
8906 /* Force the local context and create a fake scope that we zap
8907 at the end so declarations will not be stuck either in the
8908 global varpool or in the current scope. */
8909 if (!current_function_decl)
8910 {
8911 current_function_decl = get_elaboration_procedure ();
8912 went_into_elab_proc = true;
8913 }
8914 force_global = 0;
8915 gnat_pushlevel ();
8916
8917 tree gnu_result = gnat_to_gnu (gnat_node);
8918
8919 gnat_zaplevel ();
8920 force_global = save_force_global;
8921 if (went_into_elab_proc)
8922 current_function_decl = NULL_TREE;
8923
8924 /* Do not import locations from external units. */
8925 if (gnu_result && EXPR_P (gnu_result))
8926 SET_EXPR_LOCATION (gnu_result, UNKNOWN_LOCATION);
8927
8928 return gnu_result;
8929 }
8930
8931 /* Return true if the statement list STMT_LIST is empty. */
8932
8933 static bool
empty_stmt_list_p(tree stmt_list)8934 empty_stmt_list_p (tree stmt_list)
8935 {
8936 tree_stmt_iterator tsi;
8937
8938 for (tsi = tsi_start (stmt_list); !tsi_end_p (tsi); tsi_next (&tsi))
8939 {
8940 tree stmt = tsi_stmt (tsi);
8941
8942 /* Anything else than an empty STMT_STMT counts as something. */
8943 if (TREE_CODE (stmt) != STMT_STMT || STMT_STMT_STMT (stmt))
8944 return false;
8945 }
8946
8947 return true;
8948 }
8949
8950 /* Record the current code position in GNAT_NODE. */
8951
8952 static void
record_code_position(Node_Id gnat_node)8953 record_code_position (Node_Id gnat_node)
8954 {
8955 tree stmt_stmt = build1 (STMT_STMT, void_type_node, NULL_TREE);
8956
8957 add_stmt_with_node (stmt_stmt, gnat_node);
8958 save_gnu_tree (gnat_node, stmt_stmt, true);
8959 }
8960
8961 /* Insert the code for GNAT_NODE at the position saved for that node. */
8962
8963 static void
insert_code_for(Node_Id gnat_node)8964 insert_code_for (Node_Id gnat_node)
8965 {
8966 tree code = gnat_to_gnu (gnat_node);
8967
8968 /* It's too late to remove the STMT_STMT itself at this point. */
8969 if (!empty_stmt_list_p (code))
8970 STMT_STMT_STMT (get_gnu_tree (gnat_node)) = code;
8971
8972 save_gnu_tree (gnat_node, NULL_TREE, true);
8973 }
8974
8975 /* Start a new statement group chained to the previous group. */
8976
8977 void
start_stmt_group(void)8978 start_stmt_group (void)
8979 {
8980 struct stmt_group *group = stmt_group_free_list;
8981
8982 /* First see if we can get one from the free list. */
8983 if (group)
8984 stmt_group_free_list = group->previous;
8985 else
8986 group = ggc_alloc<stmt_group> ();
8987
8988 group->previous = current_stmt_group;
8989 group->stmt_list = group->block = group->cleanups = NULL_TREE;
8990 current_stmt_group = group;
8991 }
8992
8993 /* Add GNU_STMT to the current statement group. If it is an expression with
8994 no effects, it is ignored. */
8995
8996 void
add_stmt(tree gnu_stmt)8997 add_stmt (tree gnu_stmt)
8998 {
8999 append_to_statement_list (gnu_stmt, ¤t_stmt_group->stmt_list);
9000 }
9001
9002 /* Similar, but the statement is always added, regardless of side-effects. */
9003
9004 void
add_stmt_force(tree gnu_stmt)9005 add_stmt_force (tree gnu_stmt)
9006 {
9007 append_to_statement_list_force (gnu_stmt, ¤t_stmt_group->stmt_list);
9008 }
9009
9010 /* Like add_stmt, but set the location of GNU_STMT to that of GNAT_NODE. */
9011
9012 void
add_stmt_with_node(tree gnu_stmt,Node_Id gnat_node)9013 add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node)
9014 {
9015 if (Present (gnat_node))
9016 set_expr_location_from_node (gnu_stmt, gnat_node);
9017 add_stmt (gnu_stmt);
9018 }
9019
9020 /* Similar, but the statement is always added, regardless of side-effects. */
9021
9022 void
add_stmt_with_node_force(tree gnu_stmt,Node_Id gnat_node)9023 add_stmt_with_node_force (tree gnu_stmt, Node_Id gnat_node)
9024 {
9025 if (Present (gnat_node))
9026 set_expr_location_from_node (gnu_stmt, gnat_node);
9027 add_stmt_force (gnu_stmt);
9028 }
9029
9030 /* Add a declaration statement for GNU_DECL to the current statement group.
9031 Get the SLOC to be put onto the statement from GNAT_NODE. */
9032
9033 void
add_decl_expr(tree gnu_decl,Node_Id gnat_node)9034 add_decl_expr (tree gnu_decl, Node_Id gnat_node)
9035 {
9036 tree type = TREE_TYPE (gnu_decl);
9037 tree gnu_stmt, gnu_init;
9038
9039 /* If this is a variable that Gigi is to ignore, we may have been given
9040 an ERROR_MARK. So test for it. We also might have been given a
9041 reference for a renaming. So only do something for a decl. Also
9042 ignore a TYPE_DECL for an UNCONSTRAINED_ARRAY_TYPE. */
9043 if (!DECL_P (gnu_decl)
9044 || (TREE_CODE (gnu_decl) == TYPE_DECL
9045 && TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE))
9046 return;
9047
9048 gnu_stmt = build1 (DECL_EXPR, void_type_node, gnu_decl);
9049
9050 /* If we are external or global, we don't want to output the DECL_EXPR for
9051 this DECL node since we already have evaluated the expressions in the
9052 sizes and positions as globals and doing it again would be wrong. */
9053 if (DECL_EXTERNAL (gnu_decl) || global_bindings_p ())
9054 {
9055 /* Mark everything as used to prevent node sharing with subprograms.
9056 Note that walk_tree knows how to deal with TYPE_DECL, but neither
9057 VAR_DECL nor CONST_DECL. This appears to be somewhat arbitrary. */
9058 MARK_VISITED (gnu_stmt);
9059 if (TREE_CODE (gnu_decl) == VAR_DECL
9060 || TREE_CODE (gnu_decl) == CONST_DECL)
9061 {
9062 MARK_VISITED (DECL_SIZE (gnu_decl));
9063 MARK_VISITED (DECL_SIZE_UNIT (gnu_decl));
9064 MARK_VISITED (DECL_INITIAL (gnu_decl));
9065 }
9066 /* In any case, we have to deal with our own TYPE_ADA_SIZE field. */
9067 else if (TREE_CODE (gnu_decl) == TYPE_DECL
9068 && RECORD_OR_UNION_TYPE_P (type)
9069 && !TYPE_FAT_POINTER_P (type))
9070 MARK_VISITED (TYPE_ADA_SIZE (type));
9071 }
9072 else
9073 add_stmt_with_node (gnu_stmt, gnat_node);
9074
9075 /* If this is a variable and an initializer is attached to it, it must be
9076 valid for the context. Similar to init_const in create_var_decl. */
9077 if (TREE_CODE (gnu_decl) == VAR_DECL
9078 && (gnu_init = DECL_INITIAL (gnu_decl))
9079 && (!gnat_types_compatible_p (type, TREE_TYPE (gnu_init))
9080 || (TREE_STATIC (gnu_decl)
9081 && !initializer_constant_valid_p (gnu_init,
9082 TREE_TYPE (gnu_init)))))
9083 {
9084 DECL_INITIAL (gnu_decl) = NULL_TREE;
9085 if (TREE_READONLY (gnu_decl))
9086 {
9087 TREE_READONLY (gnu_decl) = 0;
9088 DECL_READONLY_ONCE_ELAB (gnu_decl) = 1;
9089 }
9090
9091 /* If GNU_DECL has a padded type, convert it to the unpadded
9092 type so the assignment is done properly. */
9093 if (TYPE_IS_PADDING_P (type))
9094 gnu_decl = convert (TREE_TYPE (TYPE_FIELDS (type)), gnu_decl);
9095
9096 gnu_stmt = build_binary_op (INIT_EXPR, NULL_TREE, gnu_decl, gnu_init);
9097 add_stmt_with_node (gnu_stmt, gnat_node);
9098 }
9099 }
9100
9101 /* Callback for walk_tree to mark the visited trees rooted at *TP. */
9102
9103 static tree
mark_visited_r(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)9104 mark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
9105 {
9106 tree t = *tp;
9107
9108 if (TREE_VISITED (t))
9109 *walk_subtrees = 0;
9110
9111 /* Don't mark a dummy type as visited because we want to mark its sizes
9112 and fields once it's filled in. */
9113 else if (!TYPE_IS_DUMMY_P (t))
9114 TREE_VISITED (t) = 1;
9115
9116 /* The test in gimplify_type_sizes is on the main variant. */
9117 if (TYPE_P (t))
9118 TYPE_SIZES_GIMPLIFIED (TYPE_MAIN_VARIANT (t)) = 1;
9119
9120 return NULL_TREE;
9121 }
9122
9123 /* Mark nodes rooted at T with TREE_VISITED and types as having their
9124 sized gimplified. We use this to indicate all variable sizes and
9125 positions in global types may not be shared by any subprogram. */
9126
9127 void
mark_visited(tree t)9128 mark_visited (tree t)
9129 {
9130 walk_tree (&t, mark_visited_r, NULL, NULL);
9131 }
9132
9133 /* Add GNU_CLEANUP, a cleanup action, to the current code group and
9134 set its location to that of GNAT_NODE if present, but with column info
9135 cleared so that conditional branches generated as part of the cleanup
9136 code do not interfere with coverage analysis tools. */
9137
9138 static void
add_cleanup(tree gnu_cleanup,Node_Id gnat_node)9139 add_cleanup (tree gnu_cleanup, Node_Id gnat_node)
9140 {
9141 if (Present (gnat_node))
9142 set_expr_location_from_node (gnu_cleanup, gnat_node, true);
9143 /* An EH_ELSE_EXPR must be by itself, and that's all we need when we
9144 use it. The assert below makes sure that is so. Should we ever
9145 need more than that, we could combine EH_ELSE_EXPRs, and copy
9146 non-EH_ELSE_EXPR stmts into both cleanup paths of an
9147 EH_ELSE_EXPR. */
9148 if (TREE_CODE (gnu_cleanup) == EH_ELSE_EXPR)
9149 {
9150 gcc_assert (!current_stmt_group->cleanups);
9151 current_stmt_group->cleanups = gnu_cleanup;
9152 }
9153 else
9154 {
9155 gcc_assert (!current_stmt_group->cleanups
9156 || (TREE_CODE (current_stmt_group->cleanups)
9157 != EH_ELSE_EXPR));
9158 append_to_statement_list (gnu_cleanup, ¤t_stmt_group->cleanups);
9159 }
9160 }
9161
9162 /* Set the BLOCK node corresponding to the current code group to GNU_BLOCK. */
9163
9164 void
set_block_for_group(tree gnu_block)9165 set_block_for_group (tree gnu_block)
9166 {
9167 gcc_assert (!current_stmt_group->block);
9168 current_stmt_group->block = gnu_block;
9169 }
9170
9171 /* Return code corresponding to the current code group. It is normally
9172 a STATEMENT_LIST, but may also be a BIND_EXPR or TRY_FINALLY_EXPR if
9173 BLOCK or cleanups were set. */
9174
9175 tree
end_stmt_group(void)9176 end_stmt_group (void)
9177 {
9178 struct stmt_group *group = current_stmt_group;
9179 tree gnu_retval = group->stmt_list;
9180
9181 /* If this is a null list, allocate a new STATEMENT_LIST. Then, if there
9182 are cleanups, make a TRY_FINALLY_EXPR. Last, if there is a BLOCK,
9183 make a BIND_EXPR. Note that we nest in that because the cleanup may
9184 reference variables in the block. */
9185 if (!gnu_retval)
9186 gnu_retval = alloc_stmt_list ();
9187
9188 if (group->cleanups)
9189 gnu_retval = build2 (TRY_FINALLY_EXPR, void_type_node, gnu_retval,
9190 group->cleanups);
9191
9192 if (current_stmt_group->block)
9193 gnu_retval = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (group->block),
9194 gnu_retval, group->block);
9195
9196 /* Remove this group from the stack and add it to the free list. */
9197 current_stmt_group = group->previous;
9198 group->previous = stmt_group_free_list;
9199 stmt_group_free_list = group;
9200
9201 return gnu_retval;
9202 }
9203
9204 /* Return whether the current statement group may fall through. */
9205
9206 static inline bool
stmt_group_may_fallthru(void)9207 stmt_group_may_fallthru (void)
9208 {
9209 if (current_stmt_group->stmt_list)
9210 return block_may_fallthru (current_stmt_group->stmt_list);
9211 else
9212 return true;
9213 }
9214
9215 /* Add a list of statements from GNAT_LIST, a possibly-empty list of
9216 statements.*/
9217
9218 static void
add_stmt_list(List_Id gnat_list)9219 add_stmt_list (List_Id gnat_list)
9220 {
9221 Node_Id gnat_node;
9222
9223 if (Present (gnat_list))
9224 for (gnat_node = First (gnat_list); Present (gnat_node);
9225 gnat_node = Next (gnat_node))
9226 add_stmt (gnat_to_gnu (gnat_node));
9227 }
9228
9229 /* Build a tree from GNAT_LIST, a possibly-empty list of statements.
9230 If BINDING_P is true, push and pop a binding level around the list. */
9231
9232 static tree
build_stmt_group(List_Id gnat_list,bool binding_p)9233 build_stmt_group (List_Id gnat_list, bool binding_p)
9234 {
9235 start_stmt_group ();
9236
9237 if (binding_p)
9238 gnat_pushlevel ();
9239
9240 add_stmt_list (gnat_list);
9241
9242 if (binding_p)
9243 gnat_poplevel ();
9244
9245 return end_stmt_group ();
9246 }
9247
9248 /* Generate GIMPLE in place for the expression at *EXPR_P. */
9249
9250 int
gnat_gimplify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p ATTRIBUTE_UNUSED)9251 gnat_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
9252 gimple_seq *post_p ATTRIBUTE_UNUSED)
9253 {
9254 tree expr = *expr_p;
9255 tree type = TREE_TYPE (expr);
9256 tree op;
9257
9258 if (IS_ADA_STMT (expr))
9259 return gnat_gimplify_stmt (expr_p);
9260
9261 switch (TREE_CODE (expr))
9262 {
9263 case NULL_EXPR:
9264 /* If this is an aggregate type, build a null pointer of the appropriate
9265 type and dereference it. */
9266 if (AGGREGATE_TYPE_P (type)
9267 || TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
9268 *expr_p = build_unary_op (INDIRECT_REF, NULL_TREE,
9269 convert (build_pointer_type (type),
9270 integer_zero_node));
9271 /* Otherwise, just make a VAR_DECL. */
9272 else
9273 {
9274 *expr_p = create_tmp_var (type, NULL);
9275 TREE_NO_WARNING (*expr_p) = 1;
9276 }
9277
9278 gimplify_and_add (TREE_OPERAND (expr, 0), pre_p);
9279 return GS_OK;
9280
9281 case UNCONSTRAINED_ARRAY_REF:
9282 /* We should only do this if we are just elaborating for side-effects,
9283 but we can't know that yet. */
9284 *expr_p = TREE_OPERAND (*expr_p, 0);
9285 return GS_OK;
9286
9287 case ADDR_EXPR:
9288 op = TREE_OPERAND (expr, 0);
9289
9290 /* If we are taking the address of a constant CONSTRUCTOR, make sure it
9291 is put into static memory. We know that it's going to be read-only
9292 given the semantics we have and it must be in static memory when the
9293 reference is in an elaboration procedure. */
9294 if (TREE_CODE (op) == CONSTRUCTOR && TREE_CONSTANT (op))
9295 {
9296 tree addr = build_fold_addr_expr (tree_output_constant_def (op));
9297 *expr_p = fold_convert (type, addr);
9298 return GS_ALL_DONE;
9299 }
9300
9301 /* Replace atomic loads with their first argument. That's necessary
9302 because the gimplifier would create a temporary otherwise. */
9303 if (TREE_SIDE_EFFECTS (op))
9304 while (handled_component_p (op) || CONVERT_EXPR_P (op))
9305 {
9306 tree inner = TREE_OPERAND (op, 0);
9307 if (TREE_CODE (inner) == CALL_EXPR && call_is_atomic_load (inner))
9308 {
9309 tree t = CALL_EXPR_ARG (inner, 0);
9310 if (TREE_CODE (t) == NOP_EXPR)
9311 t = TREE_OPERAND (t, 0);
9312 if (TREE_CODE (t) == ADDR_EXPR)
9313 TREE_OPERAND (op, 0) = TREE_OPERAND (t, 0);
9314 else
9315 TREE_OPERAND (op, 0) = build_fold_indirect_ref (t);
9316 }
9317 else
9318 op = inner;
9319 }
9320
9321 return GS_UNHANDLED;
9322
9323 case VIEW_CONVERT_EXPR:
9324 op = TREE_OPERAND (expr, 0);
9325
9326 /* If we are view-converting a CONSTRUCTOR or a call from an aggregate
9327 type to a scalar one, explicitly create the local temporary. That's
9328 required if the type is passed by reference. */
9329 if ((TREE_CODE (op) == CONSTRUCTOR || TREE_CODE (op) == CALL_EXPR)
9330 && AGGREGATE_TYPE_P (TREE_TYPE (op))
9331 && !AGGREGATE_TYPE_P (type))
9332 {
9333 tree mod, new_var = create_tmp_var_raw (TREE_TYPE (op), "C");
9334 gimple_add_tmp_var (new_var);
9335
9336 mod = build2 (INIT_EXPR, TREE_TYPE (new_var), new_var, op);
9337 gimplify_and_add (mod, pre_p);
9338
9339 TREE_OPERAND (expr, 0) = new_var;
9340 return GS_OK;
9341 }
9342
9343 return GS_UNHANDLED;
9344
9345 case DECL_EXPR:
9346 op = DECL_EXPR_DECL (expr);
9347
9348 /* The expressions for the RM bounds must be gimplified to ensure that
9349 they are properly elaborated. See gimplify_decl_expr. */
9350 if ((TREE_CODE (op) == TYPE_DECL || TREE_CODE (op) == VAR_DECL)
9351 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (op)))
9352 switch (TREE_CODE (TREE_TYPE (op)))
9353 {
9354 case INTEGER_TYPE:
9355 case ENUMERAL_TYPE:
9356 case BOOLEAN_TYPE:
9357 case REAL_TYPE:
9358 {
9359 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (op)), t, val;
9360
9361 val = TYPE_RM_MIN_VALUE (type);
9362 if (val)
9363 {
9364 gimplify_one_sizepos (&val, pre_p);
9365 for (t = type; t; t = TYPE_NEXT_VARIANT (t))
9366 SET_TYPE_RM_MIN_VALUE (t, val);
9367 }
9368
9369 val = TYPE_RM_MAX_VALUE (type);
9370 if (val)
9371 {
9372 gimplify_one_sizepos (&val, pre_p);
9373 for (t = type; t; t = TYPE_NEXT_VARIANT (t))
9374 SET_TYPE_RM_MAX_VALUE (t, val);
9375 }
9376
9377 }
9378 break;
9379
9380 default:
9381 break;
9382 }
9383
9384 /* ... fall through ... */
9385
9386 default:
9387 return GS_UNHANDLED;
9388 }
9389 }
9390
9391 /* Generate GIMPLE in place for the statement at *STMT_P. */
9392
9393 static enum gimplify_status
gnat_gimplify_stmt(tree * stmt_p)9394 gnat_gimplify_stmt (tree *stmt_p)
9395 {
9396 tree stmt = *stmt_p;
9397
9398 switch (TREE_CODE (stmt))
9399 {
9400 case STMT_STMT:
9401 *stmt_p = STMT_STMT_STMT (stmt);
9402 return GS_OK;
9403
9404 case LOOP_STMT:
9405 {
9406 tree gnu_start_label = create_artificial_label (input_location);
9407 tree gnu_cond = LOOP_STMT_COND (stmt);
9408 tree gnu_update = LOOP_STMT_UPDATE (stmt);
9409 tree gnu_end_label = LOOP_STMT_LABEL (stmt);
9410
9411 /* Build the condition expression from the test, if any. */
9412 if (gnu_cond)
9413 {
9414 /* Deal with the optimization hints. */
9415 if (LOOP_STMT_IVDEP (stmt))
9416 gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
9417 build_int_cst (integer_type_node,
9418 annot_expr_ivdep_kind),
9419 integer_zero_node);
9420 if (LOOP_STMT_NO_UNROLL (stmt))
9421 gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
9422 build_int_cst (integer_type_node,
9423 annot_expr_unroll_kind),
9424 integer_one_node);
9425 if (LOOP_STMT_UNROLL (stmt))
9426 gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
9427 build_int_cst (integer_type_node,
9428 annot_expr_unroll_kind),
9429 build_int_cst (NULL_TREE, USHRT_MAX));
9430 if (LOOP_STMT_NO_VECTOR (stmt))
9431 gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
9432 build_int_cst (integer_type_node,
9433 annot_expr_no_vector_kind),
9434 integer_zero_node);
9435 if (LOOP_STMT_VECTOR (stmt))
9436 gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
9437 build_int_cst (integer_type_node,
9438 annot_expr_vector_kind),
9439 integer_zero_node);
9440
9441 gnu_cond
9442 = build3 (COND_EXPR, void_type_node, gnu_cond, NULL_TREE,
9443 build1 (GOTO_EXPR, void_type_node, gnu_end_label));
9444 }
9445
9446 /* Set to emit the statements of the loop. */
9447 *stmt_p = NULL_TREE;
9448
9449 /* We first emit the start label and then a conditional jump to the
9450 end label if there's a top condition, then the update if it's at
9451 the top, then the body of the loop, then a conditional jump to
9452 the end label if there's a bottom condition, then the update if
9453 it's at the bottom, and finally a jump to the start label and the
9454 definition of the end label. */
9455 append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
9456 gnu_start_label),
9457 stmt_p);
9458
9459 if (gnu_cond && !LOOP_STMT_BOTTOM_COND_P (stmt))
9460 append_to_statement_list (gnu_cond, stmt_p);
9461
9462 if (gnu_update && LOOP_STMT_TOP_UPDATE_P (stmt))
9463 append_to_statement_list (gnu_update, stmt_p);
9464
9465 append_to_statement_list (LOOP_STMT_BODY (stmt), stmt_p);
9466
9467 if (gnu_cond && LOOP_STMT_BOTTOM_COND_P (stmt))
9468 append_to_statement_list (gnu_cond, stmt_p);
9469
9470 if (gnu_update && !LOOP_STMT_TOP_UPDATE_P (stmt))
9471 append_to_statement_list (gnu_update, stmt_p);
9472
9473 tree t = build1 (GOTO_EXPR, void_type_node, gnu_start_label);
9474 SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (gnu_end_label));
9475 append_to_statement_list (t, stmt_p);
9476
9477 append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
9478 gnu_end_label),
9479 stmt_p);
9480 return GS_OK;
9481 }
9482
9483 case EXIT_STMT:
9484 /* Build a statement to jump to the corresponding end label, then
9485 see if it needs to be conditional. */
9486 *stmt_p = build1 (GOTO_EXPR, void_type_node, EXIT_STMT_LABEL (stmt));
9487 if (EXIT_STMT_COND (stmt))
9488 *stmt_p = build3 (COND_EXPR, void_type_node,
9489 EXIT_STMT_COND (stmt), *stmt_p, alloc_stmt_list ());
9490 return GS_OK;
9491
9492 default:
9493 gcc_unreachable ();
9494 }
9495 }
9496
9497 /* Force a reference to each of the entities in GNAT_PACKAGE recursively.
9498
9499 This routine is exclusively called in type_annotate mode, to compute DDA
9500 information for types in withed units, for ASIS use. */
9501
9502 static void
elaborate_all_entities_for_package(Entity_Id gnat_package)9503 elaborate_all_entities_for_package (Entity_Id gnat_package)
9504 {
9505 Entity_Id gnat_entity;
9506
9507 for (gnat_entity = First_Entity (gnat_package);
9508 Present (gnat_entity);
9509 gnat_entity = Next_Entity (gnat_entity))
9510 {
9511 const Entity_Kind kind = Ekind (gnat_entity);
9512
9513 /* We are interested only in entities visible from the main unit. */
9514 if (!Is_Public (gnat_entity))
9515 continue;
9516
9517 /* Skip stuff internal to the compiler. */
9518 if (Convention (gnat_entity) == Convention_Intrinsic)
9519 continue;
9520 if (kind == E_Operator)
9521 continue;
9522 if (IN (kind, Subprogram_Kind)
9523 && (Present (Alias (gnat_entity))
9524 || Is_Intrinsic_Subprogram (gnat_entity)))
9525 continue;
9526 if (Is_Itype (gnat_entity))
9527 continue;
9528
9529 /* Skip named numbers. */
9530 if (IN (kind, Named_Kind))
9531 continue;
9532
9533 /* Skip generic declarations. */
9534 if (IN (kind, Generic_Unit_Kind))
9535 continue;
9536
9537 /* Skip formal objects. */
9538 if (IN (kind, Formal_Object_Kind))
9539 continue;
9540
9541 /* Skip package bodies. */
9542 if (kind == E_Package_Body)
9543 continue;
9544
9545 /* Skip limited views that point back to the main unit. */
9546 if (IN (kind, Incomplete_Kind)
9547 && From_Limited_With (gnat_entity)
9548 && In_Extended_Main_Code_Unit (Non_Limited_View (gnat_entity)))
9549 continue;
9550
9551 /* Skip types that aren't frozen. */
9552 if (IN (kind, Type_Kind) && !Is_Frozen (gnat_entity))
9553 continue;
9554
9555 /* Recurse on real packages that aren't in the main unit. */
9556 if (kind == E_Package)
9557 {
9558 if (No (Renamed_Entity (gnat_entity))
9559 && !In_Extended_Main_Code_Unit (gnat_entity))
9560 elaborate_all_entities_for_package (gnat_entity);
9561 }
9562 else
9563 gnat_to_gnu_entity (gnat_entity, NULL_TREE, false);
9564 }
9565 }
9566
9567 /* Force a reference to each of the entities in packages withed by GNAT_NODE.
9568 Operate recursively but check that we aren't elaborating something more
9569 than once.
9570
9571 This routine is exclusively called in type_annotate mode, to compute DDA
9572 information for types in withed units, for ASIS use. */
9573
9574 static void
elaborate_all_entities(Node_Id gnat_node)9575 elaborate_all_entities (Node_Id gnat_node)
9576 {
9577 Entity_Id gnat_with_clause;
9578
9579 /* Process each unit only once. As we trace the context of all relevant
9580 units transitively, including generic bodies, we may encounter the
9581 same generic unit repeatedly. */
9582 if (!present_gnu_tree (gnat_node))
9583 save_gnu_tree (gnat_node, integer_zero_node, true);
9584
9585 /* Save entities in all context units. A body may have an implicit_with
9586 on its own spec, if the context includes a child unit, so don't save
9587 the spec twice. */
9588 for (gnat_with_clause = First (Context_Items (gnat_node));
9589 Present (gnat_with_clause);
9590 gnat_with_clause = Next (gnat_with_clause))
9591 if (Nkind (gnat_with_clause) == N_With_Clause
9592 && !present_gnu_tree (Library_Unit (gnat_with_clause))
9593 && Library_Unit (gnat_with_clause) != Library_Unit (Cunit (Main_Unit)))
9594 {
9595 Node_Id gnat_unit = Library_Unit (gnat_with_clause);
9596 Entity_Id gnat_entity = Entity (Name (gnat_with_clause));
9597
9598 elaborate_all_entities (gnat_unit);
9599
9600 if (Ekind (gnat_entity) == E_Package
9601 && No (Renamed_Entity (gnat_entity)))
9602 elaborate_all_entities_for_package (gnat_entity);
9603
9604 else if (Ekind (gnat_entity) == E_Generic_Package)
9605 {
9606 Node_Id gnat_body = Corresponding_Body (Unit (gnat_unit));
9607
9608 /* Retrieve compilation unit node of generic body. */
9609 while (Present (gnat_body)
9610 && Nkind (gnat_body) != N_Compilation_Unit)
9611 gnat_body = Parent (gnat_body);
9612
9613 /* If body is available, elaborate its context. */
9614 if (Present (gnat_body))
9615 elaborate_all_entities (gnat_body);
9616 }
9617 }
9618
9619 if (Nkind (Unit (gnat_node)) == N_Package_Body)
9620 elaborate_all_entities (Library_Unit (gnat_node));
9621 }
9622
9623 /* Do the processing of GNAT_NODE, an N_Freeze_Entity. */
9624
9625 static void
process_freeze_entity(Node_Id gnat_node)9626 process_freeze_entity (Node_Id gnat_node)
9627 {
9628 const Entity_Id gnat_entity = Entity (gnat_node);
9629 const Entity_Kind kind = Ekind (gnat_entity);
9630 tree gnu_old, gnu_new;
9631
9632 /* If this is a package, generate code for the package body, if any. */
9633 if (kind == E_Package)
9634 {
9635 const Node_Id gnat_decl = Parent (Declaration_Node (gnat_entity));
9636 if (Present (Corresponding_Body (gnat_decl)))
9637 insert_code_for (Parent (Corresponding_Body (gnat_decl)));
9638 return;
9639 }
9640
9641 /* Don't do anything for class-wide types as they are always transformed
9642 into their root type. */
9643 if (kind == E_Class_Wide_Type)
9644 return;
9645
9646 /* Check for an old definition if this isn't an object with address clause,
9647 since the saved GCC tree is the address expression in that case. */
9648 gnu_old
9649 = present_gnu_tree (gnat_entity) && No (Address_Clause (gnat_entity))
9650 ? get_gnu_tree (gnat_entity) : NULL_TREE;
9651
9652 /* Don't do anything for subprograms that may have been elaborated before
9653 their freeze nodes. This can happen, for example, because of an inner
9654 call in an instance body or because of previous compilation of a spec
9655 for inlining purposes. */
9656 if (gnu_old
9657 && ((TREE_CODE (gnu_old) == FUNCTION_DECL
9658 && (kind == E_Function || kind == E_Procedure))
9659 || (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (gnu_old))
9660 && kind == E_Subprogram_Type)))
9661 return;
9662
9663 /* If we have a non-dummy type old tree, we have nothing to do, except for
9664 aborting, since this node was never delayed as it should have been. We
9665 let this happen for concurrent types and their Corresponding_Record_Type,
9666 however, because each might legitimately be elaborated before its own
9667 freeze node, e.g. while processing the other. */
9668 if (gnu_old
9669 && !(TREE_CODE (gnu_old) == TYPE_DECL
9670 && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old))))
9671 {
9672 gcc_assert (Is_Concurrent_Type (gnat_entity)
9673 || (Is_Record_Type (gnat_entity)
9674 && Is_Concurrent_Record_Type (gnat_entity)));
9675 return;
9676 }
9677
9678 /* Reset the saved tree, if any, and elaborate the object or type for real.
9679 If there is a full view, elaborate it and use the result. And, if this
9680 is the root type of a class-wide type, reuse it for the latter. */
9681 if (gnu_old)
9682 {
9683 save_gnu_tree (gnat_entity, NULL_TREE, false);
9684
9685 if (Is_Incomplete_Or_Private_Type (gnat_entity)
9686 && Present (Full_View (gnat_entity)))
9687 {
9688 Entity_Id full_view = Full_View (gnat_entity);
9689
9690 save_gnu_tree (full_view, NULL_TREE, false);
9691
9692 if (Is_Private_Type (full_view)
9693 && Present (Underlying_Full_View (full_view)))
9694 {
9695 full_view = Underlying_Full_View (full_view);
9696 save_gnu_tree (full_view, NULL_TREE, false);
9697 }
9698 }
9699
9700 if (Is_Type (gnat_entity)
9701 && Present (Class_Wide_Type (gnat_entity))
9702 && Root_Type (Class_Wide_Type (gnat_entity)) == gnat_entity)
9703 save_gnu_tree (Class_Wide_Type (gnat_entity), NULL_TREE, false);
9704 }
9705
9706 if (Is_Incomplete_Or_Private_Type (gnat_entity)
9707 && Present (Full_View (gnat_entity)))
9708 {
9709 Entity_Id full_view = Full_View (gnat_entity);
9710
9711 if (Is_Private_Type (full_view)
9712 && Present (Underlying_Full_View (full_view)))
9713 full_view = Underlying_Full_View (full_view);
9714
9715 gnu_new = gnat_to_gnu_entity (full_view, NULL_TREE, true);
9716
9717 /* Propagate back-annotations from full view to partial view. */
9718 if (Unknown_Alignment (gnat_entity))
9719 Set_Alignment (gnat_entity, Alignment (full_view));
9720
9721 if (Unknown_Esize (gnat_entity))
9722 Set_Esize (gnat_entity, Esize (full_view));
9723
9724 if (Unknown_RM_Size (gnat_entity))
9725 Set_RM_Size (gnat_entity, RM_Size (full_view));
9726
9727 /* The above call may have defined this entity (the simplest example
9728 of this is when we have a private enumeral type since the bounds
9729 will have the public view). */
9730 if (!present_gnu_tree (gnat_entity))
9731 save_gnu_tree (gnat_entity, gnu_new, false);
9732 }
9733 else
9734 {
9735 tree gnu_init
9736 = (Nkind (Declaration_Node (gnat_entity)) == N_Object_Declaration
9737 && present_gnu_tree (Declaration_Node (gnat_entity)))
9738 ? get_gnu_tree (Declaration_Node (gnat_entity)) : NULL_TREE;
9739
9740 gnu_new = gnat_to_gnu_entity (gnat_entity, gnu_init, true);
9741 }
9742
9743 if (Is_Type (gnat_entity)
9744 && Present (Class_Wide_Type (gnat_entity))
9745 && Root_Type (Class_Wide_Type (gnat_entity)) == gnat_entity)
9746 save_gnu_tree (Class_Wide_Type (gnat_entity), gnu_new, false);
9747
9748 /* If we have an old type and we've made pointers to this type, update those
9749 pointers. If this is a Taft amendment type in the main unit, we need to
9750 mark the type as used since other units referencing it don't see the full
9751 declaration and, therefore, cannot mark it as used themselves. */
9752 if (gnu_old)
9753 {
9754 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
9755 TREE_TYPE (gnu_new));
9756 if (TYPE_DUMMY_IN_PROFILE_P (TREE_TYPE (gnu_old)))
9757 update_profiles_with (TREE_TYPE (gnu_old));
9758 if (DECL_TAFT_TYPE_P (gnu_old))
9759 used_types_insert (TREE_TYPE (gnu_new));
9760 }
9761 }
9762
9763 /* Elaborate decls in the lists GNAT_DECLS and GNAT_DECLS2, if present.
9764 We make two passes, one to elaborate anything other than bodies (but
9765 we declare a function if there was no spec). The second pass
9766 elaborates the bodies.
9767
9768 GNAT_END_LIST gives the element in the list past the end. Normally,
9769 this is Empty, but can be First_Real_Statement for a
9770 Handled_Sequence_Of_Statements.
9771
9772 We make a complete pass through both lists if PASS1P is true, then make
9773 the second pass over both lists if PASS2P is true. The lists usually
9774 correspond to the public and private parts of a package. */
9775
9776 static void
process_decls(List_Id gnat_decls,List_Id gnat_decls2,Node_Id gnat_end_list,bool pass1p,bool pass2p)9777 process_decls (List_Id gnat_decls, List_Id gnat_decls2,
9778 Node_Id gnat_end_list, bool pass1p, bool pass2p)
9779 {
9780 List_Id gnat_decl_array[2];
9781 Node_Id gnat_decl;
9782 int i;
9783
9784 gnat_decl_array[0] = gnat_decls, gnat_decl_array[1] = gnat_decls2;
9785
9786 if (pass1p)
9787 for (i = 0; i <= 1; i++)
9788 if (Present (gnat_decl_array[i]))
9789 for (gnat_decl = First (gnat_decl_array[i]);
9790 gnat_decl != gnat_end_list; gnat_decl = Next (gnat_decl))
9791 {
9792 /* For package specs, we recurse inside the declarations,
9793 thus taking the two pass approach inside the boundary. */
9794 if (Nkind (gnat_decl) == N_Package_Declaration
9795 && (Nkind (Specification (gnat_decl)
9796 == N_Package_Specification)))
9797 process_decls (Visible_Declarations (Specification (gnat_decl)),
9798 Private_Declarations (Specification (gnat_decl)),
9799 Empty, true, false);
9800
9801 /* Similarly for any declarations in the actions of a
9802 freeze node. */
9803 else if (Nkind (gnat_decl) == N_Freeze_Entity)
9804 {
9805 process_freeze_entity (gnat_decl);
9806 process_decls (Actions (gnat_decl), Empty, Empty, true, false);
9807 }
9808
9809 /* Package bodies with freeze nodes get their elaboration deferred
9810 until the freeze node, but the code must be placed in the right
9811 place, so record the code position now. */
9812 else if (Nkind (gnat_decl) == N_Package_Body
9813 && Present (Freeze_Node (Corresponding_Spec (gnat_decl))))
9814 record_code_position (gnat_decl);
9815
9816 else if (Nkind (gnat_decl) == N_Package_Body_Stub
9817 && Present (Library_Unit (gnat_decl))
9818 && Present (Freeze_Node
9819 (Corresponding_Spec
9820 (Proper_Body (Unit
9821 (Library_Unit (gnat_decl)))))))
9822 record_code_position
9823 (Proper_Body (Unit (Library_Unit (gnat_decl))));
9824
9825 /* We defer most subprogram bodies to the second pass. */
9826 else if (Nkind (gnat_decl) == N_Subprogram_Body)
9827 {
9828 if (Acts_As_Spec (gnat_decl))
9829 {
9830 Node_Id gnat_subprog_id = Defining_Entity (gnat_decl);
9831
9832 if (Ekind (gnat_subprog_id) != E_Generic_Procedure
9833 && Ekind (gnat_subprog_id) != E_Generic_Function)
9834 gnat_to_gnu_entity (gnat_subprog_id, NULL_TREE, true);
9835 }
9836 }
9837
9838 /* For bodies and stubs that act as their own specs, the entity
9839 itself must be elaborated in the first pass, because it may
9840 be used in other declarations. */
9841 else if (Nkind (gnat_decl) == N_Subprogram_Body_Stub)
9842 {
9843 Node_Id gnat_subprog_id
9844 = Defining_Entity (Specification (gnat_decl));
9845
9846 if (Ekind (gnat_subprog_id) != E_Subprogram_Body
9847 && Ekind (gnat_subprog_id) != E_Generic_Procedure
9848 && Ekind (gnat_subprog_id) != E_Generic_Function)
9849 gnat_to_gnu_entity (gnat_subprog_id, NULL_TREE, true);
9850 }
9851
9852 /* Concurrent stubs stand for the corresponding subprogram bodies,
9853 which are deferred like other bodies. */
9854 else if (Nkind (gnat_decl) == N_Task_Body_Stub
9855 || Nkind (gnat_decl) == N_Protected_Body_Stub)
9856 ;
9857
9858 /* Renamed subprograms may not be elaborated yet at this point
9859 since renamings do not trigger freezing. Wait for the second
9860 pass to take care of them. */
9861 else if (Nkind (gnat_decl) == N_Subprogram_Renaming_Declaration)
9862 ;
9863
9864 else
9865 add_stmt (gnat_to_gnu (gnat_decl));
9866 }
9867
9868 /* Here we elaborate everything we deferred above except for package bodies,
9869 which are elaborated at their freeze nodes. Note that we must also
9870 go inside things (package specs and freeze nodes) the first pass did. */
9871 if (pass2p)
9872 for (i = 0; i <= 1; i++)
9873 if (Present (gnat_decl_array[i]))
9874 for (gnat_decl = First (gnat_decl_array[i]);
9875 gnat_decl != gnat_end_list; gnat_decl = Next (gnat_decl))
9876 {
9877 if (Nkind (gnat_decl) == N_Subprogram_Body
9878 || Nkind (gnat_decl) == N_Subprogram_Body_Stub
9879 || Nkind (gnat_decl) == N_Task_Body_Stub
9880 || Nkind (gnat_decl) == N_Protected_Body_Stub)
9881 add_stmt (gnat_to_gnu (gnat_decl));
9882
9883 else if (Nkind (gnat_decl) == N_Package_Declaration
9884 && (Nkind (Specification (gnat_decl)
9885 == N_Package_Specification)))
9886 process_decls (Visible_Declarations (Specification (gnat_decl)),
9887 Private_Declarations (Specification (gnat_decl)),
9888 Empty, false, true);
9889
9890 else if (Nkind (gnat_decl) == N_Freeze_Entity)
9891 process_decls (Actions (gnat_decl), Empty, Empty, false, true);
9892
9893 else if (Nkind (gnat_decl) == N_Subprogram_Renaming_Declaration)
9894 add_stmt (gnat_to_gnu (gnat_decl));
9895 }
9896 }
9897
9898 /* Make a unary operation of kind CODE using build_unary_op, but guard
9899 the operation by an overflow check. CODE can be one of NEGATE_EXPR
9900 or ABS_EXPR. GNU_TYPE is the type desired for the result. Usually
9901 the operation is to be performed in that type. GNAT_NODE is the gnat
9902 node conveying the source location for which the error should be
9903 signaled. */
9904
9905 static tree
build_unary_op_trapv(enum tree_code code,tree gnu_type,tree operand,Node_Id gnat_node)9906 build_unary_op_trapv (enum tree_code code, tree gnu_type, tree operand,
9907 Node_Id gnat_node)
9908 {
9909 gcc_assert (code == NEGATE_EXPR || code == ABS_EXPR);
9910
9911 operand = gnat_protect_expr (operand);
9912
9913 return emit_check (build_binary_op (EQ_EXPR, boolean_type_node,
9914 operand, TYPE_MIN_VALUE (gnu_type)),
9915 build_unary_op (code, gnu_type, operand),
9916 CE_Overflow_Check_Failed, gnat_node);
9917 }
9918
9919 /* Make a binary operation of kind CODE using build_binary_op, but guard
9920 the operation by an overflow check. CODE can be one of PLUS_EXPR,
9921 MINUS_EXPR or MULT_EXPR. GNU_TYPE is the type desired for the result.
9922 Usually the operation is to be performed in that type. GNAT_NODE is
9923 the GNAT node conveying the source location for which the error should
9924 be signaled. */
9925
9926 static tree
build_binary_op_trapv(enum tree_code code,tree gnu_type,tree left,tree right,Node_Id gnat_node)9927 build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left,
9928 tree right, Node_Id gnat_node)
9929 {
9930 const unsigned int precision = TYPE_PRECISION (gnu_type);
9931 tree lhs = gnat_protect_expr (left);
9932 tree rhs = gnat_protect_expr (right);
9933 tree type_max = TYPE_MAX_VALUE (gnu_type);
9934 tree type_min = TYPE_MIN_VALUE (gnu_type);
9935 tree gnu_expr, check;
9936 int sgn;
9937
9938 /* Assert that the precision is a power of 2. */
9939 gcc_assert ((precision & (precision - 1)) == 0);
9940
9941 /* Prefer a constant on the RHS to simplify checks. */
9942 if (TREE_CODE (rhs) != INTEGER_CST
9943 && TREE_CODE (lhs) == INTEGER_CST
9944 && (code == PLUS_EXPR || code == MULT_EXPR))
9945 {
9946 tree tmp = lhs;
9947 lhs = rhs;
9948 rhs = tmp;
9949 }
9950
9951 gnu_expr = build_binary_op (code, gnu_type, lhs, rhs);
9952
9953 /* If we can fold the expression to a constant, just return it.
9954 The caller will deal with overflow, no need to generate a check. */
9955 if (TREE_CODE (gnu_expr) == INTEGER_CST)
9956 return gnu_expr;
9957
9958 /* If no operand is a constant, we use the generic implementation. */
9959 if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (rhs) != INTEGER_CST)
9960 {
9961 /* Never inline a 64-bit mult for a 32-bit target, it's way too long. */
9962 if (code == MULT_EXPR && precision == 64 && BITS_PER_WORD < 64)
9963 {
9964 tree int64 = gnat_type_for_size (64, 0);
9965 return convert (gnu_type, build_call_n_expr (mulv64_decl, 2,
9966 convert (int64, lhs),
9967 convert (int64, rhs)));
9968 }
9969
9970 enum internal_fn icode;
9971
9972 switch (code)
9973 {
9974 case PLUS_EXPR:
9975 icode = IFN_ADD_OVERFLOW;
9976 break;
9977 case MINUS_EXPR:
9978 icode = IFN_SUB_OVERFLOW;
9979 break;
9980 case MULT_EXPR:
9981 icode = IFN_MUL_OVERFLOW;
9982 break;
9983 default:
9984 gcc_unreachable ();
9985 }
9986
9987 tree gnu_ctype = build_complex_type (gnu_type);
9988 tree call
9989 = build_call_expr_internal_loc (UNKNOWN_LOCATION, icode, gnu_ctype, 2,
9990 lhs, rhs);
9991 tree tgt = save_expr (call);
9992 gnu_expr = build1 (REALPART_EXPR, gnu_type, tgt);
9993 check = fold_build2 (NE_EXPR, boolean_type_node,
9994 build1 (IMAGPART_EXPR, gnu_type, tgt),
9995 build_int_cst (gnu_type, 0));
9996 return
9997 emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node);
9998 }
9999
10000 /* If one operand is a constant, we expose the overflow condition to enable
10001 a subsequent simplication or even elimination. */
10002 switch (code)
10003 {
10004 case PLUS_EXPR:
10005 sgn = tree_int_cst_sgn (rhs);
10006 if (sgn > 0)
10007 /* When rhs > 0, overflow when lhs > type_max - rhs. */
10008 check = build_binary_op (GT_EXPR, boolean_type_node, lhs,
10009 build_binary_op (MINUS_EXPR, gnu_type,
10010 type_max, rhs));
10011 else if (sgn < 0)
10012 /* When rhs < 0, overflow when lhs < type_min - rhs. */
10013 check = build_binary_op (LT_EXPR, boolean_type_node, lhs,
10014 build_binary_op (MINUS_EXPR, gnu_type,
10015 type_min, rhs));
10016 else
10017 return gnu_expr;
10018 break;
10019
10020 case MINUS_EXPR:
10021 if (TREE_CODE (lhs) == INTEGER_CST)
10022 {
10023 sgn = tree_int_cst_sgn (lhs);
10024 if (sgn > 0)
10025 /* When lhs > 0, overflow when rhs < lhs - type_max. */
10026 check = build_binary_op (LT_EXPR, boolean_type_node, rhs,
10027 build_binary_op (MINUS_EXPR, gnu_type,
10028 lhs, type_max));
10029 else if (sgn < 0)
10030 /* When lhs < 0, overflow when rhs > lhs - type_min. */
10031 check = build_binary_op (GT_EXPR, boolean_type_node, rhs,
10032 build_binary_op (MINUS_EXPR, gnu_type,
10033 lhs, type_min));
10034 else
10035 return gnu_expr;
10036 }
10037 else
10038 {
10039 sgn = tree_int_cst_sgn (rhs);
10040 if (sgn > 0)
10041 /* When rhs > 0, overflow when lhs < type_min + rhs. */
10042 check = build_binary_op (LT_EXPR, boolean_type_node, lhs,
10043 build_binary_op (PLUS_EXPR, gnu_type,
10044 type_min, rhs));
10045 else if (sgn < 0)
10046 /* When rhs < 0, overflow when lhs > type_max + rhs. */
10047 check = build_binary_op (GT_EXPR, boolean_type_node, lhs,
10048 build_binary_op (PLUS_EXPR, gnu_type,
10049 type_max, rhs));
10050 else
10051 return gnu_expr;
10052 }
10053 break;
10054
10055 case MULT_EXPR:
10056 sgn = tree_int_cst_sgn (rhs);
10057 if (sgn > 0)
10058 {
10059 if (integer_onep (rhs))
10060 return gnu_expr;
10061
10062 tree lb = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_min, rhs);
10063 tree ub = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_max, rhs);
10064
10065 /* When rhs > 1, overflow outside [type_min/rhs; type_max/rhs]. */
10066 check
10067 = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
10068 build_binary_op (LT_EXPR, boolean_type_node,
10069 lhs, lb),
10070 build_binary_op (GT_EXPR, boolean_type_node,
10071 lhs, ub));
10072 }
10073 else if (sgn < 0)
10074 {
10075 tree lb = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_max, rhs);
10076 tree ub = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_min, rhs);
10077
10078 if (integer_minus_onep (rhs))
10079 /* When rhs == -1, overflow if lhs == type_min. */
10080 check
10081 = build_binary_op (EQ_EXPR, boolean_type_node, lhs, type_min);
10082 else
10083 /* When rhs < -1, overflow outside [type_max/rhs; type_min/rhs]. */
10084 check
10085 = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
10086 build_binary_op (LT_EXPR, boolean_type_node,
10087 lhs, lb),
10088 build_binary_op (GT_EXPR, boolean_type_node,
10089 lhs, ub));
10090 }
10091 else
10092 return gnu_expr;
10093 break;
10094
10095 default:
10096 gcc_unreachable ();
10097 }
10098
10099 return emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node);
10100 }
10101
10102 /* GNU_COND contains the condition corresponding to an index, overflow or
10103 range check of value GNU_EXPR. Build a COND_EXPR that returns GNU_EXPR
10104 if GNU_COND is false and raises a CONSTRAINT_ERROR if GNU_COND is true.
10105 REASON is the code that says why the exception is raised. GNAT_NODE is
10106 the node conveying the source location for which the error should be
10107 signaled.
10108
10109 We used to propagate TREE_SIDE_EFFECTS from GNU_EXPR to the COND_EXPR,
10110 overwriting the setting inherited from the call statement, on the ground
10111 that the expression need not be evaluated just for the check. However
10112 that's incorrect because, in the GCC type system, its value is presumed
10113 to be valid so its comparison against the type bounds always yields true
10114 and, therefore, could be done without evaluating it; given that it can
10115 be a computation that overflows the bounds, the language may require the
10116 check to fail and thus the expression to be evaluated in this case. */
10117
10118 static tree
emit_check(tree gnu_cond,tree gnu_expr,int reason,Node_Id gnat_node)10119 emit_check (tree gnu_cond, tree gnu_expr, int reason, Node_Id gnat_node)
10120 {
10121 tree gnu_call
10122 = build_call_raise (reason, gnat_node, N_Raise_Constraint_Error);
10123 return
10124 fold_build3 (COND_EXPR, TREE_TYPE (gnu_expr), gnu_cond,
10125 build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr), gnu_call,
10126 SCALAR_FLOAT_TYPE_P (TREE_TYPE (gnu_expr))
10127 ? build_real (TREE_TYPE (gnu_expr), dconst0)
10128 : build_int_cst (TREE_TYPE (gnu_expr), 0)),
10129 gnu_expr);
10130 }
10131
10132 /* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing overflow
10133 checks if OVERFLOW_P is true. If TRUNCATE_P is true, do a fp-to-integer
10134 conversion with truncation, otherwise round. GNAT_NODE is the GNAT node
10135 conveying the source location for which the error should be signaled. */
10136
10137 static tree
convert_with_check(Entity_Id gnat_type,tree gnu_expr,bool overflow_p,bool truncate_p,Node_Id gnat_node)10138 convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p,
10139 bool truncate_p, Node_Id gnat_node)
10140 {
10141 tree gnu_type = get_unpadded_type (gnat_type);
10142 tree gnu_base_type = get_base_type (gnu_type);
10143 tree gnu_in_type = TREE_TYPE (gnu_expr);
10144 tree gnu_in_base_type = get_base_type (gnu_in_type);
10145 tree gnu_result = gnu_expr;
10146
10147 /* If we are not doing any checks, the output is an integral type and the
10148 input is not a floating-point type, just do the conversion. This is
10149 required for packed array types and is simpler in all cases anyway. */
10150 if (!overflow_p
10151 && INTEGRAL_TYPE_P (gnu_base_type)
10152 && !FLOAT_TYPE_P (gnu_in_base_type))
10153 return convert (gnu_type, gnu_expr);
10154
10155 /* If the mode of the input base type is larger, then converting to it below
10156 may pessimize the final conversion step, for example generate a libcall
10157 instead of a simple instruction, so use a narrower type in this case. */
10158 if (TYPE_MODE (gnu_in_base_type) != TYPE_MODE (gnu_in_type)
10159 && !(TREE_CODE (gnu_in_type) == INTEGER_TYPE
10160 && TYPE_BIASED_REPRESENTATION_P (gnu_in_type)))
10161 gnu_in_base_type = gnat_type_for_mode (TYPE_MODE (gnu_in_type),
10162 TYPE_UNSIGNED (gnu_in_type));
10163
10164 /* First convert the expression to the base type. This will never generate
10165 code, but makes the tests below simpler. But don't do this if converting
10166 from an integer type to an unconstrained array type since then we need to
10167 get the bounds from the original (unpacked) type. */
10168 if (TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE)
10169 gnu_result = convert (gnu_in_base_type, gnu_result);
10170
10171 /* If overflow checks are requested, we need to be sure the result will fit
10172 in the output base type. But don't do this if the input is integer and
10173 the output floating-point. */
10174 if (overflow_p
10175 && !(FLOAT_TYPE_P (gnu_base_type) && INTEGRAL_TYPE_P (gnu_in_base_type)))
10176 {
10177 /* Ensure GNU_EXPR only gets evaluated once. */
10178 tree gnu_input = gnat_protect_expr (gnu_result);
10179 tree gnu_cond = boolean_false_node;
10180 tree gnu_in_lb = TYPE_MIN_VALUE (gnu_in_base_type);
10181 tree gnu_in_ub = TYPE_MAX_VALUE (gnu_in_base_type);
10182 tree gnu_out_lb = TYPE_MIN_VALUE (gnu_base_type);
10183 tree gnu_out_ub
10184 = (TREE_CODE (gnu_base_type) == INTEGER_TYPE
10185 && TYPE_MODULAR_P (gnu_base_type))
10186 ? fold_build2 (MINUS_EXPR, gnu_base_type,
10187 TYPE_MODULUS (gnu_base_type),
10188 build_int_cst (gnu_base_type, 1))
10189 : TYPE_MAX_VALUE (gnu_base_type);
10190
10191 /* Convert the lower bounds to signed types, so we're sure we're
10192 comparing them properly. Likewise, convert the upper bounds
10193 to unsigned types. */
10194 if (INTEGRAL_TYPE_P (gnu_in_base_type)
10195 && TYPE_UNSIGNED (gnu_in_base_type))
10196 gnu_in_lb
10197 = convert (gnat_signed_type_for (gnu_in_base_type), gnu_in_lb);
10198
10199 if (INTEGRAL_TYPE_P (gnu_in_base_type)
10200 && !TYPE_UNSIGNED (gnu_in_base_type))
10201 gnu_in_ub
10202 = convert (gnat_unsigned_type_for (gnu_in_base_type), gnu_in_ub);
10203
10204 if (INTEGRAL_TYPE_P (gnu_base_type) && TYPE_UNSIGNED (gnu_base_type))
10205 gnu_out_lb
10206 = convert (gnat_signed_type_for (gnu_base_type), gnu_out_lb);
10207
10208 if (INTEGRAL_TYPE_P (gnu_base_type) && !TYPE_UNSIGNED (gnu_base_type))
10209 gnu_out_ub
10210 = convert (gnat_unsigned_type_for (gnu_base_type), gnu_out_ub);
10211
10212 /* Check each bound separately and only if the result bound
10213 is tighter than the bound on the input type. Note that all the
10214 types are base types, so the bounds must be constant. Also,
10215 the comparison is done in the base type of the input, which
10216 always has the proper signedness. First check for input
10217 integer (which means output integer), output float (which means
10218 both float), or mixed, in which case we always compare.
10219 Note that we have to do the comparison which would *fail* in the
10220 case of an error since if it's an FP comparison and one of the
10221 values is a NaN or Inf, the comparison will fail. */
10222 if (INTEGRAL_TYPE_P (gnu_in_base_type)
10223 ? tree_int_cst_lt (gnu_in_lb, gnu_out_lb)
10224 : (FLOAT_TYPE_P (gnu_base_type)
10225 ? real_less (&TREE_REAL_CST (gnu_in_lb),
10226 &TREE_REAL_CST (gnu_out_lb))
10227 : 1))
10228 gnu_cond
10229 = invert_truthvalue
10230 (build_binary_op (GE_EXPR, boolean_type_node,
10231 gnu_input, convert (gnu_in_base_type,
10232 gnu_out_lb)));
10233
10234 if (INTEGRAL_TYPE_P (gnu_in_base_type)
10235 ? tree_int_cst_lt (gnu_out_ub, gnu_in_ub)
10236 : (FLOAT_TYPE_P (gnu_base_type)
10237 ? real_less (&TREE_REAL_CST (gnu_out_ub),
10238 &TREE_REAL_CST (gnu_in_ub))
10239 : 1))
10240 gnu_cond
10241 = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, gnu_cond,
10242 invert_truthvalue
10243 (build_binary_op (LE_EXPR, boolean_type_node,
10244 gnu_input,
10245 convert (gnu_in_base_type,
10246 gnu_out_ub))));
10247
10248 if (!integer_zerop (gnu_cond))
10249 gnu_result = emit_check (gnu_cond, gnu_input,
10250 CE_Overflow_Check_Failed, gnat_node);
10251 }
10252
10253 /* Now convert to the result base type. If this is a non-truncating
10254 float-to-integer conversion, round. */
10255 if (INTEGRAL_TYPE_P (gnu_base_type)
10256 && FLOAT_TYPE_P (gnu_in_base_type)
10257 && !truncate_p)
10258 {
10259 REAL_VALUE_TYPE half_minus_pred_half, pred_half;
10260 tree gnu_conv, gnu_zero, gnu_comp, calc_type;
10261 tree gnu_pred_half, gnu_add_pred_half, gnu_subtract_pred_half;
10262 const struct real_format *fmt;
10263
10264 /* The following calculations depend on proper rounding to even
10265 of each arithmetic operation. In order to prevent excess
10266 precision from spoiling this property, use the widest hardware
10267 floating-point type if FP_ARITH_MAY_WIDEN is true. */
10268 calc_type
10269 = fp_arith_may_widen ? longest_float_type_node : gnu_in_base_type;
10270
10271 /* Compute the exact value calc_type'Pred (0.5) at compile time. */
10272 fmt = REAL_MODE_FORMAT (TYPE_MODE (calc_type));
10273 real_2expN (&half_minus_pred_half, -(fmt->p) - 1, TYPE_MODE (calc_type));
10274 real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf,
10275 &half_minus_pred_half);
10276 gnu_pred_half = build_real (calc_type, pred_half);
10277
10278 /* If the input is strictly negative, subtract this value
10279 and otherwise add it from the input. For 0.5, the result
10280 is exactly between 1.0 and the machine number preceding 1.0
10281 (for calc_type). Since the last bit of 1.0 is even, this 0.5
10282 will round to 1.0, while all other number with an absolute
10283 value less than 0.5 round to 0.0. For larger numbers exactly
10284 halfway between integers, rounding will always be correct as
10285 the true mathematical result will be closer to the higher
10286 integer compared to the lower one. So, this constant works
10287 for all floating-point numbers.
10288
10289 The reason to use the same constant with subtract/add instead
10290 of a positive and negative constant is to allow the comparison
10291 to be scheduled in parallel with retrieval of the constant and
10292 conversion of the input to the calc_type (if necessary). */
10293
10294 gnu_zero = build_real (gnu_in_base_type, dconst0);
10295 gnu_result = gnat_protect_expr (gnu_result);
10296 gnu_conv = convert (calc_type, gnu_result);
10297 gnu_comp
10298 = fold_build2 (GE_EXPR, boolean_type_node, gnu_result, gnu_zero);
10299 gnu_add_pred_half
10300 = fold_build2 (PLUS_EXPR, calc_type, gnu_conv, gnu_pred_half);
10301 gnu_subtract_pred_half
10302 = fold_build2 (MINUS_EXPR, calc_type, gnu_conv, gnu_pred_half);
10303 gnu_result = fold_build3 (COND_EXPR, calc_type, gnu_comp,
10304 gnu_add_pred_half, gnu_subtract_pred_half);
10305 }
10306
10307 if (TREE_CODE (gnu_base_type) == INTEGER_TYPE
10308 && TYPE_HAS_ACTUAL_BOUNDS_P (gnu_base_type)
10309 && TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF)
10310 gnu_result = unchecked_convert (gnu_base_type, gnu_result, false);
10311 else
10312 gnu_result = convert (gnu_base_type, gnu_result);
10313
10314 return convert (gnu_type, gnu_result);
10315 }
10316
10317 /* Return true if GNU_EXPR can be directly addressed. This is the case
10318 unless it is an expression involving computation or if it involves a
10319 reference to a bitfield or to an object not sufficiently aligned for
10320 its type. If GNU_TYPE is non-null, return true only if GNU_EXPR can
10321 be directly addressed as an object of this type.
10322
10323 *** Notes on addressability issues in the Ada compiler ***
10324
10325 This predicate is necessary in order to bridge the gap between Gigi
10326 and the middle-end about addressability of GENERIC trees. A tree
10327 is said to be addressable if it can be directly addressed, i.e. if
10328 its address can be taken, is a multiple of the type's alignment on
10329 strict-alignment architectures and returns the first storage unit
10330 assigned to the object represented by the tree.
10331
10332 In the C family of languages, everything is in practice addressable
10333 at the language level, except for bit-fields. This means that these
10334 compilers will take the address of any tree that doesn't represent
10335 a bit-field reference and expect the result to be the first storage
10336 unit assigned to the object. Even in cases where this will result
10337 in unaligned accesses at run time, nothing is supposed to be done
10338 and the program is considered as erroneous instead (see PR c/18287).
10339
10340 The implicit assumptions made in the middle-end are in keeping with
10341 the C viewpoint described above:
10342 - the address of a bit-field reference is supposed to be never
10343 taken; the compiler (generally) will stop on such a construct,
10344 - any other tree is addressable if it is formally addressable,
10345 i.e. if it is formally allowed to be the operand of ADDR_EXPR.
10346
10347 In Ada, the viewpoint is the opposite one: nothing is addressable
10348 at the language level unless explicitly declared so. This means
10349 that the compiler will both make sure that the trees representing
10350 references to addressable ("aliased" in Ada parlance) objects are
10351 addressable and make no real attempts at ensuring that the trees
10352 representing references to non-addressable objects are addressable.
10353
10354 In the first case, Ada is effectively equivalent to C and handing
10355 down the direct result of applying ADDR_EXPR to these trees to the
10356 middle-end works flawlessly. In the second case, Ada cannot afford
10357 to consider the program as erroneous if the address of trees that
10358 are not addressable is requested for technical reasons, unlike C;
10359 as a consequence, the Ada compiler must arrange for either making
10360 sure that this address is not requested in the middle-end or for
10361 compensating by inserting temporaries if it is requested in Gigi.
10362
10363 The first goal can be achieved because the middle-end should not
10364 request the address of non-addressable trees on its own; the only
10365 exception is for the invocation of low-level block operations like
10366 memcpy, for which the addressability requirements are lower since
10367 the type's alignment can be disregarded. In practice, this means
10368 that Gigi must make sure that such operations cannot be applied to
10369 non-BLKmode bit-fields.
10370
10371 The second goal is achieved by means of the addressable_p predicate,
10372 which computes whether a temporary must be inserted by Gigi when the
10373 address of a tree is requested; if so, the address of the temporary
10374 will be used in lieu of that of the original tree and some glue code
10375 generated to connect everything together. */
10376
10377 static bool
addressable_p(tree gnu_expr,tree gnu_type)10378 addressable_p (tree gnu_expr, tree gnu_type)
10379 {
10380 /* For an integral type, the size of the actual type of the object may not
10381 be greater than that of the expected type, otherwise an indirect access
10382 in the latter type wouldn't correctly set all the bits of the object. */
10383 if (gnu_type
10384 && INTEGRAL_TYPE_P (gnu_type)
10385 && smaller_form_type_p (gnu_type, TREE_TYPE (gnu_expr)))
10386 return false;
10387
10388 /* The size of the actual type of the object may not be smaller than that
10389 of the expected type, otherwise an indirect access in the latter type
10390 would be larger than the object. But only record types need to be
10391 considered in practice for this case. */
10392 if (gnu_type
10393 && TREE_CODE (gnu_type) == RECORD_TYPE
10394 && smaller_form_type_p (TREE_TYPE (gnu_expr), gnu_type))
10395 return false;
10396
10397 switch (TREE_CODE (gnu_expr))
10398 {
10399 case VAR_DECL:
10400 case PARM_DECL:
10401 case FUNCTION_DECL:
10402 case RESULT_DECL:
10403 /* All DECLs are addressable: if they are in a register, we can force
10404 them to memory. */
10405 return true;
10406
10407 case UNCONSTRAINED_ARRAY_REF:
10408 case INDIRECT_REF:
10409 /* Taking the address of a dereference yields the original pointer. */
10410 return true;
10411
10412 case STRING_CST:
10413 case INTEGER_CST:
10414 case REAL_CST:
10415 /* Taking the address yields a pointer to the constant pool. */
10416 return true;
10417
10418 case CONSTRUCTOR:
10419 /* Taking the address of a static constructor yields a pointer to the
10420 tree constant pool. */
10421 return TREE_STATIC (gnu_expr) ? true : false;
10422
10423 case NULL_EXPR:
10424 case ADDR_EXPR:
10425 case SAVE_EXPR:
10426 case CALL_EXPR:
10427 case PLUS_EXPR:
10428 case MINUS_EXPR:
10429 case BIT_IOR_EXPR:
10430 case BIT_XOR_EXPR:
10431 case BIT_AND_EXPR:
10432 case BIT_NOT_EXPR:
10433 /* All rvalues are deemed addressable since taking their address will
10434 force a temporary to be created by the middle-end. */
10435 return true;
10436
10437 case COMPOUND_EXPR:
10438 /* The address of a compound expression is that of its 2nd operand. */
10439 return addressable_p (TREE_OPERAND (gnu_expr, 1), gnu_type);
10440
10441 case COND_EXPR:
10442 /* We accept &COND_EXPR as soon as both operands are addressable and
10443 expect the outcome to be the address of the selected operand. */
10444 return (addressable_p (TREE_OPERAND (gnu_expr, 1), NULL_TREE)
10445 && addressable_p (TREE_OPERAND (gnu_expr, 2), NULL_TREE));
10446
10447 case COMPONENT_REF:
10448 return (((!DECL_BIT_FIELD (TREE_OPERAND (gnu_expr, 1))
10449 /* Even with DECL_BIT_FIELD cleared, we have to ensure that
10450 the field is sufficiently aligned, in case it is subject
10451 to a pragma Component_Alignment. But we don't need to
10452 check the alignment of the containing record, as it is
10453 guaranteed to be not smaller than that of its most
10454 aligned field that is not a bit-field. */
10455 && (!STRICT_ALIGNMENT
10456 || DECL_ALIGN (TREE_OPERAND (gnu_expr, 1))
10457 >= TYPE_ALIGN (TREE_TYPE (gnu_expr))))
10458 /* The field of a padding record is always addressable. */
10459 || TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_expr, 0))))
10460 && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE));
10461
10462 case ARRAY_REF: case ARRAY_RANGE_REF:
10463 case REALPART_EXPR: case IMAGPART_EXPR:
10464 case NOP_EXPR:
10465 return addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE);
10466
10467 case CONVERT_EXPR:
10468 return (AGGREGATE_TYPE_P (TREE_TYPE (gnu_expr))
10469 && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE));
10470
10471 case VIEW_CONVERT_EXPR:
10472 {
10473 /* This is addressable if we can avoid a copy. */
10474 tree type = TREE_TYPE (gnu_expr);
10475 tree inner_type = TREE_TYPE (TREE_OPERAND (gnu_expr, 0));
10476 return (((TYPE_MODE (type) == TYPE_MODE (inner_type)
10477 && (!STRICT_ALIGNMENT
10478 || TYPE_ALIGN (type) <= TYPE_ALIGN (inner_type)
10479 || TYPE_ALIGN (inner_type) >= BIGGEST_ALIGNMENT))
10480 || ((TYPE_MODE (type) == BLKmode
10481 || TYPE_MODE (inner_type) == BLKmode)
10482 && (!STRICT_ALIGNMENT
10483 || TYPE_ALIGN (type) <= TYPE_ALIGN (inner_type)
10484 || TYPE_ALIGN (inner_type) >= BIGGEST_ALIGNMENT
10485 || TYPE_ALIGN_OK (type)
10486 || TYPE_ALIGN_OK (inner_type))))
10487 && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE));
10488 }
10489
10490 default:
10491 return false;
10492 }
10493 }
10494
10495 /* Do the processing for the declaration of a GNAT_ENTITY, a type or subtype.
10496 If a Freeze node exists for the entity, delay the bulk of the processing.
10497 Otherwise make a GCC type for GNAT_ENTITY and set up the correspondence. */
10498
10499 void
process_type(Entity_Id gnat_entity)10500 process_type (Entity_Id gnat_entity)
10501 {
10502 tree gnu_old
10503 = present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity) : NULL_TREE;
10504
10505 /* If we are to delay elaboration of this type, just do any elaboration
10506 needed for expressions within the declaration and make a dummy node
10507 for it and its Full_View (if any), in case something points to it.
10508 Do not do this if it has already been done (the only way that can
10509 happen is if the private completion is also delayed). */
10510 if (Present (Freeze_Node (gnat_entity)))
10511 {
10512 elaborate_entity (gnat_entity);
10513
10514 if (!gnu_old)
10515 {
10516 tree gnu_decl = TYPE_STUB_DECL (make_dummy_type (gnat_entity));
10517 save_gnu_tree (gnat_entity, gnu_decl, false);
10518 if (Is_Incomplete_Or_Private_Type (gnat_entity)
10519 && Present (Full_View (gnat_entity)))
10520 {
10521 if (Has_Completion_In_Body (gnat_entity))
10522 DECL_TAFT_TYPE_P (gnu_decl) = 1;
10523 save_gnu_tree (Full_View (gnat_entity), gnu_decl, false);
10524 }
10525 }
10526
10527 return;
10528 }
10529
10530 /* If we saved away a dummy type for this node, it means that this made the
10531 type that corresponds to the full type of an incomplete type. Clear that
10532 type for now and then update the type in the pointers below. But, if the
10533 saved type is not dummy, it very likely means that we have a use before
10534 declaration for the type in the tree, what we really cannot handle. */
10535 if (gnu_old)
10536 {
10537 gcc_assert (TREE_CODE (gnu_old) == TYPE_DECL
10538 && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old)));
10539
10540 save_gnu_tree (gnat_entity, NULL_TREE, false);
10541 }
10542
10543 /* Now fully elaborate the type. */
10544 tree gnu_new = gnat_to_gnu_entity (gnat_entity, NULL_TREE, true);
10545 gcc_assert (TREE_CODE (gnu_new) == TYPE_DECL);
10546
10547 /* If we have an old type and we've made pointers to this type, update those
10548 pointers. If this is a Taft amendment type in the main unit, we need to
10549 mark the type as used since other units referencing it don't see the full
10550 declaration and, therefore, cannot mark it as used themselves. */
10551 if (gnu_old)
10552 {
10553 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
10554 TREE_TYPE (gnu_new));
10555 if (DECL_TAFT_TYPE_P (gnu_old))
10556 used_types_insert (TREE_TYPE (gnu_new));
10557 }
10558
10559 /* If this is a record type corresponding to a task or protected type
10560 that is a completion of an incomplete type, perform a similar update
10561 on the type. ??? Including protected types here is a guess. */
10562 if (Is_Record_Type (gnat_entity)
10563 && Is_Concurrent_Record_Type (gnat_entity)
10564 && present_gnu_tree (Corresponding_Concurrent_Type (gnat_entity)))
10565 {
10566 tree gnu_task_old
10567 = get_gnu_tree (Corresponding_Concurrent_Type (gnat_entity));
10568
10569 save_gnu_tree (Corresponding_Concurrent_Type (gnat_entity),
10570 NULL_TREE, false);
10571 save_gnu_tree (Corresponding_Concurrent_Type (gnat_entity),
10572 gnu_new, false);
10573
10574 update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_task_old)),
10575 TREE_TYPE (gnu_new));
10576 }
10577 }
10578
10579 /* Subroutine of assoc_to_constructor: VALUES is a list of field associations,
10580 some of which are from RECORD_TYPE. Return a CONSTRUCTOR consisting of the
10581 associations that are from RECORD_TYPE. If we see an internal record, make
10582 a recursive call to fill it in as well. */
10583
10584 static tree
extract_values(tree values,tree record_type)10585 extract_values (tree values, tree record_type)
10586 {
10587 vec<constructor_elt, va_gc> *v = NULL;
10588 tree field;
10589
10590 for (field = TYPE_FIELDS (record_type); field; field = DECL_CHAIN (field))
10591 {
10592 tree tem, value = NULL_TREE;
10593
10594 /* _Parent is an internal field, but may have values in the aggregate,
10595 so check for values first. */
10596 if ((tem = purpose_member (field, values)))
10597 {
10598 value = TREE_VALUE (tem);
10599 TREE_ADDRESSABLE (tem) = 1;
10600 }
10601
10602 else if (DECL_INTERNAL_P (field))
10603 {
10604 value = extract_values (values, TREE_TYPE (field));
10605 if (TREE_CODE (value) == CONSTRUCTOR
10606 && vec_safe_is_empty (CONSTRUCTOR_ELTS (value)))
10607 value = NULL_TREE;
10608 }
10609 else
10610 /* If we have a record subtype, the names will match, but not the
10611 actual FIELD_DECLs. */
10612 for (tem = values; tem; tem = TREE_CHAIN (tem))
10613 if (DECL_NAME (TREE_PURPOSE (tem)) == DECL_NAME (field))
10614 {
10615 value = convert (TREE_TYPE (field), TREE_VALUE (tem));
10616 TREE_ADDRESSABLE (tem) = 1;
10617 }
10618
10619 if (!value)
10620 continue;
10621
10622 CONSTRUCTOR_APPEND_ELT (v, field, value);
10623 }
10624
10625 return gnat_build_constructor (record_type, v);
10626 }
10627
10628 /* GNAT_ENTITY is the type of the resulting constructor, GNAT_ASSOC is the
10629 front of the Component_Associations of an N_Aggregate and GNU_TYPE is the
10630 GCC type of the corresponding record type. Return the CONSTRUCTOR. */
10631
10632 static tree
assoc_to_constructor(Entity_Id gnat_entity,Node_Id gnat_assoc,tree gnu_type)10633 assoc_to_constructor (Entity_Id gnat_entity, Node_Id gnat_assoc, tree gnu_type)
10634 {
10635 tree gnu_list = NULL_TREE, gnu_result;
10636
10637 /* We test for GNU_FIELD being empty in the case where a variant
10638 was the last thing since we don't take things off GNAT_ASSOC in
10639 that case. We check GNAT_ASSOC in case we have a variant, but it
10640 has no fields. */
10641
10642 for (; Present (gnat_assoc); gnat_assoc = Next (gnat_assoc))
10643 {
10644 const Node_Id gnat_field = First (Choices (gnat_assoc));
10645 const Node_Id gnat_expr = Expression (gnat_assoc);
10646 tree gnu_field = gnat_to_gnu_field_decl (Entity (gnat_field));
10647 tree gnu_expr = gnat_to_gnu (Expression (gnat_assoc));
10648
10649 /* The expander is supposed to put a single component selector name
10650 in every record component association. */
10651 gcc_assert (No (Next (gnat_field)));
10652
10653 /* Ignore discriminants that have Corresponding_Discriminants in tagged
10654 types since we'll be setting those fields in the parent subtype. */
10655 if (Ekind (Entity (gnat_field)) == E_Discriminant
10656 && Present (Corresponding_Discriminant (Entity (gnat_field)))
10657 && Is_Tagged_Type (Scope (Entity (gnat_field))))
10658 continue;
10659
10660 /* Also ignore discriminants of Unchecked_Unions. */
10661 if (Ekind (Entity (gnat_field)) == E_Discriminant
10662 && Is_Unchecked_Union (gnat_entity))
10663 continue;
10664
10665 gigi_checking_assert (!Do_Range_Check (gnat_expr));
10666
10667 /* Convert to the type of the field. */
10668 gnu_expr = convert (TREE_TYPE (gnu_field), gnu_expr);
10669
10670 /* Add the field and expression to the list. */
10671 gnu_list = tree_cons (gnu_field, gnu_expr, gnu_list);
10672 }
10673
10674 gnu_result = extract_values (gnu_list, gnu_type);
10675
10676 if (flag_checking)
10677 {
10678 /* Verify that every entry in GNU_LIST was used. */
10679 for (; gnu_list; gnu_list = TREE_CHAIN (gnu_list))
10680 gcc_assert (TREE_ADDRESSABLE (gnu_list));
10681 }
10682
10683 return gnu_result;
10684 }
10685
10686 /* Build a possibly nested constructor for array aggregates. GNAT_EXPR is
10687 the first element of an array aggregate. It may itself be an aggregate.
10688 GNU_ARRAY_TYPE is the GCC type corresponding to the array aggregate. */
10689
10690 static tree
pos_to_constructor(Node_Id gnat_expr,tree gnu_array_type)10691 pos_to_constructor (Node_Id gnat_expr, tree gnu_array_type)
10692 {
10693 tree gnu_index = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_array_type));
10694 vec<constructor_elt, va_gc> *gnu_expr_vec = NULL;
10695
10696 for (; Present (gnat_expr); gnat_expr = Next (gnat_expr))
10697 {
10698 tree gnu_expr;
10699
10700 /* If the expression is itself an array aggregate then first build the
10701 innermost constructor if it is part of our array (multi-dimensional
10702 case). */
10703 if (Nkind (gnat_expr) == N_Aggregate
10704 && TREE_CODE (TREE_TYPE (gnu_array_type)) == ARRAY_TYPE
10705 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_array_type)))
10706 gnu_expr = pos_to_constructor (First (Expressions (gnat_expr)),
10707 TREE_TYPE (gnu_array_type));
10708 else
10709 {
10710 /* If the expression is a conversion to an unconstrained array type,
10711 skip it to avoid spilling to memory. */
10712 if (Nkind (gnat_expr) == N_Type_Conversion
10713 && Is_Array_Type (Etype (gnat_expr))
10714 && !Is_Constrained (Etype (gnat_expr)))
10715 gnu_expr = gnat_to_gnu (Expression (gnat_expr));
10716 else
10717 gnu_expr = gnat_to_gnu (gnat_expr);
10718
10719 gigi_checking_assert (!Do_Range_Check (gnat_expr));
10720 }
10721
10722 CONSTRUCTOR_APPEND_ELT (gnu_expr_vec, gnu_index,
10723 convert (TREE_TYPE (gnu_array_type), gnu_expr));
10724
10725 gnu_index = int_const_binop (PLUS_EXPR, gnu_index,
10726 convert (TREE_TYPE (gnu_index),
10727 integer_one_node));
10728 }
10729
10730 return gnat_build_constructor (gnu_array_type, gnu_expr_vec);
10731 }
10732
10733 /* Process a N_Validate_Unchecked_Conversion node. */
10734
10735 static void
validate_unchecked_conversion(Node_Id gnat_node)10736 validate_unchecked_conversion (Node_Id gnat_node)
10737 {
10738 tree gnu_source_type = gnat_to_gnu_type (Source_Type (gnat_node));
10739 tree gnu_target_type = gnat_to_gnu_type (Target_Type (gnat_node));
10740
10741 /* If the target is a pointer type, see if we are either converting from a
10742 non-pointer or from a pointer to a type with a different alias set and
10743 warn if so, unless the pointer has been marked to alias everything. */
10744 if (POINTER_TYPE_P (gnu_target_type)
10745 && !TYPE_REF_CAN_ALIAS_ALL (gnu_target_type))
10746 {
10747 tree gnu_source_desig_type = POINTER_TYPE_P (gnu_source_type)
10748 ? TREE_TYPE (gnu_source_type)
10749 : NULL_TREE;
10750 tree gnu_target_desig_type = TREE_TYPE (gnu_target_type);
10751 alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);
10752
10753 if (target_alias_set != 0
10754 && (!POINTER_TYPE_P (gnu_source_type)
10755 || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
10756 target_alias_set)))
10757 {
10758 post_error_ne ("?possible aliasing problem for type&",
10759 gnat_node, Target_Type (gnat_node));
10760 post_error ("\\?use -fno-strict-aliasing switch for references",
10761 gnat_node);
10762 post_error_ne ("\\?or use `pragma No_Strict_Aliasing (&);`",
10763 gnat_node, Target_Type (gnat_node));
10764 }
10765 }
10766
10767 /* Likewise if the target is a fat pointer type, but we have no mechanism to
10768 mitigate the problem in this case, so we unconditionally warn. */
10769 else if (TYPE_IS_FAT_POINTER_P (gnu_target_type))
10770 {
10771 tree gnu_source_desig_type
10772 = TYPE_IS_FAT_POINTER_P (gnu_source_type)
10773 ? TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_source_type)))
10774 : NULL_TREE;
10775 tree gnu_target_desig_type
10776 = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type)));
10777 alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);
10778
10779 if (target_alias_set != 0
10780 && (!TYPE_IS_FAT_POINTER_P (gnu_source_type)
10781 || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
10782 target_alias_set)))
10783 {
10784 post_error_ne ("?possible aliasing problem for type&",
10785 gnat_node, Target_Type (gnat_node));
10786 post_error ("\\?use -fno-strict-aliasing switch for references",
10787 gnat_node);
10788 }
10789 }
10790 }
10791
10792 /* EXP is to be used in a context where access objects are implicitly
10793 dereferenced. Handle the cases when it is an access object. */
10794
10795 static Node_Id
adjust_for_implicit_deref(Node_Id exp)10796 adjust_for_implicit_deref (Node_Id exp)
10797 {
10798 Entity_Id type = Underlying_Type (Etype (exp));
10799
10800 /* Make sure the designated type is complete before dereferencing. */
10801 if (Is_Access_Type (type))
10802 gnat_to_gnu_entity (Designated_Type (type), NULL_TREE, false);
10803
10804 return exp;
10805 }
10806
10807 /* EXP is to be treated as an array or record. Handle the cases when it is
10808 an access object and perform the required dereferences. */
10809
10810 static tree
maybe_implicit_deref(tree exp)10811 maybe_implicit_deref (tree exp)
10812 {
10813 /* If the type is a pointer, dereference it. */
10814 if (POINTER_TYPE_P (TREE_TYPE (exp))
10815 || TYPE_IS_FAT_POINTER_P (TREE_TYPE (exp)))
10816 exp = build_unary_op (INDIRECT_REF, NULL_TREE, exp);
10817
10818 /* If we got a padded type, remove it too. */
10819 if (TYPE_IS_PADDING_P (TREE_TYPE (exp)))
10820 exp = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (exp))), exp);
10821
10822 return exp;
10823 }
10824
10825 /* Convert SLOC into LOCUS. Return true if SLOC corresponds to a
10826 source code location and false if it doesn't. If CLEAR_COLUMN is
10827 true, set the column information to 0. If DECL is given and SLOC
10828 refers to a File with an instance, map DECL to that instance. */
10829
10830 bool
Sloc_to_locus(Source_Ptr Sloc,location_t * locus,bool clear_column,const_tree decl)10831 Sloc_to_locus (Source_Ptr Sloc, location_t *locus, bool clear_column,
10832 const_tree decl)
10833 {
10834 if (Sloc == No_Location)
10835 return false;
10836
10837 if (Sloc <= Standard_Location)
10838 {
10839 *locus = BUILTINS_LOCATION;
10840 return false;
10841 }
10842
10843 Source_File_Index file = Get_Source_File_Index (Sloc);
10844 Line_Number_Type line = Get_Logical_Line_Number (Sloc);
10845 Column_Number_Type column = (clear_column ? 0 : Get_Column_Number (Sloc));
10846 line_map_ordinary *map = LINEMAPS_ORDINARY_MAP_AT (line_table, file - 1);
10847
10848 /* We can have zero if pragma Source_Reference is in effect. */
10849 if (line < 1)
10850 line = 1;
10851
10852 /* Translate the location. */
10853 *locus
10854 = linemap_position_for_line_and_column (line_table, map, line, column);
10855
10856 if (file_map && file_map[file - 1].Instance)
10857 decl_to_instance_map->put (decl, file_map[file - 1].Instance);
10858
10859 return true;
10860 }
10861
10862 /* Return whether GNAT_NODE is a defining identifier for a renaming that comes
10863 from the parameter association for the instantiation of a generic. We do
10864 not want to emit source location for them: the code generated for their
10865 initialization is likely to disturb debugging. */
10866
10867 bool
renaming_from_instantiation_p(Node_Id gnat_node)10868 renaming_from_instantiation_p (Node_Id gnat_node)
10869 {
10870 if (Nkind (gnat_node) != N_Defining_Identifier
10871 || !Is_Object (gnat_node)
10872 || Comes_From_Source (gnat_node)
10873 || !Present (Renamed_Object (gnat_node)))
10874 return false;
10875
10876 /* Get the object declaration of the renamed object, if any and if the
10877 renamed object is a mere identifier. */
10878 gnat_node = Renamed_Object (gnat_node);
10879 if (Nkind (gnat_node) != N_Identifier)
10880 return false;
10881
10882 gnat_node = Parent (Entity (gnat_node));
10883 return (Present (gnat_node)
10884 && Nkind (gnat_node) == N_Object_Declaration
10885 && Present (Corresponding_Generic_Association (gnat_node)));
10886 }
10887
10888 /* Similar to set_expr_location, but start with the Sloc of GNAT_NODE and
10889 don't do anything if it doesn't correspond to a source location. And,
10890 if CLEAR_COLUMN is true, set the column information to 0. */
10891
10892 static void
set_expr_location_from_node(tree node,Node_Id gnat_node,bool clear_column)10893 set_expr_location_from_node (tree node, Node_Id gnat_node, bool clear_column)
10894 {
10895 location_t locus;
10896
10897 /* Do not set a location for constructs likely to disturb debugging. */
10898 if (Nkind (gnat_node) == N_Defining_Identifier)
10899 {
10900 if (Is_Type (gnat_node) && Is_Actual_Subtype (gnat_node))
10901 return;
10902
10903 if (renaming_from_instantiation_p (gnat_node))
10904 return;
10905 }
10906
10907 if (!Sloc_to_locus (Sloc (gnat_node), &locus, clear_column))
10908 return;
10909
10910 SET_EXPR_LOCATION (node, locus);
10911 }
10912
10913 /* More elaborate version of set_expr_location_from_node to be used in more
10914 general contexts, for example the result of the translation of a generic
10915 GNAT node. */
10916
10917 static void
set_gnu_expr_location_from_node(tree node,Node_Id gnat_node)10918 set_gnu_expr_location_from_node (tree node, Node_Id gnat_node)
10919 {
10920 /* Set the location information on the node if it is a real expression.
10921 References can be reused for multiple GNAT nodes and they would get
10922 the location information of their last use. Also make sure not to
10923 overwrite an existing location as it is probably more precise. */
10924
10925 switch (TREE_CODE (node))
10926 {
10927 CASE_CONVERT:
10928 case NON_LVALUE_EXPR:
10929 case SAVE_EXPR:
10930 break;
10931
10932 case COMPOUND_EXPR:
10933 if (EXPR_P (TREE_OPERAND (node, 1)))
10934 set_gnu_expr_location_from_node (TREE_OPERAND (node, 1), gnat_node);
10935
10936 /* ... fall through ... */
10937
10938 default:
10939 if (!REFERENCE_CLASS_P (node) && !EXPR_HAS_LOCATION (node))
10940 {
10941 set_expr_location_from_node (node, gnat_node);
10942 set_end_locus_from_node (node, gnat_node);
10943 }
10944 break;
10945 }
10946 }
10947
10948 /* Set the end_locus information for GNU_NODE, if any, from an explicit end
10949 location associated with GNAT_NODE or GNAT_NODE itself, whichever makes
10950 most sense. Return true if a sensible assignment was performed. */
10951
10952 static bool
set_end_locus_from_node(tree gnu_node,Node_Id gnat_node)10953 set_end_locus_from_node (tree gnu_node, Node_Id gnat_node)
10954 {
10955 Node_Id gnat_end_label;
10956 location_t end_locus;
10957
10958 /* Pick the GNAT node of which we'll take the sloc to assign to the GCC node
10959 end_locus when there is one. We consider only GNAT nodes with a possible
10960 End_Label attached. If the End_Label actually was unassigned, fallback
10961 on the original node. We'd better assign an explicit sloc associated with
10962 the outer construct in any case. */
10963
10964 switch (Nkind (gnat_node))
10965 {
10966 case N_Package_Body:
10967 case N_Subprogram_Body:
10968 case N_Block_Statement:
10969 gnat_end_label = End_Label (Handled_Statement_Sequence (gnat_node));
10970 break;
10971
10972 case N_Package_Declaration:
10973 gnat_end_label = End_Label (Specification (gnat_node));
10974 break;
10975
10976 default:
10977 return false;
10978 }
10979
10980 if (Present (gnat_end_label))
10981 gnat_node = gnat_end_label;
10982
10983 /* Some expanded subprograms have neither an End_Label nor a Sloc
10984 attached. Notify that to callers. For a block statement with no
10985 End_Label, clear column information, so that the tree for a
10986 transient block does not receive the sloc of a source condition. */
10987 if (!Sloc_to_locus (Sloc (gnat_node), &end_locus,
10988 No (gnat_end_label)
10989 && (Nkind (gnat_node) == N_Block_Statement)))
10990 return false;
10991
10992 switch (TREE_CODE (gnu_node))
10993 {
10994 case BIND_EXPR:
10995 BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (gnu_node)) = end_locus;
10996 return true;
10997
10998 case FUNCTION_DECL:
10999 DECL_STRUCT_FUNCTION (gnu_node)->function_end_locus = end_locus;
11000 return true;
11001
11002 default:
11003 return false;
11004 }
11005 }
11006
11007 /* Return a colon-separated list of encodings contained in encoded Ada
11008 name. */
11009
11010 static const char *
extract_encoding(const char * name)11011 extract_encoding (const char *name)
11012 {
11013 char *encoding = (char *) ggc_alloc_atomic (strlen (name));
11014 get_encoding (name, encoding);
11015 return encoding;
11016 }
11017
11018 /* Extract the Ada name from an encoded name. */
11019
11020 static const char *
decode_name(const char * name)11021 decode_name (const char *name)
11022 {
11023 char *decoded = (char *) ggc_alloc_atomic (strlen (name) * 2 + 60);
11024 __gnat_decode (name, decoded, 0);
11025 return decoded;
11026 }
11027
11028 /* Post an error message. MSG is the error message, properly annotated.
11029 NODE is the node at which to post the error and the node to use for the
11030 '&' substitution. */
11031
11032 void
post_error(const char * msg,Node_Id node)11033 post_error (const char *msg, Node_Id node)
11034 {
11035 String_Template temp;
11036 String_Pointer sp;
11037
11038 if (No (node))
11039 return;
11040
11041 temp.Low_Bound = 1;
11042 temp.High_Bound = strlen (msg);
11043 sp.Bounds = &temp;
11044 sp.Array = msg;
11045 Error_Msg_N (sp, node);
11046 }
11047
11048 /* Similar to post_error, but NODE is the node at which to post the error and
11049 ENT is the node to use for the '&' substitution. */
11050
11051 void
post_error_ne(const char * msg,Node_Id node,Entity_Id ent)11052 post_error_ne (const char *msg, Node_Id node, Entity_Id ent)
11053 {
11054 String_Template temp;
11055 String_Pointer sp;
11056
11057 if (No (node))
11058 return;
11059
11060 temp.Low_Bound = 1;
11061 temp.High_Bound = strlen (msg);
11062 sp.Bounds = &temp;
11063 sp.Array = msg;
11064 Error_Msg_NE (sp, node, ent);
11065 }
11066
11067 /* Similar to post_error_ne, but NUM is the number to use for the '^'. */
11068
11069 void
post_error_ne_num(const char * msg,Node_Id node,Entity_Id ent,int num)11070 post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, int num)
11071 {
11072 Error_Msg_Uint_1 = UI_From_Int (num);
11073 post_error_ne (msg, node, ent);
11074 }
11075
11076 /* Similar to post_error_ne, but T is a GCC tree representing the number to
11077 write. If T represents a constant, the text inside curly brackets in
11078 MSG will be output (presumably including a '^'). Otherwise it will not
11079 be output and the text inside square brackets will be output instead. */
11080
11081 void
post_error_ne_tree(const char * msg,Node_Id node,Entity_Id ent,tree t)11082 post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t)
11083 {
11084 char *new_msg = XALLOCAVEC (char, strlen (msg) + 1);
11085 char start_yes, end_yes, start_no, end_no;
11086 const char *p;
11087 char *q;
11088
11089 if (TREE_CODE (t) == INTEGER_CST)
11090 {
11091 Error_Msg_Uint_1 = UI_From_gnu (t);
11092 start_yes = '{', end_yes = '}', start_no = '[', end_no = ']';
11093 }
11094 else
11095 start_yes = '[', end_yes = ']', start_no = '{', end_no = '}';
11096
11097 for (p = msg, q = new_msg; *p; p++)
11098 {
11099 if (*p == start_yes)
11100 for (p++; *p != end_yes; p++)
11101 *q++ = *p;
11102 else if (*p == start_no)
11103 for (p++; *p != end_no; p++)
11104 ;
11105 else
11106 *q++ = *p;
11107 }
11108
11109 *q = 0;
11110
11111 post_error_ne (new_msg, node, ent);
11112 }
11113
11114 /* Similar to post_error_ne_tree, but NUM is a second integer to write. */
11115
11116 void
post_error_ne_tree_2(const char * msg,Node_Id node,Entity_Id ent,tree t,int num)11117 post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent, tree t,
11118 int num)
11119 {
11120 Error_Msg_Uint_2 = UI_From_Int (num);
11121 post_error_ne_tree (msg, node, ent, t);
11122 }
11123
11124 /* Return a label to branch to for the exception type in KIND or Empty
11125 if none. */
11126
11127 Entity_Id
get_exception_label(char kind)11128 get_exception_label (char kind)
11129 {
11130 switch (kind)
11131 {
11132 case N_Raise_Constraint_Error:
11133 return gnu_constraint_error_label_stack.last ();
11134
11135 case N_Raise_Storage_Error:
11136 return gnu_storage_error_label_stack.last ();
11137
11138 case N_Raise_Program_Error:
11139 return gnu_program_error_label_stack.last ();
11140
11141 default:
11142 return Empty;
11143 }
11144
11145 gcc_unreachable ();
11146 }
11147
11148 /* Return the decl for the current elaboration procedure. */
11149
11150 static tree
get_elaboration_procedure(void)11151 get_elaboration_procedure (void)
11152 {
11153 return gnu_elab_proc_stack->last ();
11154 }
11155
11156 /* Return the controlling type of a dispatching subprogram. */
11157
11158 static Entity_Id
get_controlling_type(Entity_Id subprog)11159 get_controlling_type (Entity_Id subprog)
11160 {
11161 /* This is modeled on Expand_Interface_Thunk. */
11162 Entity_Id controlling_type = Etype (First_Formal (subprog));
11163 if (Is_Access_Type (controlling_type))
11164 controlling_type = Directly_Designated_Type (controlling_type);
11165 controlling_type = Underlying_Type (controlling_type);
11166 if (Is_Concurrent_Type (controlling_type))
11167 controlling_type = Corresponding_Record_Type (controlling_type);
11168 controlling_type = Base_Type (controlling_type);
11169 return controlling_type;
11170 }
11171
11172 /* Return whether we should use an alias for the TARGET of a thunk
11173 in order to make the call generated in the thunk local. */
11174
11175 static bool
use_alias_for_thunk_p(tree target)11176 use_alias_for_thunk_p (tree target)
11177 {
11178 /* We cannot generate a local call in this case. */
11179 if (DECL_EXTERNAL (target))
11180 return false;
11181
11182 /* The call is already local in this case. */
11183 if (TREE_CODE (DECL_CONTEXT (target)) == FUNCTION_DECL)
11184 return false;
11185
11186 return TARGET_USE_LOCAL_THUNK_ALIAS_P (target);
11187 }
11188
11189 static GTY(()) unsigned long thunk_labelno = 0;
11190
11191 /* Create an alias for TARGET to be used as the target of a thunk. */
11192
11193 static tree
make_alias_for_thunk(tree target)11194 make_alias_for_thunk (tree target)
11195 {
11196 char buf[64];
11197 targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno++);
11198
11199 tree alias = build_decl (DECL_SOURCE_LOCATION (target), TREE_CODE (target),
11200 get_identifier (buf), TREE_TYPE (target));
11201
11202 DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
11203 DECL_CONTEXT (alias) = DECL_CONTEXT (target);
11204 TREE_READONLY (alias) = TREE_READONLY (target);
11205 TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
11206 DECL_ARTIFICIAL (alias) = 1;
11207 DECL_INITIAL (alias) = error_mark_node;
11208 DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target));
11209 TREE_ADDRESSABLE (alias) = 1;
11210 SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
11211
11212 cgraph_node *n = cgraph_node::create_same_body_alias (alias, target);
11213 gcc_assert (n);
11214
11215 return alias;
11216 }
11217
11218 /* Create the covariant part of the {GNAT,GNU}_THUNK. */
11219
11220 static tree
make_covariant_thunk(Entity_Id gnat_thunk,tree gnu_thunk)11221 make_covariant_thunk (Entity_Id gnat_thunk, tree gnu_thunk)
11222 {
11223 tree gnu_name = create_concat_name (gnat_thunk, "CV");
11224 tree gnu_cv_thunk
11225 = build_decl (DECL_SOURCE_LOCATION (gnu_thunk), TREE_CODE (gnu_thunk),
11226 gnu_name, TREE_TYPE (gnu_thunk));
11227
11228 DECL_ARGUMENTS (gnu_cv_thunk) = copy_list (DECL_ARGUMENTS (gnu_thunk));
11229 DECL_RESULT (gnu_cv_thunk) = copy_node (DECL_RESULT (gnu_thunk));
11230 DECL_CONTEXT (DECL_RESULT (gnu_cv_thunk)) = gnu_cv_thunk;
11231
11232 DECL_LANG_SPECIFIC (gnu_cv_thunk) = DECL_LANG_SPECIFIC (gnu_thunk);
11233 DECL_CONTEXT (gnu_cv_thunk) = DECL_CONTEXT (gnu_thunk);
11234 TREE_READONLY (gnu_cv_thunk) = TREE_READONLY (gnu_thunk);
11235 TREE_THIS_VOLATILE (gnu_cv_thunk) = TREE_THIS_VOLATILE (gnu_thunk);
11236 TREE_PUBLIC (gnu_cv_thunk) = TREE_PUBLIC (gnu_thunk);
11237 DECL_ARTIFICIAL (gnu_cv_thunk) = 1;
11238
11239 return gnu_cv_thunk;
11240 }
11241
11242 /* Try to create a GNU thunk for {GNAT,GNU}_THUNK and return true on success.
11243
11244 GNU thunks are more efficient than GNAT thunks because they don't call into
11245 the runtime to retrieve the offset used in the displacement operation, but
11246 they are tailored to C++ and thus too limited to support the full range of
11247 thunks generated in Ada. Here's the complete list of limitations:
11248
11249 1. Multi-controlling thunks, i.e thunks with more than one controlling
11250 parameter, are simply not supported.
11251
11252 2. Covariant thunks, i.e. thunks for which the result is also controlling,
11253 are split into a pair of (this, covariant-only) thunks.
11254
11255 3. Variable-offset thunks, i.e. thunks for which the offset depends on the
11256 object and not only on its type, are supported as 2nd class citizens.
11257
11258 4. External thunks, i.e. thunks for which the target is not declared in
11259 the same unit as the thunk, are supported as 2nd class citizens.
11260
11261 5. Local thunks, i.e. thunks generated for a local type, are supported as
11262 2nd class citizens. */
11263
11264 static bool
maybe_make_gnu_thunk(Entity_Id gnat_thunk,tree gnu_thunk)11265 maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk)
11266 {
11267 const Entity_Id gnat_target = Thunk_Entity (gnat_thunk);
11268
11269 /* Check that the first formal of the target is the only controlling one. */
11270 Entity_Id gnat_formal = First_Formal (gnat_target);
11271 if (!Is_Controlling_Formal (gnat_formal))
11272 return false;
11273 for (gnat_formal = Next_Formal (gnat_formal);
11274 Present (gnat_formal);
11275 gnat_formal = Next_Formal (gnat_formal))
11276 if (Is_Controlling_Formal (gnat_formal))
11277 return false;
11278
11279 /* Look for the types that control the target and the thunk. */
11280 const Entity_Id gnat_controlling_type = get_controlling_type (gnat_target);
11281 const Entity_Id gnat_interface_type = get_controlling_type (gnat_thunk);
11282
11283 /* We must have an interface type at this point. */
11284 gcc_assert (Is_Interface (gnat_interface_type));
11285
11286 /* Now compute whether the former covers the latter. */
11287 const Entity_Id gnat_interface_tag
11288 = Find_Interface_Tag (gnat_controlling_type, gnat_interface_type);
11289 tree gnu_interface_tag
11290 = Present (gnat_interface_tag)
11291 ? gnat_to_gnu_field_decl (gnat_interface_tag)
11292 : NULL_TREE;
11293 tree gnu_interface_offset
11294 = gnu_interface_tag ? byte_position (gnu_interface_tag) : NULL_TREE;
11295
11296 /* There are three ways to retrieve the offset between the interface view
11297 and the base object. Either the controlling type covers the interface
11298 type and the offset of the corresponding tag is fixed, in which case it
11299 can be statically encoded in the thunk (see FIXED_OFFSET below). Or the
11300 controlling type doesn't cover the interface type but is of fixed size,
11301 in which case the offset is stored in the dispatch table, two pointers
11302 above the dispatch table address (see VIRTUAL_VALUE below). Otherwise,
11303 the offset is variable and is stored right after the tag in every object
11304 (see INDIRECT_OFFSET below). See also a-tags.ads for more details. */
11305 HOST_WIDE_INT fixed_offset, virtual_value, indirect_offset;
11306 tree virtual_offset;
11307
11308 if (gnu_interface_offset && TREE_CODE (gnu_interface_offset) == INTEGER_CST)
11309 {
11310 fixed_offset = - tree_to_shwi (gnu_interface_offset);
11311 virtual_value = 0;
11312 virtual_offset = NULL_TREE;
11313 indirect_offset = 0;
11314 }
11315 else if (!gnu_interface_offset
11316 && !Is_Variable_Size_Record (gnat_controlling_type))
11317 {
11318 fixed_offset = 0;
11319 virtual_value = - 2 * (HOST_WIDE_INT) (POINTER_SIZE / BITS_PER_UNIT);
11320 virtual_offset = build_int_cst (integer_type_node, virtual_value);
11321 indirect_offset = 0;
11322 }
11323 else
11324 {
11325 /* Covariant thunks with variable offset are not supported. */
11326 if (Has_Controlling_Result (gnat_target))
11327 return false;
11328
11329 fixed_offset = 0;
11330 virtual_value = 0;
11331 virtual_offset = NULL_TREE;
11332 indirect_offset = (HOST_WIDE_INT) (POINTER_SIZE / BITS_PER_UNIT);
11333 }
11334
11335 tree gnu_target = gnat_to_gnu_entity (gnat_target, NULL_TREE, false);
11336
11337 /* Thunk and target must have the same nesting level, if any. */
11338 gcc_assert (DECL_CONTEXT (gnu_thunk) == DECL_CONTEXT (gnu_target));
11339
11340 /* If the target returns by invisible reference and is external, apply the
11341 same transformation as Subprogram_Body_to_gnu here. */
11342 if (TREE_ADDRESSABLE (TREE_TYPE (gnu_target))
11343 && DECL_EXTERNAL (gnu_target)
11344 && !POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (gnu_target))))
11345 {
11346 TREE_TYPE (DECL_RESULT (gnu_target))
11347 = build_reference_type (TREE_TYPE (DECL_RESULT (gnu_target)));
11348 relayout_decl (DECL_RESULT (gnu_target));
11349 }
11350
11351 /* The thunk expander requires the return types of thunk and target to be
11352 compatible, which is not fully the case with the CICO mechanism. */
11353 if (TYPE_CI_CO_LIST (TREE_TYPE (gnu_thunk)))
11354 {
11355 tree gnu_target_type = TREE_TYPE (gnu_target);
11356 gcc_assert (TYPE_CI_CO_LIST (gnu_target_type));
11357 TYPE_CANONICAL (TREE_TYPE (TREE_TYPE (gnu_thunk)))
11358 = TYPE_CANONICAL (TREE_TYPE (gnu_target_type));
11359 }
11360
11361 cgraph_node *target_node = cgraph_node::get_create (gnu_target);
11362
11363 /* If the return type of the target is a controlling type, then we need
11364 both an usual this thunk and a covariant thunk in this order:
11365
11366 this thunk --> covariant thunk --> target
11367
11368 For covariant thunks, we can only handle a fixed offset. */
11369 if (Has_Controlling_Result (gnat_target))
11370 {
11371 gcc_assert (fixed_offset < 0);
11372 tree gnu_cv_thunk = make_covariant_thunk (gnat_thunk, gnu_thunk);
11373 target_node->create_thunk (gnu_cv_thunk, gnu_target, false,
11374 - fixed_offset, 0, 0,
11375 NULL_TREE, gnu_target);
11376
11377 gnu_target = gnu_cv_thunk;
11378 }
11379
11380 /* We may also need to create an alias for the target in order to make
11381 the call local, depending on the linkage of the target. */
11382 tree gnu_alias = use_alias_for_thunk_p (gnu_target)
11383 ? make_alias_for_thunk (gnu_target)
11384 : gnu_target;
11385
11386 target_node->create_thunk (gnu_thunk, gnu_target, true,
11387 fixed_offset, virtual_value, indirect_offset,
11388 virtual_offset, gnu_alias);
11389
11390 return true;
11391 }
11392
11393 /* Initialize the table that maps GNAT codes to GCC codes for simple
11394 binary and unary operations. */
11395
11396 static void
init_code_table(void)11397 init_code_table (void)
11398 {
11399 gnu_codes[N_Op_And] = TRUTH_AND_EXPR;
11400 gnu_codes[N_Op_Or] = TRUTH_OR_EXPR;
11401 gnu_codes[N_Op_Xor] = TRUTH_XOR_EXPR;
11402 gnu_codes[N_Op_Eq] = EQ_EXPR;
11403 gnu_codes[N_Op_Ne] = NE_EXPR;
11404 gnu_codes[N_Op_Lt] = LT_EXPR;
11405 gnu_codes[N_Op_Le] = LE_EXPR;
11406 gnu_codes[N_Op_Gt] = GT_EXPR;
11407 gnu_codes[N_Op_Ge] = GE_EXPR;
11408 gnu_codes[N_Op_Add] = PLUS_EXPR;
11409 gnu_codes[N_Op_Subtract] = MINUS_EXPR;
11410 gnu_codes[N_Op_Multiply] = MULT_EXPR;
11411 gnu_codes[N_Op_Mod] = FLOOR_MOD_EXPR;
11412 gnu_codes[N_Op_Rem] = TRUNC_MOD_EXPR;
11413 gnu_codes[N_Op_Minus] = NEGATE_EXPR;
11414 gnu_codes[N_Op_Abs] = ABS_EXPR;
11415 gnu_codes[N_Op_Not] = TRUTH_NOT_EXPR;
11416 gnu_codes[N_Op_Rotate_Left] = LROTATE_EXPR;
11417 gnu_codes[N_Op_Rotate_Right] = RROTATE_EXPR;
11418 gnu_codes[N_Op_Shift_Left] = LSHIFT_EXPR;
11419 gnu_codes[N_Op_Shift_Right] = RSHIFT_EXPR;
11420 gnu_codes[N_Op_Shift_Right_Arithmetic] = RSHIFT_EXPR;
11421 gnu_codes[N_And_Then] = TRUTH_ANDIF_EXPR;
11422 gnu_codes[N_Or_Else] = TRUTH_ORIF_EXPR;
11423 }
11424
11425 #include "gt-ada-trans.h"
11426