Allow returning something of type void in a function that returns void
[delight/core.git] / d-bi-attrs-341.h
blob458b9eaa805df37f00f3896c88986cdb7b8664fb
1 static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
2 static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
3 static tree handle_common_attribute (tree *, tree, tree, int, bool *);
4 static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
5 static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
6 static tree handle_always_inline_attribute (tree *, tree, tree, int,
7 bool *);
8 static tree handle_used_attribute (tree *, tree, tree, int, bool *);
9 static tree handle_unused_attribute (tree *, tree, tree, int, bool *);
10 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
11 static tree handle_transparent_union_attribute (tree *, tree, tree,
12 int, bool *);
13 static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
14 static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
15 static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
16 static tree handle_section_attribute (tree *, tree, tree, int, bool *);
17 static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
18 static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
19 static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
20 static tree handle_visibility_attribute (tree *, tree, tree, int,
21 bool *);
22 static tree handle_tls_model_attribute (tree *, tree, tree, int,
23 bool *);
24 static tree handle_no_instrument_function_attribute (tree *, tree,
25 tree, int, bool *);
26 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
27 static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
28 bool *);
29 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
30 static tree handle_deprecated_attribute (tree *, tree, tree, int,
31 bool *);
32 static tree handle_vector_size_attribute (tree *, tree, tree, int,
33 bool *);
34 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
35 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
36 /*not in gdc//static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);*/
37 static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
38 bool *);
39 static tree vector_size_helper (tree, tree);
41 /*not in gdc//static void check_function_nonnull (tree, tree);*/
42 static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
43 static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
44 static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
46 /* extra for gdc copy: */
47 static void check_function_arguments_recurse (void (*)
48 (void *, tree,
49 unsigned HOST_WIDE_INT),
50 void *, tree,
51 unsigned HOST_WIDE_INT);
52 static tree
53 handle_format_arg_attribute (tree *node ATTRIBUTE_UNUSED, tree name ATTRIBUTE_UNUSED,
54 tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs ATTRIBUTE_UNUSED)
56 return NULL_TREE;
58 static tree
59 handle_format_attribute (tree *node ATTRIBUTE_UNUSED, tree name ATTRIBUTE_UNUSED, tree args ATTRIBUTE_UNUSED,
60 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs ATTRIBUTE_UNUSED)
62 return NULL_TREE;
65 /* -- end extra */
67 /* Table of machine-independent attributes common to all C-like languages. */
68 const struct attribute_spec d_common_attribute_table[] =
70 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
71 { "packed", 0, 0, false, false, false,
72 handle_packed_attribute },
73 { "nocommon", 0, 0, true, false, false,
74 handle_nocommon_attribute },
75 { "common", 0, 0, true, false, false,
76 handle_common_attribute },
77 /* FIXME: logically, noreturn attributes should be listed as
78 "false, true, true" and apply to function types. But implementing this
79 would require all the places in the compiler that use TREE_THIS_VOLATILE
80 on a decl to identify non-returning functions to be located and fixed
81 to check the function type instead. */
82 { "noreturn", 0, 0, true, false, false,
83 handle_noreturn_attribute },
84 { "volatile", 0, 0, true, false, false,
85 handle_noreturn_attribute },
86 { "noinline", 0, 0, true, false, false,
87 handle_noinline_attribute },
88 { "always_inline", 0, 0, true, false, false,
89 handle_always_inline_attribute },
90 { "used", 0, 0, true, false, false,
91 handle_used_attribute },
92 { "unused", 0, 0, false, false, false,
93 handle_unused_attribute },
94 /* The same comments as for noreturn attributes apply to const ones. */
95 { "const", 0, 0, true, false, false,
96 handle_const_attribute },
97 { "transparent_union", 0, 0, false, false, false,
98 handle_transparent_union_attribute },
99 { "constructor", 0, 0, true, false, false,
100 handle_constructor_attribute },
101 { "destructor", 0, 0, true, false, false,
102 handle_destructor_attribute },
103 { "mode", 1, 1, false, true, false,
104 handle_mode_attribute },
105 { "section", 1, 1, true, false, false,
106 handle_section_attribute },
107 { "aligned", 0, 1, false, false, false,
108 handle_aligned_attribute },
109 { "weak", 0, 0, true, false, false,
110 handle_weak_attribute },
111 { "alias", 1, 1, true, false, false,
112 handle_alias_attribute },
113 { "no_instrument_function", 0, 0, true, false, false,
114 handle_no_instrument_function_attribute },
115 { "malloc", 0, 0, true, false, false,
116 handle_malloc_attribute },
117 { "no_stack_limit", 0, 0, true, false, false,
118 handle_no_limit_stack_attribute },
119 { "pure", 0, 0, true, false, false,
120 handle_pure_attribute },
121 { "deprecated", 0, 0, false, false, false,
122 handle_deprecated_attribute },
123 { "vector_size", 1, 1, false, true, false,
124 handle_vector_size_attribute },
125 { "visibility", 1, 1, true, false, false,
126 handle_visibility_attribute },
127 { "tls_model", 1, 1, true, false, false,
128 handle_tls_model_attribute },
129 { "nonnull", 0, -1, false, true, true,
130 handle_nonnull_attribute },
131 { "nothrow", 0, 0, true, false, false,
132 handle_nothrow_attribute },
133 { "may_alias", 0, 0, false, true, false, NULL },
134 /* not in gdc// { "cleanup", 1, 1, true, false, false,
135 handle_cleanup_attribute },*/
136 { "warn_unused_result", 0, 0, false, true, true,
137 handle_warn_unused_result_attribute },
138 { NULL, 0, 0, false, false, false, NULL }
141 /* Give the specifications for the format attributes, used by C and all
142 descendants. */
144 const struct attribute_spec d_common_format_attribute_table[] =
146 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
147 { "format", 3, 3, false, true, true,
148 handle_format_attribute },
149 { "format_arg", 1, 1, false, true, true,
150 handle_format_arg_attribute },
151 { NULL, 0, 0, false, false, false, NULL }
154 /* Attribute handlers common to C front ends. */
156 /* Handle a "packed" attribute; arguments as in
157 struct attribute_spec.handler. */
159 static tree
160 handle_packed_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
161 int flags, bool *no_add_attrs)
163 if (TYPE_P (*node))
165 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
166 *node = build_type_copy (*node);
167 TYPE_PACKED (*node) = 1;
168 if (TYPE_MAIN_VARIANT (*node) == *node)
170 /* If it is the main variant, then pack the other variants
171 too. This happens in,
173 struct Foo {
174 struct Foo const *ptr; // creates a variant w/o packed flag
175 } __ attribute__((packed)); // packs it now.
177 tree probe;
179 for (probe = *node; probe; probe = TYPE_NEXT_VARIANT (probe))
180 TYPE_PACKED (probe) = 1;
184 else if (TREE_CODE (*node) == FIELD_DECL)
185 DECL_PACKED (*node) = 1;
186 /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
187 used for DECL_REGISTER. It wouldn't mean anything anyway.
188 We can't set DECL_PACKED on the type of a TYPE_DECL, because
189 that changes what the typedef is typing. */
190 else
192 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
193 *no_add_attrs = true;
196 return NULL_TREE;
199 /* Handle a "nocommon" attribute; arguments as in
200 struct attribute_spec.handler. */
202 static tree
203 handle_nocommon_attribute (tree *node, tree name,
204 tree args ATTRIBUTE_UNUSED,
205 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
207 if (TREE_CODE (*node) == VAR_DECL)
208 DECL_COMMON (*node) = 0;
209 else
211 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
212 *no_add_attrs = true;
215 return NULL_TREE;
218 /* Handle a "common" attribute; arguments as in
219 struct attribute_spec.handler. */
221 static tree
222 handle_common_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
223 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
225 if (TREE_CODE (*node) == VAR_DECL)
226 DECL_COMMON (*node) = 1;
227 else
229 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
230 *no_add_attrs = true;
233 return NULL_TREE;
236 /* Handle a "noreturn" attribute; arguments as in
237 struct attribute_spec.handler. */
239 static tree
240 handle_noreturn_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
241 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
243 tree type = TREE_TYPE (*node);
245 /* See FIXME comment in c_common_attribute_table. */
246 if (TREE_CODE (*node) == FUNCTION_DECL)
247 TREE_THIS_VOLATILE (*node) = 1;
248 else if (TREE_CODE (type) == POINTER_TYPE
249 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
250 TREE_TYPE (*node)
251 = build_pointer_type
252 (build_type_variant (TREE_TYPE (type),
253 TREE_READONLY (TREE_TYPE (type)), 1));
254 else
256 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
257 *no_add_attrs = true;
260 return NULL_TREE;
263 /* Handle a "noinline" attribute; arguments as in
264 struct attribute_spec.handler. */
266 static tree
267 handle_noinline_attribute (tree *node, tree name,
268 tree args ATTRIBUTE_UNUSED,
269 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
271 if (TREE_CODE (*node) == FUNCTION_DECL)
272 DECL_UNINLINABLE (*node) = 1;
273 else
275 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
276 *no_add_attrs = true;
279 return NULL_TREE;
282 /* Handle a "always_inline" attribute; arguments as in
283 struct attribute_spec.handler. */
285 static tree
286 handle_always_inline_attribute (tree *node, tree name,
287 tree args ATTRIBUTE_UNUSED,
288 int flags ATTRIBUTE_UNUSED,
289 bool *no_add_attrs)
291 if (TREE_CODE (*node) == FUNCTION_DECL)
293 /* Do nothing else, just set the attribute. We'll get at
294 it later with lookup_attribute. */
296 else
298 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
299 *no_add_attrs = true;
302 return NULL_TREE;
305 /* Handle a "used" attribute; arguments as in
306 struct attribute_spec.handler. */
308 static tree
309 handle_used_attribute (tree *pnode, tree name, tree args ATTRIBUTE_UNUSED,
310 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
312 tree node = *pnode;
314 if (TREE_CODE (node) == FUNCTION_DECL
315 || (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)))
317 TREE_USED (node) = 1;
319 else
321 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
322 *no_add_attrs = true;
325 return NULL_TREE;
328 /* Handle a "unused" attribute; arguments as in
329 struct attribute_spec.handler. */
331 static tree
332 handle_unused_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
333 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
335 if (DECL_P (*node))
337 tree decl = *node;
339 if (TREE_CODE (decl) == PARM_DECL
340 || TREE_CODE (decl) == VAR_DECL
341 || TREE_CODE (decl) == FUNCTION_DECL
342 || TREE_CODE (decl) == LABEL_DECL
343 || TREE_CODE (decl) == TYPE_DECL)
344 TREE_USED (decl) = 1;
345 else
347 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
348 *no_add_attrs = true;
351 else
353 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
354 *node = build_type_copy (*node);
355 TREE_USED (*node) = 1;
358 return NULL_TREE;
361 /* Handle a "const" attribute; arguments as in
362 struct attribute_spec.handler. */
364 static tree
365 handle_const_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
366 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
368 tree type = TREE_TYPE (*node);
370 /* See FIXME comment on noreturn in c_common_attribute_table. */
371 if (TREE_CODE (*node) == FUNCTION_DECL)
372 TREE_READONLY (*node) = 1;
373 else if (TREE_CODE (type) == POINTER_TYPE
374 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
375 TREE_TYPE (*node)
376 = build_pointer_type
377 (build_type_variant (TREE_TYPE (type), 1,
378 TREE_THIS_VOLATILE (TREE_TYPE (type))));
379 else
381 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
382 *no_add_attrs = true;
385 return NULL_TREE;
388 /* Handle a "transparent_union" attribute; arguments as in
389 struct attribute_spec.handler. */
391 static tree
392 handle_transparent_union_attribute (tree *node, tree name,
393 tree args ATTRIBUTE_UNUSED, int flags,
394 bool *no_add_attrs)
396 tree decl = NULL_TREE;
397 tree *type = NULL;
398 int is_type = 0;
400 if (DECL_P (*node))
402 decl = *node;
403 type = &TREE_TYPE (decl);
404 is_type = TREE_CODE (*node) == TYPE_DECL;
406 else if (TYPE_P (*node))
407 type = node, is_type = 1;
409 if (is_type
410 && TREE_CODE (*type) == UNION_TYPE
411 && (decl == 0
412 || (TYPE_FIELDS (*type) != 0
413 && TYPE_MODE (*type) == DECL_MODE (TYPE_FIELDS (*type)))))
415 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
416 *type = build_type_copy (*type);
417 TYPE_TRANSPARENT_UNION (*type) = 1;
419 else if (decl != 0 && TREE_CODE (decl) == PARM_DECL
420 && TREE_CODE (*type) == UNION_TYPE
421 && TYPE_MODE (*type) == DECL_MODE (TYPE_FIELDS (*type)))
422 DECL_TRANSPARENT_UNION (decl) = 1;
423 else
425 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
426 *no_add_attrs = true;
429 return NULL_TREE;
432 /* Handle a "constructor" attribute; arguments as in
433 struct attribute_spec.handler. */
435 static tree
436 handle_constructor_attribute (tree *node, tree name,
437 tree args ATTRIBUTE_UNUSED,
438 int flags ATTRIBUTE_UNUSED,
439 bool *no_add_attrs)
441 tree decl = *node;
442 tree type = TREE_TYPE (decl);
444 if (TREE_CODE (decl) == FUNCTION_DECL
445 && TREE_CODE (type) == FUNCTION_TYPE
446 && decl_function_context (decl) == 0)
448 DECL_STATIC_CONSTRUCTOR (decl) = 1;
449 TREE_USED (decl) = 1;
451 else
453 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
454 *no_add_attrs = true;
457 return NULL_TREE;
460 /* Handle a "destructor" attribute; arguments as in
461 struct attribute_spec.handler. */
463 static tree
464 handle_destructor_attribute (tree *node, tree name,
465 tree args ATTRIBUTE_UNUSED,
466 int flags ATTRIBUTE_UNUSED,
467 bool *no_add_attrs)
469 tree decl = *node;
470 tree type = TREE_TYPE (decl);
472 if (TREE_CODE (decl) == FUNCTION_DECL
473 && TREE_CODE (type) == FUNCTION_TYPE
474 && decl_function_context (decl) == 0)
476 DECL_STATIC_DESTRUCTOR (decl) = 1;
477 TREE_USED (decl) = 1;
479 else
481 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
482 *no_add_attrs = true;
485 return NULL_TREE;
488 /* Handle a "mode" attribute; arguments as in
489 struct attribute_spec.handler. */
491 static tree
492 handle_mode_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
493 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
495 tree type = *node;
497 *no_add_attrs = true;
499 if (TREE_CODE (TREE_VALUE (args)) != IDENTIFIER_NODE)
500 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
501 else
503 int j;
504 const char *p = IDENTIFIER_POINTER (TREE_VALUE (args));
505 int len = strlen (p);
506 enum machine_mode mode = VOIDmode;
507 tree typefm;
508 tree ptr_type;
510 if (len > 4 && p[0] == '_' && p[1] == '_'
511 && p[len - 1] == '_' && p[len - 2] == '_')
513 char *newp = alloca (len - 1);
515 strcpy (newp, &p[2]);
516 newp[len - 4] = '\0';
517 p = newp;
520 /* Change this type to have a type with the specified mode.
521 First check for the special modes. */
522 if (! strcmp (p, "byte"))
523 mode = byte_mode;
524 else if (!strcmp (p, "word"))
525 mode = word_mode;
526 else if (! strcmp (p, "pointer"))
527 mode = ptr_mode;
528 else
529 for (j = 0; j < NUM_MACHINE_MODES; j++)
530 if (!strcmp (p, GET_MODE_NAME (j)))
531 mode = (enum machine_mode) j;
533 if (mode == VOIDmode)
534 error ("unknown machine mode `%s'", p);
535 else if (0 == (typefm = (*lang_hooks.types.type_for_mode)
536 (mode, TREE_UNSIGNED (type))))
537 error ("no data type for mode `%s'", p);
538 else if ((TREE_CODE (type) == POINTER_TYPE
539 || TREE_CODE (type) == REFERENCE_TYPE)
540 && !(*targetm.valid_pointer_mode) (mode))
541 error ("invalid pointer mode `%s'", p);
542 else
544 /* If this is a vector, make sure we either have hardware
545 support, or we can emulate it. */
546 if (VECTOR_MODE_P (mode) && !vector_mode_valid_p (mode))
548 error ("unable to emulate '%s'", GET_MODE_NAME (mode));
549 return NULL_TREE;
552 if (TREE_CODE (type) == POINTER_TYPE)
554 ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
555 mode);
556 *node = ptr_type;
558 else if (TREE_CODE (type) == REFERENCE_TYPE)
560 ptr_type = build_reference_type_for_mode (TREE_TYPE (type),
561 mode);
562 *node = ptr_type;
564 else
565 *node = typefm;
566 /* No need to layout the type here. The caller should do this. */
570 return NULL_TREE;
573 /* Handle a "section" attribute; arguments as in
574 struct attribute_spec.handler. */
576 static tree
577 handle_section_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
578 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
580 tree decl = *node;
582 if (targetm.have_named_sections)
584 if ((TREE_CODE (decl) == FUNCTION_DECL
585 || TREE_CODE (decl) == VAR_DECL)
586 && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
588 if (TREE_CODE (decl) == VAR_DECL
589 && current_function_decl != NULL_TREE
590 && ! (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
592 error ("%Jsection attribute cannot be specified for "
593 "local variables", decl);
594 *no_add_attrs = true;
597 /* The decl may have already been given a section attribute
598 from a previous declaration. Ensure they match. */
599 else if (DECL_SECTION_NAME (decl) != NULL_TREE
600 && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
601 TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
603 error ("%Jsection of '%D' conflicts with previous declaration",
604 *node, *node);
605 *no_add_attrs = true;
607 else
608 DECL_SECTION_NAME (decl) = TREE_VALUE (args);
610 else
612 error ("%Jsection attribute not allowed for '%D'", *node, *node);
613 *no_add_attrs = true;
616 else
618 error ("%Jsection attributes are not supported for this target", *node);
619 *no_add_attrs = true;
622 return NULL_TREE;
625 /* Handle a "aligned" attribute; arguments as in
626 struct attribute_spec.handler. */
628 static tree
629 handle_aligned_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
630 int flags, bool *no_add_attrs)
632 tree decl = NULL_TREE;
633 tree *type = NULL;
634 int is_type = 0;
635 tree align_expr = (args ? TREE_VALUE (args)
636 : size_int (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
637 int i;
639 if (DECL_P (*node))
641 decl = *node;
642 type = &TREE_TYPE (decl);
643 is_type = TREE_CODE (*node) == TYPE_DECL;
645 else if (TYPE_P (*node))
646 type = node, is_type = 1;
648 /* Strip any NOPs of any kind. */
649 while (TREE_CODE (align_expr) == NOP_EXPR
650 || TREE_CODE (align_expr) == CONVERT_EXPR
651 || TREE_CODE (align_expr) == NON_LVALUE_EXPR)
652 align_expr = TREE_OPERAND (align_expr, 0);
654 if (TREE_CODE (align_expr) != INTEGER_CST)
656 error ("requested alignment is not a constant");
657 *no_add_attrs = true;
659 else if ((i = tree_log2 (align_expr)) == -1)
661 error ("requested alignment is not a power of 2");
662 *no_add_attrs = true;
664 else if (i > HOST_BITS_PER_INT - 2)
666 error ("requested alignment is too large");
667 *no_add_attrs = true;
669 else if (is_type)
671 /* If we have a TYPE_DECL, then copy the type, so that we
672 don't accidentally modify a builtin type. See pushdecl. */
673 if (decl && TREE_TYPE (decl) != error_mark_node
674 && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
676 tree tt = TREE_TYPE (decl);
677 *type = build_type_copy (*type);
678 DECL_ORIGINAL_TYPE (decl) = tt;
679 TYPE_NAME (*type) = decl;
680 TREE_USED (*type) = TREE_USED (decl);
681 TREE_TYPE (decl) = *type;
683 else if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
684 *type = build_type_copy (*type);
686 TYPE_ALIGN (*type) = (1 << i) * BITS_PER_UNIT;
687 TYPE_USER_ALIGN (*type) = 1;
689 else if (TREE_CODE (decl) != VAR_DECL
690 && TREE_CODE (decl) != FIELD_DECL)
692 error ("%Jalignment may not be specified for '%D'", decl, decl);
693 *no_add_attrs = true;
695 else
697 DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;
698 DECL_USER_ALIGN (decl) = 1;
701 return NULL_TREE;
704 /* Handle a "weak" attribute; arguments as in
705 struct attribute_spec.handler. */
707 static tree
708 handle_weak_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
709 tree args ATTRIBUTE_UNUSED,
710 int flags ATTRIBUTE_UNUSED,
711 bool *no_add_attrs ATTRIBUTE_UNUSED)
713 declare_weak (*node);
715 return NULL_TREE;
718 /* Handle an "alias" attribute; arguments as in
719 struct attribute_spec.handler. */
721 static tree
722 handle_alias_attribute (tree *node, tree name, tree args,
723 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
725 tree decl = *node;
727 if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
728 || (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)))
730 error ("%J'%D' defined both normally and as an alias", decl, decl);
731 *no_add_attrs = true;
733 else if (decl_function_context (decl) == 0)
735 tree id;
737 id = TREE_VALUE (args);
738 if (TREE_CODE (id) != STRING_CST)
740 error ("alias arg not a string");
741 *no_add_attrs = true;
742 return NULL_TREE;
744 id = get_identifier (TREE_STRING_POINTER (id));
745 /* This counts as a use of the object pointed to. */
746 TREE_USED (id) = 1;
748 if (TREE_CODE (decl) == FUNCTION_DECL)
749 DECL_INITIAL (decl) = error_mark_node;
750 else
751 DECL_EXTERNAL (decl) = 0;
753 else
755 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
756 *no_add_attrs = true;
759 return NULL_TREE;
762 /* Handle an "visibility" attribute; arguments as in
763 struct attribute_spec.handler. */
765 static tree
766 handle_visibility_attribute (tree *node, tree name, tree args,
767 int flags ATTRIBUTE_UNUSED,
768 bool *no_add_attrs)
770 tree decl = *node;
771 tree id = TREE_VALUE (args);
773 *no_add_attrs = true;
775 if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
777 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
778 return NULL_TREE;
781 if (TREE_CODE (id) != STRING_CST)
783 error ("visibility arg not a string");
784 return NULL_TREE;
787 if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
788 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
789 else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
790 DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
791 else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
792 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
793 else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
794 DECL_VISIBILITY (decl) = VISIBILITY_PROTECTED;
795 else
796 error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
798 return NULL_TREE;
801 /* Handle an "tls_model" attribute; arguments as in
802 struct attribute_spec.handler. */
804 static tree
805 handle_tls_model_attribute (tree *node, tree name, tree args,
806 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
808 tree decl = *node;
810 if (! DECL_THREAD_LOCAL (decl))
812 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
813 *no_add_attrs = true;
815 else
817 tree id;
819 id = TREE_VALUE (args);
820 if (TREE_CODE (id) != STRING_CST)
822 error ("tls_model arg not a string");
823 *no_add_attrs = true;
824 return NULL_TREE;
826 if (strcmp (TREE_STRING_POINTER (id), "local-exec")
827 && strcmp (TREE_STRING_POINTER (id), "initial-exec")
828 && strcmp (TREE_STRING_POINTER (id), "local-dynamic")
829 && strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
831 error ("tls_model arg must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
832 *no_add_attrs = true;
833 return NULL_TREE;
837 return NULL_TREE;
840 /* Handle a "no_instrument_function" attribute; arguments as in
841 struct attribute_spec.handler. */
843 static tree
844 handle_no_instrument_function_attribute (tree *node, tree name,
845 tree args ATTRIBUTE_UNUSED,
846 int flags ATTRIBUTE_UNUSED,
847 bool *no_add_attrs)
849 tree decl = *node;
851 if (TREE_CODE (decl) != FUNCTION_DECL)
853 error ("%J'%E' attribute applies only to functions", decl, name);
854 *no_add_attrs = true;
856 else if (DECL_INITIAL (decl))
858 error ("%Jcan't set '%E' attribute after definition", decl, name);
859 *no_add_attrs = true;
861 else
862 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
864 return NULL_TREE;
867 /* Handle a "malloc" attribute; arguments as in
868 struct attribute_spec.handler. */
870 static tree
871 handle_malloc_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
872 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
874 if (TREE_CODE (*node) == FUNCTION_DECL)
875 DECL_IS_MALLOC (*node) = 1;
876 /* ??? TODO: Support types. */
877 else
879 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
880 *no_add_attrs = true;
883 return NULL_TREE;
886 /* Handle a "no_limit_stack" attribute; arguments as in
887 struct attribute_spec.handler. */
889 static tree
890 handle_no_limit_stack_attribute (tree *node, tree name,
891 tree args ATTRIBUTE_UNUSED,
892 int flags ATTRIBUTE_UNUSED,
893 bool *no_add_attrs)
895 tree decl = *node;
897 if (TREE_CODE (decl) != FUNCTION_DECL)
899 error ("%J'%E' attribute applies only to functions", decl, name);
900 *no_add_attrs = true;
902 else if (DECL_INITIAL (decl))
904 error ("%Jcan't set '%E' attribute after definition", decl, name);
905 *no_add_attrs = true;
907 else
908 DECL_NO_LIMIT_STACK (decl) = 1;
910 return NULL_TREE;
913 /* Handle a "pure" attribute; arguments as in
914 struct attribute_spec.handler. */
916 static tree
917 handle_pure_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
918 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
920 if (TREE_CODE (*node) == FUNCTION_DECL)
921 DECL_IS_PURE (*node) = 1;
922 /* ??? TODO: Support types. */
923 else
925 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
926 *no_add_attrs = true;
929 return NULL_TREE;
932 /* Handle a "deprecated" attribute; arguments as in
933 struct attribute_spec.handler. */
935 static tree
936 handle_deprecated_attribute (tree *node, tree name,
937 tree args ATTRIBUTE_UNUSED, int flags,
938 bool *no_add_attrs)
940 tree type = NULL_TREE;
941 int warn = 0;
942 const char *what = NULL;
944 if (DECL_P (*node))
946 tree decl = *node;
947 type = TREE_TYPE (decl);
949 if (TREE_CODE (decl) == TYPE_DECL
950 || TREE_CODE (decl) == PARM_DECL
951 || TREE_CODE (decl) == VAR_DECL
952 || TREE_CODE (decl) == FUNCTION_DECL
953 || TREE_CODE (decl) == FIELD_DECL)
954 TREE_DEPRECATED (decl) = 1;
955 else
956 warn = 1;
958 else if (TYPE_P (*node))
960 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
961 *node = build_type_copy (*node);
962 TREE_DEPRECATED (*node) = 1;
963 type = *node;
965 else
966 warn = 1;
968 if (warn)
970 *no_add_attrs = true;
971 if (type && TYPE_NAME (type))
973 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
974 what = IDENTIFIER_POINTER (TYPE_NAME (*node));
975 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
976 && DECL_NAME (TYPE_NAME (type)))
977 what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
979 if (what)
980 warning ("`%s' attribute ignored for `%s'",
981 IDENTIFIER_POINTER (name), what);
982 else
983 warning ("`%s' attribute ignored",
984 IDENTIFIER_POINTER (name));
987 return NULL_TREE;
990 /* Keep a list of vector type nodes we created in handle_vector_size_attribute,
991 to prevent us from duplicating type nodes unnecessarily.
992 The normal mechanism to prevent duplicates is to use type_hash_canon, but
993 since we want to distinguish types that are essentially identical (except
994 for their debug representation), we use a local list here. */
995 static GTY(()) tree vector_type_node_list = 0;
997 /* Handle a "vector_size" attribute; arguments as in
998 struct attribute_spec.handler. */
1000 static tree
1001 handle_vector_size_attribute (tree *node, tree name, tree args,
1002 int flags ATTRIBUTE_UNUSED,
1003 bool *no_add_attrs)
1005 unsigned HOST_WIDE_INT vecsize, nunits;
1006 enum machine_mode mode, orig_mode, new_mode;
1007 tree type = *node, new_type = NULL_TREE;
1008 tree type_list_node;
1010 *no_add_attrs = true;
1012 if (! host_integerp (TREE_VALUE (args), 1))
1014 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1015 return NULL_TREE;
1018 /* Get the vector size (in bytes). */
1019 vecsize = tree_low_cst (TREE_VALUE (args), 1);
1021 /* We need to provide for vector pointers, vector arrays, and
1022 functions returning vectors. For example:
1024 __attribute__((vector_size(16))) short *foo;
1026 In this case, the mode is SI, but the type being modified is
1027 HI, so we need to look further. */
1029 while (POINTER_TYPE_P (type)
1030 || TREE_CODE (type) == FUNCTION_TYPE
1031 || TREE_CODE (type) == METHOD_TYPE
1032 || TREE_CODE (type) == ARRAY_TYPE)
1033 type = TREE_TYPE (type);
1035 /* Get the mode of the type being modified. */
1036 orig_mode = TYPE_MODE (type);
1038 if (TREE_CODE (type) == RECORD_TYPE
1039 || (GET_MODE_CLASS (orig_mode) != MODE_FLOAT
1040 && GET_MODE_CLASS (orig_mode) != MODE_INT)
1041 || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1043 error ("invalid vector type for attribute `%s'",
1044 IDENTIFIER_POINTER (name));
1045 return NULL_TREE;
1048 /* Calculate how many units fit in the vector. */
1049 nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1);
1051 /* Find a suitably sized vector. */
1052 new_mode = VOIDmode;
1053 for (mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_mode) == MODE_INT
1054 ? MODE_VECTOR_INT
1055 : MODE_VECTOR_FLOAT);
1056 mode != VOIDmode;
1057 mode = GET_MODE_WIDER_MODE (mode))
1058 if (vecsize == GET_MODE_SIZE (mode)
1059 && nunits == (unsigned HOST_WIDE_INT) GET_MODE_NUNITS (mode))
1061 new_mode = mode;
1062 break;
1065 if (new_mode == VOIDmode)
1067 error ("no vector mode with the size and type specified could be found");
1068 return NULL_TREE;
1071 for (type_list_node = vector_type_node_list; type_list_node;
1072 type_list_node = TREE_CHAIN (type_list_node))
1074 tree other_type = TREE_VALUE (type_list_node);
1075 tree record = TYPE_DEBUG_REPRESENTATION_TYPE (other_type);
1076 tree fields = TYPE_FIELDS (record);
1077 tree field_type = TREE_TYPE (fields);
1078 tree array_type = TREE_TYPE (field_type);
1079 if (TREE_CODE (fields) != FIELD_DECL
1080 || TREE_CODE (field_type) != ARRAY_TYPE)
1081 abort ();
1083 if (TYPE_MODE (other_type) == mode && type == array_type)
1085 new_type = other_type;
1086 break;
1090 if (new_type == NULL_TREE)
1092 tree index, array, rt, list_node;
1094 new_type = (*lang_hooks.types.type_for_mode) (new_mode,
1095 TREE_UNSIGNED (type));
1097 if (!new_type)
1099 error ("no vector mode with the size and type specified could be found");
1100 return NULL_TREE;
1103 new_type = build_type_copy (new_type);
1105 /* If this is a vector, make sure we either have hardware
1106 support, or we can emulate it. */
1107 if ((GET_MODE_CLASS (mode) == MODE_VECTOR_INT
1108 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
1109 && !vector_mode_valid_p (mode))
1111 error ("unable to emulate '%s'", GET_MODE_NAME (mode));
1112 return NULL_TREE;
1115 /* Set the debug information here, because this is the only
1116 place where we know the underlying type for a vector made
1117 with vector_size. For debugging purposes we pretend a vector
1118 is an array within a structure. */
1119 index = build_int_2 (TYPE_VECTOR_SUBPARTS (new_type) - 1, 0);
1120 array = build_array_type (type, build_index_type (index));
1121 rt = make_node (RECORD_TYPE);
1123 TYPE_FIELDS (rt) = build_decl (FIELD_DECL, get_identifier ("f"), array);
1124 DECL_CONTEXT (TYPE_FIELDS (rt)) = rt;
1125 layout_type (rt);
1126 TYPE_DEBUG_REPRESENTATION_TYPE (new_type) = rt;
1128 list_node = build_tree_list (NULL, new_type);
1129 TREE_CHAIN (list_node) = vector_type_node_list;
1130 vector_type_node_list = list_node;
1133 /* Build back pointers if needed. */
1134 *node = vector_size_helper (*node, new_type);
1136 return NULL_TREE;
1139 /* HACK. GROSS. This is absolutely disgusting. I wish there was a
1140 better way.
1142 If we requested a pointer to a vector, build up the pointers that
1143 we stripped off while looking for the inner type. Similarly for
1144 return values from functions.
1146 The argument "type" is the top of the chain, and "bottom" is the
1147 new type which we will point to. */
1149 static tree
1150 vector_size_helper (tree type, tree bottom)
1152 tree inner, outer;
1154 if (POINTER_TYPE_P (type))
1156 inner = vector_size_helper (TREE_TYPE (type), bottom);
1157 outer = build_pointer_type (inner);
1159 else if (TREE_CODE (type) == ARRAY_TYPE)
1161 inner = vector_size_helper (TREE_TYPE (type), bottom);
1162 outer = build_array_type (inner, TYPE_DOMAIN (type));
1164 else if (TREE_CODE (type) == FUNCTION_TYPE)
1166 inner = vector_size_helper (TREE_TYPE (type), bottom);
1167 outer = build_function_type (inner, TYPE_ARG_TYPES (type));
1169 else if (TREE_CODE (type) == METHOD_TYPE)
1171 inner = vector_size_helper (TREE_TYPE (type), bottom);
1172 outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
1173 inner,
1174 TYPE_ARG_TYPES (type));
1176 else
1177 return bottom;
1179 TREE_READONLY (outer) = TREE_READONLY (type);
1180 TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
1182 return outer;
1185 /* Handle the "nonnull" attribute. */
1186 static tree
1187 handle_nonnull_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
1188 tree args, int flags ATTRIBUTE_UNUSED,
1189 bool *no_add_attrs)
1191 tree type = *node;
1192 unsigned HOST_WIDE_INT attr_arg_num;
1194 /* If no arguments are specified, all pointer arguments should be
1195 non-null. Verify a full prototype is given so that the arguments
1196 will have the correct types when we actually check them later. */
1197 if (! args)
1199 if (! TYPE_ARG_TYPES (type))
1201 error ("nonnull attribute without arguments on a non-prototype");
1202 *no_add_attrs = true;
1204 return NULL_TREE;
1207 /* Argument list specified. Verify that each argument number references
1208 a pointer argument. */
1209 for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
1211 tree argument;
1212 unsigned HOST_WIDE_INT arg_num, ck_num;
1214 if (! get_nonnull_operand (TREE_VALUE (args), &arg_num))
1216 error ("nonnull argument has invalid operand number (arg %lu)",
1217 (unsigned long) attr_arg_num);
1218 *no_add_attrs = true;
1219 return NULL_TREE;
1222 argument = TYPE_ARG_TYPES (type);
1223 if (argument)
1225 for (ck_num = 1; ; ck_num++)
1227 if (! argument || ck_num == arg_num)
1228 break;
1229 argument = TREE_CHAIN (argument);
1232 if (! argument
1233 || TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
1235 error ("nonnull argument with out-of-range operand number (arg %lu, operand %lu)",
1236 (unsigned long) attr_arg_num, (unsigned long) arg_num);
1237 *no_add_attrs = true;
1238 return NULL_TREE;
1241 if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
1243 error ("nonnull argument references non-pointer operand (arg %lu, operand %lu)",
1244 (unsigned long) attr_arg_num, (unsigned long) arg_num);
1245 *no_add_attrs = true;
1246 return NULL_TREE;
1251 return NULL_TREE;
1254 #if 0
1255 /* not in gdc */
1256 /* Check the argument list of a function call for null in argument slots
1257 that are marked as requiring a non-null pointer argument. */
1259 static void
1260 check_function_nonnull (tree attrs, tree params)
1262 tree a, args, param;
1263 int param_num;
1265 for (a = attrs; a; a = TREE_CHAIN (a))
1267 if (is_attribute_p ("nonnull", TREE_PURPOSE (a)))
1269 args = TREE_VALUE (a);
1271 /* Walk the argument list. If we encounter an argument number we
1272 should check for non-null, do it. If the attribute has no args,
1273 then every pointer argument is checked (in which case the check
1274 for pointer type is done in check_nonnull_arg). */
1275 for (param = params, param_num = 1; ;
1276 param_num++, param = TREE_CHAIN (param))
1278 if (! param)
1279 break;
1280 if (! args || nonnull_check_p (args, param_num))
1281 check_function_arguments_recurse (check_nonnull_arg, NULL,
1282 TREE_VALUE (param),
1283 param_num);
1288 #endif
1290 /* Helper for check_function_nonnull; given a list of operands which
1291 must be non-null in ARGS, determine if operand PARAM_NUM should be
1292 checked. */
1294 static bool
1295 nonnull_check_p (tree args, unsigned HOST_WIDE_INT param_num)
1297 unsigned HOST_WIDE_INT arg_num;
1299 for (; args; args = TREE_CHAIN (args))
1301 if (! get_nonnull_operand (TREE_VALUE (args), &arg_num))
1302 abort ();
1304 if (arg_num == param_num)
1305 return true;
1307 return false;
1310 /* Check that the function argument PARAM (which is operand number
1311 PARAM_NUM) is non-null. This is called by check_function_nonnull
1312 via check_function_arguments_recurse. */
1314 static void
1315 check_nonnull_arg (void *ctx ATTRIBUTE_UNUSED, tree param,
1316 unsigned HOST_WIDE_INT param_num)
1318 /* Just skip checking the argument if it's not a pointer. This can
1319 happen if the "nonnull" attribute was given without an operand
1320 list (which means to check every pointer argument). */
1322 if (TREE_CODE (TREE_TYPE (param)) != POINTER_TYPE)
1323 return;
1325 if (integer_zerop (param))
1326 warning ("null argument where non-null required (arg %lu)",
1327 (unsigned long) param_num);
1330 /* Helper for nonnull attribute handling; fetch the operand number
1331 from the attribute argument list. */
1333 static bool
1334 get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
1336 /* Strip any conversions from the arg number and verify they
1337 are constants. */
1338 while (TREE_CODE (arg_num_expr) == NOP_EXPR
1339 || TREE_CODE (arg_num_expr) == CONVERT_EXPR
1340 || TREE_CODE (arg_num_expr) == NON_LVALUE_EXPR)
1341 arg_num_expr = TREE_OPERAND (arg_num_expr, 0);
1343 if (TREE_CODE (arg_num_expr) != INTEGER_CST
1344 || TREE_INT_CST_HIGH (arg_num_expr) != 0)
1345 return false;
1347 *valp = TREE_INT_CST_LOW (arg_num_expr);
1348 return true;
1351 /* Handle a "nothrow" attribute; arguments as in
1352 struct attribute_spec.handler. */
1354 static tree
1355 handle_nothrow_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
1356 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1358 if (TREE_CODE (*node) == FUNCTION_DECL)
1359 TREE_NOTHROW (*node) = 1;
1360 /* ??? TODO: Support types. */
1361 else
1363 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1364 *no_add_attrs = true;
1367 return NULL_TREE;
1370 #if 0
1371 /* not in gdc */
1372 /* Handle a "cleanup" attribute; arguments as in
1373 struct attribute_spec.handler. */
1375 static tree
1376 handle_cleanup_attribute (tree *node, tree name, tree args,
1377 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1379 tree decl = *node;
1380 tree cleanup_id, cleanup_decl;
1382 /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
1383 for global destructors in C++. This requires infrastructure that
1384 we don't have generically at the moment. It's also not a feature
1385 we'd be missing too much, since we do have attribute constructor. */
1386 if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
1388 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1389 *no_add_attrs = true;
1390 return NULL_TREE;
1393 /* Verify that the argument is a function in scope. */
1394 /* ??? We could support pointers to functions here as well, if
1395 that was considered desirable. */
1396 cleanup_id = TREE_VALUE (args);
1397 if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
1399 error ("cleanup arg not an identifier");
1400 *no_add_attrs = true;
1401 return NULL_TREE;
1403 cleanup_decl = lookup_name (cleanup_id);
1404 if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
1406 error ("cleanup arg not a function");
1407 *no_add_attrs = true;
1408 return NULL_TREE;
1411 /* That the function has proper type is checked with the
1412 eventual call to build_function_call. */
1414 return NULL_TREE;
1416 #endif
1418 /* Handle a "warn_unused_result" attribute. No special handling. */
1420 static tree
1421 handle_warn_unused_result_attribute (tree *node, tree name,
1422 tree args ATTRIBUTE_UNUSED,
1423 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1425 /* Ignore the attribute for functions not returning any value. */
1426 if (VOID_TYPE_P (TREE_TYPE (*node)))
1428 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1429 *no_add_attrs = true;
1432 return NULL_TREE;
1435 #if 0
1436 /* not in gdc */
1437 /* Check for valid arguments being passed to a function. */
1438 static void
1439 check_function_arguments (tree attrs, tree params)
1441 /* Check for null being passed in a pointer argument that must be
1442 non-null. We also need to do this if format checking is enabled. */
1444 if (warn_nonnull)
1445 check_function_nonnull (attrs, params);
1447 /* Check for errors in format strings. */
1449 if (warn_format)
1450 check_function_format (NULL, attrs, params);
1452 #endif
1454 /* Generic argument checking recursion routine. PARAM is the argument to
1455 be checked. PARAM_NUM is the number of the argument. CALLBACK is invoked
1456 once the argument is resolved. CTX is context for the callback. */
1457 void
1458 check_function_arguments_recurse (void (*callback)
1459 (void *, tree, unsigned HOST_WIDE_INT),
1460 void *ctx, tree param,
1461 unsigned HOST_WIDE_INT param_num)
1463 if (TREE_CODE (param) == NOP_EXPR)
1465 /* Strip coercion. */
1466 check_function_arguments_recurse (callback, ctx,
1467 TREE_OPERAND (param, 0), param_num);
1468 return;
1471 if (TREE_CODE (param) == CALL_EXPR)
1473 tree type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (param, 0)));
1474 tree attrs;
1475 bool found_format_arg = false;
1477 /* See if this is a call to a known internationalization function
1478 that modifies a format arg. Such a function may have multiple
1479 format_arg attributes (for example, ngettext). */
1481 for (attrs = TYPE_ATTRIBUTES (type);
1482 attrs;
1483 attrs = TREE_CHAIN (attrs))
1484 if (is_attribute_p ("format_arg", TREE_PURPOSE (attrs)))
1486 tree inner_args;
1487 tree format_num_expr;
1488 int format_num;
1489 int i;
1491 /* Extract the argument number, which was previously checked
1492 to be valid. */
1493 format_num_expr = TREE_VALUE (TREE_VALUE (attrs));
1494 while (TREE_CODE (format_num_expr) == NOP_EXPR
1495 || TREE_CODE (format_num_expr) == CONVERT_EXPR
1496 || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
1497 format_num_expr = TREE_OPERAND (format_num_expr, 0);
1499 if (TREE_CODE (format_num_expr) != INTEGER_CST
1500 || TREE_INT_CST_HIGH (format_num_expr) != 0)
1501 abort ();
1503 format_num = TREE_INT_CST_LOW (format_num_expr);
1505 for (inner_args = TREE_OPERAND (param, 1), i = 1;
1506 inner_args != 0;
1507 inner_args = TREE_CHAIN (inner_args), i++)
1508 if (i == format_num)
1510 check_function_arguments_recurse (callback, ctx,
1511 TREE_VALUE (inner_args),
1512 param_num);
1513 found_format_arg = true;
1514 break;
1518 /* If we found a format_arg attribute and did a recursive check,
1519 we are done with checking this argument. Otherwise, we continue
1520 and this will be considered a non-literal. */
1521 if (found_format_arg)
1522 return;
1525 if (TREE_CODE (param) == COND_EXPR)
1527 /* Check both halves of the conditional expression. */
1528 check_function_arguments_recurse (callback, ctx,
1529 TREE_OPERAND (param, 1), param_num);
1530 check_function_arguments_recurse (callback, ctx,
1531 TREE_OPERAND (param, 2), param_num);
1532 return;
1535 (*callback) (ctx, param, param_num);