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,
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
,
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,
22 static tree
handle_tls_model_attribute (tree
*, tree
, tree
, int,
24 static tree
handle_no_instrument_function_attribute (tree
*, tree
,
26 static tree
handle_malloc_attribute (tree
*, tree
, tree
, int, bool *);
27 static tree
handle_no_limit_stack_attribute (tree
*, tree
, tree
, int,
29 static tree
handle_pure_attribute (tree
*, tree
, tree
, int, bool *);
30 static tree
handle_deprecated_attribute (tree
*, tree
, tree
, int,
32 static tree
handle_vector_size_attribute (tree
*, tree
, tree
, int,
34 static tree
handle_nonnull_attribute (tree
*, tree
, tree
, int, bool *);
35 static tree
handle_nothrow_attribute (tree
*, tree
, tree
, int, bool *);
36 //static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
37 static tree
handle_warn_unused_result_attribute (tree
*, tree
, tree
, int,
39 static tree
handle_sentinel_attribute (tree
*, tree
, tree
, int, bool *);
41 //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
*);
45 //static int resort_field_decl_cmp (const void *, const void *);
47 /* extra for gdc copy: */
48 static void check_function_arguments_recurse (void (*)
50 unsigned HOST_WIDE_INT
),
52 unsigned HOST_WIDE_INT
);
55 handle_format_arg_attribute (tree
*node ATTRIBUTE_UNUSED
, tree name ATTRIBUTE_UNUSED
,
56 tree args ATTRIBUTE_UNUSED
, int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs ATTRIBUTE_UNUSED
)
61 handle_format_attribute (tree
*node ATTRIBUTE_UNUSED
, tree name ATTRIBUTE_UNUSED
, tree args ATTRIBUTE_UNUSED
,
62 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs ATTRIBUTE_UNUSED
)
68 /* Table of machine-independent attributes common to all C-like languages. */
69 const struct attribute_spec d_common_attribute_table
[] =
71 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
72 { "packed", 0, 0, false, false, false,
73 handle_packed_attribute
},
74 { "nocommon", 0, 0, true, false, false,
75 handle_nocommon_attribute
},
76 { "common", 0, 0, true, false, false,
77 handle_common_attribute
},
78 /* FIXME: logically, noreturn attributes should be listed as
79 "false, true, true" and apply to function types. But implementing this
80 would require all the places in the compiler that use TREE_THIS_VOLATILE
81 on a decl to identify non-returning functions to be located and fixed
82 to check the function type instead. */
83 { "noreturn", 0, 0, true, false, false,
84 handle_noreturn_attribute
},
85 { "volatile", 0, 0, true, false, false,
86 handle_noreturn_attribute
},
87 { "noinline", 0, 0, true, false, false,
88 handle_noinline_attribute
},
89 { "always_inline", 0, 0, true, false, false,
90 handle_always_inline_attribute
},
91 { "used", 0, 0, true, false, false,
92 handle_used_attribute
},
93 { "unused", 0, 0, false, false, false,
94 handle_unused_attribute
},
95 /* The same comments as for noreturn attributes apply to const ones. */
96 { "const", 0, 0, true, false, false,
97 handle_const_attribute
},
98 { "transparent_union", 0, 0, false, false, false,
99 handle_transparent_union_attribute
},
100 { "constructor", 0, 0, true, false, false,
101 handle_constructor_attribute
},
102 { "destructor", 0, 0, true, false, false,
103 handle_destructor_attribute
},
104 { "mode", 1, 1, false, true, false,
105 handle_mode_attribute
},
106 { "section", 1, 1, true, false, false,
107 handle_section_attribute
},
108 { "aligned", 0, 1, false, false, false,
109 handle_aligned_attribute
},
110 { "weak", 0, 0, true, false, false,
111 handle_weak_attribute
},
112 { "alias", 1, 1, true, false, false,
113 handle_alias_attribute
},
114 { "no_instrument_function", 0, 0, true, false, false,
115 handle_no_instrument_function_attribute
},
116 { "malloc", 0, 0, true, false, false,
117 handle_malloc_attribute
},
118 { "no_stack_limit", 0, 0, true, false, false,
119 handle_no_limit_stack_attribute
},
120 { "pure", 0, 0, true, false, false,
121 handle_pure_attribute
},
122 { "deprecated", 0, 0, false, false, false,
123 handle_deprecated_attribute
},
124 { "vector_size", 1, 1, false, true, false,
125 handle_vector_size_attribute
},
126 { "visibility", 1, 1, false, false, false,
127 handle_visibility_attribute
},
128 { "tls_model", 1, 1, true, false, false,
129 handle_tls_model_attribute
},
130 { "nonnull", 0, -1, false, true, true,
131 handle_nonnull_attribute
},
132 { "nothrow", 0, 0, true, false, false,
133 handle_nothrow_attribute
},
134 { "may_alias", 0, 0, false, true, false, NULL
},
135 /* not in gdc// { "cleanup", 1, 1, true, false, false,
136 handle_cleanup_attribute },*/
137 { "warn_unused_result", 0, 0, false, true, true,
138 handle_warn_unused_result_attribute
},
139 { "sentinel", 0, 1, false, true, true,
140 handle_sentinel_attribute
},
141 { NULL
, 0, 0, false, false, false, NULL
}
144 /* Give the specifications for the format attributes, used by C and all
147 const struct attribute_spec d_common_format_attribute_table
[] =
149 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
150 { "format", 3, 3, false, true, true,
151 handle_format_attribute
},
152 { "format_arg", 1, 1, false, true, true,
153 handle_format_arg_attribute
},
154 { NULL
, 0, 0, false, false, false, NULL
}
157 /* Attribute handlers common to C front ends. */
159 /* Handle a "packed" attribute; arguments as in
160 struct attribute_spec.handler. */
163 handle_packed_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
164 int flags
, bool *no_add_attrs
)
168 if (!(flags
& (int) ATTR_FLAG_TYPE_IN_PLACE
))
169 *node
= build_variant_type_copy (*node
);
170 TYPE_PACKED (*node
) = 1;
171 if (TYPE_MAIN_VARIANT (*node
) == *node
)
173 /* If it is the main variant, then pack the other variants
174 too. This happens in,
177 struct Foo const *ptr; // creates a variant w/o packed flag
178 } __ attribute__((packed)); // packs it now.
182 for (probe
= *node
; probe
; probe
= TYPE_NEXT_VARIANT (probe
))
183 TYPE_PACKED (probe
) = 1;
187 else if (TREE_CODE (*node
) == FIELD_DECL
)
188 DECL_PACKED (*node
) = 1;
189 /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
190 used for DECL_REGISTER. It wouldn't mean anything anyway.
191 We can't set DECL_PACKED on the type of a TYPE_DECL, because
192 that changes what the typedef is typing. */
195 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
196 *no_add_attrs
= true;
202 /* Handle a "nocommon" attribute; arguments as in
203 struct attribute_spec.handler. */
206 handle_nocommon_attribute (tree
*node
, tree name
,
207 tree
ARG_UNUSED (args
),
208 int ARG_UNUSED (flags
), bool *no_add_attrs
)
210 if (TREE_CODE (*node
) == VAR_DECL
)
211 DECL_COMMON (*node
) = 0;
214 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
215 *no_add_attrs
= true;
221 /* Handle a "common" attribute; arguments as in
222 struct attribute_spec.handler. */
225 handle_common_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
226 int ARG_UNUSED (flags
), bool *no_add_attrs
)
228 if (TREE_CODE (*node
) == VAR_DECL
)
229 DECL_COMMON (*node
) = 1;
232 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
233 *no_add_attrs
= true;
239 /* Handle a "noreturn" attribute; arguments as in
240 struct attribute_spec.handler. */
243 handle_noreturn_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
244 int ARG_UNUSED (flags
), bool *no_add_attrs
)
246 tree type
= TREE_TYPE (*node
);
248 /* See FIXME comment in c_common_attribute_table. */
249 if (TREE_CODE (*node
) == FUNCTION_DECL
)
250 TREE_THIS_VOLATILE (*node
) = 1;
251 else if (TREE_CODE (type
) == POINTER_TYPE
252 && TREE_CODE (TREE_TYPE (type
)) == FUNCTION_TYPE
)
255 (build_type_variant (TREE_TYPE (type
),
256 TYPE_READONLY (TREE_TYPE (type
)), 1));
259 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
260 *no_add_attrs
= true;
266 /* Handle a "noinline" attribute; arguments as in
267 struct attribute_spec.handler. */
270 handle_noinline_attribute (tree
*node
, tree name
,
271 tree
ARG_UNUSED (args
),
272 int ARG_UNUSED (flags
), bool *no_add_attrs
)
274 if (TREE_CODE (*node
) == FUNCTION_DECL
)
275 DECL_UNINLINABLE (*node
) = 1;
278 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
279 *no_add_attrs
= true;
285 /* Handle a "always_inline" attribute; arguments as in
286 struct attribute_spec.handler. */
289 handle_always_inline_attribute (tree
*node
, tree name
,
290 tree
ARG_UNUSED (args
),
291 int ARG_UNUSED (flags
),
294 if (TREE_CODE (*node
) == FUNCTION_DECL
)
296 /* Do nothing else, just set the attribute. We'll get at
297 it later with lookup_attribute. */
301 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
302 *no_add_attrs
= true;
308 /* Handle a "used" attribute; arguments as in
309 struct attribute_spec.handler. */
312 handle_used_attribute (tree
*pnode
, tree name
, tree
ARG_UNUSED (args
),
313 int ARG_UNUSED (flags
), bool *no_add_attrs
)
317 if (TREE_CODE (node
) == FUNCTION_DECL
318 || (TREE_CODE (node
) == VAR_DECL
&& TREE_STATIC (node
)))
320 TREE_USED (node
) = 1;
321 DECL_PRESERVE_P (node
) = 1;
325 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
326 *no_add_attrs
= true;
332 /* Handle a "unused" attribute; arguments as in
333 struct attribute_spec.handler. */
336 handle_unused_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
337 int flags
, bool *no_add_attrs
)
343 if (TREE_CODE (decl
) == PARM_DECL
344 || TREE_CODE (decl
) == VAR_DECL
345 || TREE_CODE (decl
) == FUNCTION_DECL
346 || TREE_CODE (decl
) == LABEL_DECL
347 || TREE_CODE (decl
) == TYPE_DECL
)
348 TREE_USED (decl
) = 1;
351 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
352 *no_add_attrs
= true;
357 if (!(flags
& (int) ATTR_FLAG_TYPE_IN_PLACE
))
358 *node
= build_variant_type_copy (*node
);
359 TREE_USED (*node
) = 1;
365 /* Handle a "const" attribute; arguments as in
366 struct attribute_spec.handler. */
369 handle_const_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
370 int ARG_UNUSED (flags
), bool *no_add_attrs
)
372 tree type
= TREE_TYPE (*node
);
374 /* See FIXME comment on noreturn in c_common_attribute_table. */
375 if (TREE_CODE (*node
) == FUNCTION_DECL
)
376 TREE_READONLY (*node
) = 1;
377 else if (TREE_CODE (type
) == POINTER_TYPE
378 && TREE_CODE (TREE_TYPE (type
)) == FUNCTION_TYPE
)
381 (build_type_variant (TREE_TYPE (type
), 1,
382 TREE_THIS_VOLATILE (TREE_TYPE (type
))));
385 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
386 *no_add_attrs
= true;
392 /* Handle a "transparent_union" attribute; arguments as in
393 struct attribute_spec.handler. */
396 handle_transparent_union_attribute (tree
*node
, tree name
,
397 tree
ARG_UNUSED (args
), int flags
,
400 tree decl
= NULL_TREE
;
407 type
= &TREE_TYPE (decl
);
408 is_type
= TREE_CODE (*node
) == TYPE_DECL
;
410 else if (TYPE_P (*node
))
411 type
= node
, is_type
= 1;
414 && TREE_CODE (*type
) == UNION_TYPE
416 || (TYPE_FIELDS (*type
) != 0
417 && TYPE_MODE (*type
) == DECL_MODE (TYPE_FIELDS (*type
)))))
419 if (!(flags
& (int) ATTR_FLAG_TYPE_IN_PLACE
))
420 *type
= build_variant_type_copy (*type
);
421 TYPE_TRANSPARENT_UNION (*type
) = 1;
423 else if (decl
!= 0 && TREE_CODE (decl
) == PARM_DECL
424 && TREE_CODE (*type
) == UNION_TYPE
425 && TYPE_MODE (*type
) == DECL_MODE (TYPE_FIELDS (*type
)))
426 DECL_TRANSPARENT_UNION (decl
) = 1;
429 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
430 *no_add_attrs
= true;
436 /* Handle a "constructor" attribute; arguments as in
437 struct attribute_spec.handler. */
440 handle_constructor_attribute (tree
*node
, tree name
,
441 tree
ARG_UNUSED (args
),
442 int ARG_UNUSED (flags
),
446 tree type
= TREE_TYPE (decl
);
448 if (TREE_CODE (decl
) == FUNCTION_DECL
449 && TREE_CODE (type
) == FUNCTION_TYPE
450 && decl_function_context (decl
) == 0)
452 DECL_STATIC_CONSTRUCTOR (decl
) = 1;
453 TREE_USED (decl
) = 1;
457 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
458 *no_add_attrs
= true;
464 /* Handle a "destructor" attribute; arguments as in
465 struct attribute_spec.handler. */
468 handle_destructor_attribute (tree
*node
, tree name
,
469 tree
ARG_UNUSED (args
),
470 int ARG_UNUSED (flags
),
474 tree type
= TREE_TYPE (decl
);
476 if (TREE_CODE (decl
) == FUNCTION_DECL
477 && TREE_CODE (type
) == FUNCTION_TYPE
478 && decl_function_context (decl
) == 0)
480 DECL_STATIC_DESTRUCTOR (decl
) = 1;
481 TREE_USED (decl
) = 1;
485 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
486 *no_add_attrs
= true;
492 /* Handle a "mode" attribute; arguments as in
493 struct attribute_spec.handler. */
496 handle_mode_attribute (tree
*node
, tree name
, tree args
,
497 int ARG_UNUSED (flags
), bool *no_add_attrs
)
501 *no_add_attrs
= true;
503 if (TREE_CODE (TREE_VALUE (args
)) != IDENTIFIER_NODE
)
504 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
508 const char *p
= IDENTIFIER_POINTER (TREE_VALUE (args
));
509 int len
= strlen (p
);
510 enum machine_mode mode
= VOIDmode
;
514 if (len
> 4 && p
[0] == '_' && p
[1] == '_'
515 && p
[len
- 1] == '_' && p
[len
- 2] == '_')
517 char *newp
= (char *) alloca (len
- 1);
519 strcpy (newp
, &p
[2]);
520 newp
[len
- 4] = '\0';
524 /* Change this type to have a type with the specified mode.
525 First check for the special modes. */
526 if (!strcmp (p
, "byte"))
528 else if (!strcmp (p
, "word"))
530 else if (!strcmp (p
, "pointer"))
533 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
534 if (!strcmp (p
, GET_MODE_NAME (j
)))
536 mode
= (enum machine_mode
) j
;
540 if (mode
== VOIDmode
)
542 error ("unknown machine mode %qs", p
);
547 switch (GET_MODE_CLASS (mode
))
550 case MODE_PARTIAL_INT
:
552 valid_mode
= targetm
.scalar_mode_supported_p (mode
);
555 case MODE_COMPLEX_INT
:
556 case MODE_COMPLEX_FLOAT
:
557 valid_mode
= targetm
.scalar_mode_supported_p (GET_MODE_INNER (mode
));
560 case MODE_VECTOR_INT
:
561 case MODE_VECTOR_FLOAT
:
562 warning ("specifying vector types with __attribute__ ((mode)) "
564 warning ("use __attribute__ ((vector_size)) instead");
565 valid_mode
= vector_mode_valid_p (mode
);
573 error ("unable to emulate %qs", p
);
577 if (POINTER_TYPE_P (type
))
579 tree (*fn
)(tree
, enum machine_mode
, bool);
581 if (!targetm
.valid_pointer_mode (mode
))
583 error ("invalid pointer mode %qs", p
);
587 if (TREE_CODE (type
) == POINTER_TYPE
)
588 fn
= build_pointer_type_for_mode
;
590 fn
= build_reference_type_for_mode
;
591 typefm
= fn (TREE_TYPE (type
), mode
, false);
594 typefm
= lang_hooks
.types
.type_for_mode (mode
, TYPE_UNSIGNED (type
));
596 if (typefm
== NULL_TREE
)
598 error ("no data type for mode %qs", p
);
601 else if (TREE_CODE (type
) == ENUMERAL_TYPE
)
603 /* For enumeral types, copy the precision from the integer
604 type returned above. If not an INTEGER_TYPE, we can't use
605 this mode for this type. */
606 if (TREE_CODE (typefm
) != INTEGER_TYPE
)
608 error ("cannot use mode %qs for enumeral types", p
);
612 if (!(flags
& (int) ATTR_FLAG_TYPE_IN_PLACE
))
613 type
= build_variant_type_copy (type
);
615 /* We cannot use layout_type here, because that will attempt
616 to re-layout all variants, corrupting our original. */
617 TYPE_PRECISION (type
) = TYPE_PRECISION (typefm
);
618 TYPE_MIN_VALUE (type
) = TYPE_MIN_VALUE (typefm
);
619 TYPE_MAX_VALUE (type
) = TYPE_MAX_VALUE (typefm
);
620 TYPE_SIZE (type
) = TYPE_SIZE (typefm
);
621 TYPE_SIZE_UNIT (type
) = TYPE_SIZE_UNIT (typefm
);
622 TYPE_MODE (type
) = TYPE_MODE (typefm
);
623 if (!TYPE_USER_ALIGN (type
))
624 TYPE_ALIGN (type
) = TYPE_ALIGN (typefm
);
628 else if (VECTOR_MODE_P (mode
)
629 ? TREE_CODE (type
) != TREE_CODE (TREE_TYPE (typefm
))
630 : TREE_CODE (type
) != TREE_CODE (typefm
))
632 error ("mode %qs applied to inappropriate type", p
);
642 /* Handle a "section" attribute; arguments as in
643 struct attribute_spec.handler. */
646 handle_section_attribute (tree
*node
, tree
ARG_UNUSED (name
), tree args
,
647 int ARG_UNUSED (flags
), bool *no_add_attrs
)
651 if (targetm
.have_named_sections
)
653 user_defined_section_attribute
= true;
655 if ((TREE_CODE (decl
) == FUNCTION_DECL
656 || TREE_CODE (decl
) == VAR_DECL
)
657 && TREE_CODE (TREE_VALUE (args
)) == STRING_CST
)
659 if (TREE_CODE (decl
) == VAR_DECL
660 && current_function_decl
!= NULL_TREE
661 && ! (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
)))
663 error ("%Jsection attribute cannot be specified for "
664 "local variables", decl
);
665 *no_add_attrs
= true;
668 /* The decl may have already been given a section attribute
669 from a previous declaration. Ensure they match. */
670 else if (DECL_SECTION_NAME (decl
) != NULL_TREE
671 && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl
)),
672 TREE_STRING_POINTER (TREE_VALUE (args
))) != 0)
674 error ("%Jsection of %qD conflicts with previous declaration",
676 *no_add_attrs
= true;
679 DECL_SECTION_NAME (decl
) = TREE_VALUE (args
);
683 error ("%Jsection attribute not allowed for %qD", *node
, *node
);
684 *no_add_attrs
= true;
689 error ("%Jsection attributes are not supported for this target", *node
);
690 *no_add_attrs
= true;
696 /* Handle a "aligned" attribute; arguments as in
697 struct attribute_spec.handler. */
700 handle_aligned_attribute (tree
*node
, tree
ARG_UNUSED (name
), tree args
,
701 int flags
, bool *no_add_attrs
)
703 tree decl
= NULL_TREE
;
706 tree align_expr
= (args
? TREE_VALUE (args
)
707 : size_int (BIGGEST_ALIGNMENT
/ BITS_PER_UNIT
));
713 type
= &TREE_TYPE (decl
);
714 is_type
= TREE_CODE (*node
) == TYPE_DECL
;
716 else if (TYPE_P (*node
))
717 type
= node
, is_type
= 1;
719 /* Strip any NOPs of any kind. */
720 while (TREE_CODE (align_expr
) == NOP_EXPR
721 || TREE_CODE (align_expr
) == CONVERT_EXPR
722 || TREE_CODE (align_expr
) == NON_LVALUE_EXPR
)
723 align_expr
= TREE_OPERAND (align_expr
, 0);
725 if (TREE_CODE (align_expr
) != INTEGER_CST
)
727 error ("requested alignment is not a constant");
728 *no_add_attrs
= true;
730 else if ((i
= tree_log2 (align_expr
)) == -1)
732 error ("requested alignment is not a power of 2");
733 *no_add_attrs
= true;
735 else if (i
> HOST_BITS_PER_INT
- 2)
737 error ("requested alignment is too large");
738 *no_add_attrs
= true;
742 /* If we have a TYPE_DECL, then copy the type, so that we
743 don't accidentally modify a builtin type. See pushdecl. */
744 if (decl
&& TREE_TYPE (decl
) != error_mark_node
745 && DECL_ORIGINAL_TYPE (decl
) == NULL_TREE
)
747 tree tt
= TREE_TYPE (decl
);
748 *type
= build_variant_type_copy (*type
);
749 DECL_ORIGINAL_TYPE (decl
) = tt
;
750 TYPE_NAME (*type
) = decl
;
751 TREE_USED (*type
) = TREE_USED (decl
);
752 TREE_TYPE (decl
) = *type
;
754 else if (!(flags
& (int) ATTR_FLAG_TYPE_IN_PLACE
))
755 *type
= build_variant_type_copy (*type
);
757 TYPE_ALIGN (*type
) = (1 << i
) * BITS_PER_UNIT
;
758 TYPE_USER_ALIGN (*type
) = 1;
760 else if (TREE_CODE (decl
) != VAR_DECL
761 && TREE_CODE (decl
) != FIELD_DECL
)
763 error ("%Jalignment may not be specified for %qD", decl
, decl
);
764 *no_add_attrs
= true;
768 DECL_ALIGN (decl
) = (1 << i
) * BITS_PER_UNIT
;
769 DECL_USER_ALIGN (decl
) = 1;
775 /* Handle a "weak" attribute; arguments as in
776 struct attribute_spec.handler. */
779 handle_weak_attribute (tree
*node
, tree
ARG_UNUSED (name
),
780 tree
ARG_UNUSED (args
),
781 int ARG_UNUSED (flags
),
782 bool * ARG_UNUSED (no_add_attrs
))
784 declare_weak (*node
);
789 /* Handle an "alias" attribute; arguments as in
790 struct attribute_spec.handler. */
793 handle_alias_attribute (tree
*node
, tree name
, tree args
,
794 int ARG_UNUSED (flags
), bool *no_add_attrs
)
798 if ((TREE_CODE (decl
) == FUNCTION_DECL
&& DECL_INITIAL (decl
))
799 || (TREE_CODE (decl
) != FUNCTION_DECL
&& !DECL_EXTERNAL (decl
)))
801 error ("%J%qD defined both normally and as an alias", decl
, decl
);
802 *no_add_attrs
= true;
805 /* Note that the very first time we process a nested declaration,
806 decl_function_context will not be set. Indeed, *would* never
807 be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that
808 we do below. After such frobbery, pushdecl would set the context.
809 In any case, this is never what we want. */
810 else if (decl_function_context (decl
) == 0 && current_function_decl
== NULL
)
814 id
= TREE_VALUE (args
);
815 if (TREE_CODE (id
) != STRING_CST
)
817 error ("alias argument not a string");
818 *no_add_attrs
= true;
821 id
= get_identifier (TREE_STRING_POINTER (id
));
822 /* This counts as a use of the object pointed to. */
825 if (TREE_CODE (decl
) == FUNCTION_DECL
)
826 DECL_INITIAL (decl
) = error_mark_node
;
829 DECL_EXTERNAL (decl
) = 0;
830 TREE_STATIC (decl
) = 1;
835 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
836 *no_add_attrs
= true;
842 /* Handle an "visibility" attribute; arguments as in
843 struct attribute_spec.handler. */
846 handle_visibility_attribute (tree
*node
, tree name
, tree args
,
847 int ARG_UNUSED (flags
),
851 tree id
= TREE_VALUE (args
);
853 *no_add_attrs
= true;
857 if (TREE_CODE (*node
) != RECORD_TYPE
&& TREE_CODE (*node
) != UNION_TYPE
)
859 warning ("%qs attribute ignored on non-class types",
860 IDENTIFIER_POINTER (name
));
864 else if (decl_function_context (decl
) != 0 || !TREE_PUBLIC (decl
))
866 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
870 if (TREE_CODE (id
) != STRING_CST
)
872 error ("visibility argument not a string");
876 /* If this is a type, set the visibility on the type decl. */
879 decl
= TYPE_NAME (decl
);
882 if (TREE_CODE (decl
) == IDENTIFIER_NODE
)
884 warning ("%qE attribute ignored on types",
890 if (strcmp (TREE_STRING_POINTER (id
), "default") == 0)
891 DECL_VISIBILITY (decl
) = VISIBILITY_DEFAULT
;
892 else if (strcmp (TREE_STRING_POINTER (id
), "internal") == 0)
893 DECL_VISIBILITY (decl
) = VISIBILITY_INTERNAL
;
894 else if (strcmp (TREE_STRING_POINTER (id
), "hidden") == 0)
895 DECL_VISIBILITY (decl
) = VISIBILITY_HIDDEN
;
896 else if (strcmp (TREE_STRING_POINTER (id
), "protected") == 0)
897 DECL_VISIBILITY (decl
) = VISIBILITY_PROTECTED
;
899 error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
900 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
902 /* For decls only, go ahead and attach the attribute to the node as well.
903 This is needed so we can determine whether we have VISIBILITY_DEFAULT
904 because the visibility was not specified, or because it was explicitly
905 overridden from the class visibility. */
907 *no_add_attrs
= false;
912 /* Handle an "tls_model" attribute; arguments as in
913 struct attribute_spec.handler. */
916 handle_tls_model_attribute (tree
*node
, tree name
, tree args
,
917 int ARG_UNUSED (flags
), bool *no_add_attrs
)
921 if (!DECL_THREAD_LOCAL (decl
))
923 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
924 *no_add_attrs
= true;
930 id
= TREE_VALUE (args
);
931 if (TREE_CODE (id
) != STRING_CST
)
933 error ("tls_model argument not a string");
934 *no_add_attrs
= true;
937 if (strcmp (TREE_STRING_POINTER (id
), "local-exec")
938 && strcmp (TREE_STRING_POINTER (id
), "initial-exec")
939 && strcmp (TREE_STRING_POINTER (id
), "local-dynamic")
940 && strcmp (TREE_STRING_POINTER (id
), "global-dynamic"))
942 error ("tls_model argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
943 *no_add_attrs
= true;
951 /* Handle a "no_instrument_function" attribute; arguments as in
952 struct attribute_spec.handler. */
955 handle_no_instrument_function_attribute (tree
*node
, tree name
,
956 tree
ARG_UNUSED (args
),
957 int ARG_UNUSED (flags
),
962 if (TREE_CODE (decl
) != FUNCTION_DECL
)
964 error ("%J%qE attribute applies only to functions", decl
, name
);
965 *no_add_attrs
= true;
967 else if (DECL_INITIAL (decl
))
969 error ("%Jcan%'t set %qE attribute after definition", decl
, name
);
970 *no_add_attrs
= true;
973 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl
) = 1;
978 /* Handle a "malloc" attribute; arguments as in
979 struct attribute_spec.handler. */
982 handle_malloc_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
983 int ARG_UNUSED (flags
), bool *no_add_attrs
)
985 if (TREE_CODE (*node
) == FUNCTION_DECL
)
986 DECL_IS_MALLOC (*node
) = 1;
987 /* ??? TODO: Support types. */
990 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
991 *no_add_attrs
= true;
997 /* Handle a "no_limit_stack" attribute; arguments as in
998 struct attribute_spec.handler. */
1001 handle_no_limit_stack_attribute (tree
*node
, tree name
,
1002 tree
ARG_UNUSED (args
),
1003 int ARG_UNUSED (flags
),
1008 if (TREE_CODE (decl
) != FUNCTION_DECL
)
1010 error ("%J%qE attribute applies only to functions", decl
, name
);
1011 *no_add_attrs
= true;
1013 else if (DECL_INITIAL (decl
))
1015 error ("%Jcan%'t set %qE attribute after definition", decl
, name
);
1016 *no_add_attrs
= true;
1019 DECL_NO_LIMIT_STACK (decl
) = 1;
1024 /* Handle a "pure" attribute; arguments as in
1025 struct attribute_spec.handler. */
1028 handle_pure_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
1029 int ARG_UNUSED (flags
), bool *no_add_attrs
)
1031 if (TREE_CODE (*node
) == FUNCTION_DECL
)
1032 DECL_IS_PURE (*node
) = 1;
1033 /* ??? TODO: Support types. */
1036 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
1037 *no_add_attrs
= true;
1043 /* Handle a "deprecated" attribute; arguments as in
1044 struct attribute_spec.handler. */
1047 handle_deprecated_attribute (tree
*node
, tree name
,
1048 tree
ARG_UNUSED (args
), int flags
,
1051 tree type
= NULL_TREE
;
1053 const char *what
= NULL
;
1058 type
= TREE_TYPE (decl
);
1060 if (TREE_CODE (decl
) == TYPE_DECL
1061 || TREE_CODE (decl
) == PARM_DECL
1062 || TREE_CODE (decl
) == VAR_DECL
1063 || TREE_CODE (decl
) == FUNCTION_DECL
1064 || TREE_CODE (decl
) == FIELD_DECL
)
1065 TREE_DEPRECATED (decl
) = 1;
1069 else if (TYPE_P (*node
))
1071 if (!(flags
& (int) ATTR_FLAG_TYPE_IN_PLACE
))
1072 *node
= build_variant_type_copy (*node
);
1073 TREE_DEPRECATED (*node
) = 1;
1081 *no_add_attrs
= true;
1082 if (type
&& TYPE_NAME (type
))
1084 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
1085 what
= IDENTIFIER_POINTER (TYPE_NAME (*node
));
1086 else if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
1087 && DECL_NAME (TYPE_NAME (type
)))
1088 what
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
1091 warning ("%qs attribute ignored for %qs",
1092 IDENTIFIER_POINTER (name
), what
);
1094 warning ("%qs attribute ignored",
1095 IDENTIFIER_POINTER (name
));
1101 /* Handle a "vector_size" attribute; arguments as in
1102 struct attribute_spec.handler. */
1105 handle_vector_size_attribute (tree
*node
, tree name
, tree args
,
1106 int ARG_UNUSED (flags
),
1109 unsigned HOST_WIDE_INT vecsize
, nunits
;
1110 enum machine_mode orig_mode
;
1111 tree type
= *node
, new_type
, size
;
1113 *no_add_attrs
= true;
1115 /* Stripping NON_LVALUE_EXPR allows declarations such as
1116 typedef short v4si __attribute__((vector_size (4 * sizeof(short)))). */
1117 size
= TREE_VALUE (args
);
1118 if (TREE_CODE (size
) == NON_LVALUE_EXPR
)
1119 size
= TREE_OPERAND (size
, 0);
1121 if (!host_integerp (size
, 1))
1123 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
1127 /* Get the vector size (in bytes). */
1128 vecsize
= tree_low_cst (size
, 1);
1130 /* We need to provide for vector pointers, vector arrays, and
1131 functions returning vectors. For example:
1133 __attribute__((vector_size(16))) short *foo;
1135 In this case, the mode is SI, but the type being modified is
1136 HI, so we need to look further. */
1138 while (POINTER_TYPE_P (type
)
1139 || TREE_CODE (type
) == FUNCTION_TYPE
1140 || TREE_CODE (type
) == METHOD_TYPE
1141 || TREE_CODE (type
) == ARRAY_TYPE
)
1142 type
= TREE_TYPE (type
);
1144 /* Get the mode of the type being modified. */
1145 orig_mode
= TYPE_MODE (type
);
1147 if (TREE_CODE (type
) == RECORD_TYPE
1148 || (GET_MODE_CLASS (orig_mode
) != MODE_FLOAT
1149 && GET_MODE_CLASS (orig_mode
) != MODE_INT
)
1150 || !host_integerp (TYPE_SIZE_UNIT (type
), 1))
1152 error ("invalid vector type for attribute %qs",
1153 IDENTIFIER_POINTER (name
));
1157 /* Calculate how many units fit in the vector. */
1158 nunits
= vecsize
/ tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
1159 if (nunits
& (nunits
- 1))
1161 error ("number of components of the vector not a power of two");
1165 new_type
= build_vector_type (type
, nunits
);
1167 /* Build back pointers if needed. */
1168 *node
= reconstruct_complex_type (*node
, new_type
);
1173 /* Handle the "nonnull" attribute. */
1175 handle_nonnull_attribute (tree
*node
, tree
ARG_UNUSED (name
),
1176 tree args
, int ARG_UNUSED (flags
),
1180 unsigned HOST_WIDE_INT attr_arg_num
;
1182 /* If no arguments are specified, all pointer arguments should be
1183 non-null. Verify a full prototype is given so that the arguments
1184 will have the correct types when we actually check them later. */
1187 if (!TYPE_ARG_TYPES (type
))
1189 error ("nonnull attribute without arguments on a non-prototype");
1190 *no_add_attrs
= true;
1195 /* Argument list specified. Verify that each argument number references
1196 a pointer argument. */
1197 for (attr_arg_num
= 1; args
; args
= TREE_CHAIN (args
))
1200 unsigned HOST_WIDE_INT arg_num
= 0, ck_num
;
1202 if (!get_nonnull_operand (TREE_VALUE (args
), &arg_num
))
1204 error ("nonnull argument has invalid operand number (argument %lu)",
1205 (unsigned long) attr_arg_num
);
1206 *no_add_attrs
= true;
1210 argument
= TYPE_ARG_TYPES (type
);
1213 for (ck_num
= 1; ; ck_num
++)
1215 if (!argument
|| ck_num
== arg_num
)
1217 argument
= TREE_CHAIN (argument
);
1221 || TREE_CODE (TREE_VALUE (argument
)) == VOID_TYPE
)
1223 error ("nonnull argument with out-of-range operand number (argument %lu, operand %lu)",
1224 (unsigned long) attr_arg_num
, (unsigned long) arg_num
);
1225 *no_add_attrs
= true;
1229 if (TREE_CODE (TREE_VALUE (argument
)) != POINTER_TYPE
)
1231 error ("nonnull argument references non-pointer operand (argument %lu, operand %lu)",
1232 (unsigned long) attr_arg_num
, (unsigned long) arg_num
);
1233 *no_add_attrs
= true;
1243 /* Check that the Nth argument of a function call (counting backwards
1244 from the end) is a (pointer)0. */
1247 check_function_sentinel (tree attrs
, tree params
)
1249 tree attr
= lookup_attribute ("sentinel", attrs
);
1254 warning ("missing sentinel in function call");
1260 if (TREE_VALUE (attr
))
1262 tree p
= TREE_VALUE (TREE_VALUE (attr
));
1264 pos
= TREE_INT_CST_LOW (p
);
1267 sentinel
= end
= params
;
1269 /* Advance `end' ahead of `sentinel' by `pos' positions. */
1270 while (pos
> 0 && TREE_CHAIN (end
))
1273 end
= TREE_CHAIN (end
);
1277 warning ("not enough arguments to fit a sentinel");
1281 /* Now advance both until we find the last parameter. */
1282 while (TREE_CHAIN (end
))
1284 end
= TREE_CHAIN (end
);
1285 sentinel
= TREE_CHAIN (sentinel
);
1288 /* Validate the sentinel. */
1289 if (!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel
)))
1290 || !integer_zerop (TREE_VALUE (sentinel
)))
1291 warning ("missing sentinel in function call");
1296 /* Helper for check_function_nonnull; given a list of operands which
1297 must be non-null in ARGS, determine if operand PARAM_NUM should be
1301 nonnull_check_p (tree args
, unsigned HOST_WIDE_INT param_num
)
1303 unsigned HOST_WIDE_INT arg_num
= 0;
1305 for (; args
; args
= TREE_CHAIN (args
))
1307 bool found
= get_nonnull_operand (TREE_VALUE (args
), &arg_num
);
1311 if (arg_num
== param_num
)
1317 /* Check that the function argument PARAM (which is operand number
1318 PARAM_NUM) is non-null. This is called by check_function_nonnull
1319 via check_function_arguments_recurse. */
1322 check_nonnull_arg (void * ARG_UNUSED (ctx
), tree param
,
1323 unsigned HOST_WIDE_INT param_num
)
1325 /* Just skip checking the argument if it's not a pointer. This can
1326 happen if the "nonnull" attribute was given without an operand
1327 list (which means to check every pointer argument). */
1329 if (TREE_CODE (TREE_TYPE (param
)) != POINTER_TYPE
)
1332 if (integer_zerop (param
))
1333 warning ("null argument where non-null required (argument %lu)",
1334 (unsigned long) param_num
);
1337 /* Helper for nonnull attribute handling; fetch the operand number
1338 from the attribute argument list. */
1341 get_nonnull_operand (tree arg_num_expr
, unsigned HOST_WIDE_INT
*valp
)
1343 /* Strip any conversions from the arg number and verify they
1345 while (TREE_CODE (arg_num_expr
) == NOP_EXPR
1346 || TREE_CODE (arg_num_expr
) == CONVERT_EXPR
1347 || TREE_CODE (arg_num_expr
) == NON_LVALUE_EXPR
)
1348 arg_num_expr
= TREE_OPERAND (arg_num_expr
, 0);
1350 if (TREE_CODE (arg_num_expr
) != INTEGER_CST
1351 || TREE_INT_CST_HIGH (arg_num_expr
) != 0)
1354 *valp
= TREE_INT_CST_LOW (arg_num_expr
);
1358 /* Handle a "nothrow" attribute; arguments as in
1359 struct attribute_spec.handler. */
1362 handle_nothrow_attribute (tree
*node
, tree name
, tree
ARG_UNUSED (args
),
1363 int ARG_UNUSED (flags
), bool *no_add_attrs
)
1365 if (TREE_CODE (*node
) == FUNCTION_DECL
)
1366 TREE_NOTHROW (*node
) = 1;
1367 /* ??? TODO: Support types. */
1370 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
1371 *no_add_attrs
= true;
1377 /* Handle a "warn_unused_result" attribute. No special handling. */
1380 handle_warn_unused_result_attribute (tree
*node
, tree name
,
1381 tree
ARG_UNUSED (args
),
1382 int ARG_UNUSED (flags
), bool *no_add_attrs
)
1384 /* Ignore the attribute for functions not returning any value. */
1385 if (VOID_TYPE_P (TREE_TYPE (*node
)))
1387 warning ("%qs attribute ignored", IDENTIFIER_POINTER (name
));
1388 *no_add_attrs
= true;
1394 /* Handle a "sentinel" attribute. */
1397 handle_sentinel_attribute (tree
*node
, tree name
, tree args
,
1398 int ARG_UNUSED (flags
), bool *no_add_attrs
)
1400 tree params
= TYPE_ARG_TYPES (*node
);
1404 warning ("%qs attribute requires prototypes with named arguments",
1405 IDENTIFIER_POINTER (name
));
1406 *no_add_attrs
= true;
1410 while (TREE_CHAIN (params
))
1411 params
= TREE_CHAIN (params
);
1413 if (VOID_TYPE_P (TREE_VALUE (params
)))
1415 warning ("%qs attribute only applies to variadic functions",
1416 IDENTIFIER_POINTER (name
));
1417 *no_add_attrs
= true;
1423 tree position
= TREE_VALUE (args
);
1425 STRIP_NOPS (position
);
1426 if (TREE_CODE (position
) != INTEGER_CST
)
1428 warning ("requested position is not an integer constant");
1429 *no_add_attrs
= true;
1433 if (tree_int_cst_lt (position
, integer_zero_node
))
1435 warning ("requested position is less than zero");
1436 *no_add_attrs
= true;
1445 /* Generic argument checking recursion routine. PARAM is the argument to
1446 be checked. PARAM_NUM is the number of the argument. CALLBACK is invoked
1447 once the argument is resolved. CTX is context for the callback. */
1449 check_function_arguments_recurse (void (*callback
)
1450 (void *, tree
, unsigned HOST_WIDE_INT
),
1451 void *ctx
, tree param
,
1452 unsigned HOST_WIDE_INT param_num
)
1454 if (TREE_CODE (param
) == NOP_EXPR
)
1456 /* Strip coercion. */
1457 check_function_arguments_recurse (callback
, ctx
,
1458 TREE_OPERAND (param
, 0), param_num
);
1462 if (TREE_CODE (param
) == CALL_EXPR
)
1464 tree type
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (param
, 0)));
1466 bool found_format_arg
= false;
1468 /* See if this is a call to a known internationalization function
1469 that modifies a format arg. Such a function may have multiple
1470 format_arg attributes (for example, ngettext). */
1472 for (attrs
= TYPE_ATTRIBUTES (type
);
1474 attrs
= TREE_CHAIN (attrs
))
1475 if (is_attribute_p ("format_arg", TREE_PURPOSE (attrs
)))
1478 tree format_num_expr
;
1482 /* Extract the argument number, which was previously checked
1484 format_num_expr
= TREE_VALUE (TREE_VALUE (attrs
));
1485 while (TREE_CODE (format_num_expr
) == NOP_EXPR
1486 || TREE_CODE (format_num_expr
) == CONVERT_EXPR
1487 || TREE_CODE (format_num_expr
) == NON_LVALUE_EXPR
)
1488 format_num_expr
= TREE_OPERAND (format_num_expr
, 0);
1490 gcc_assert (TREE_CODE (format_num_expr
) == INTEGER_CST
1491 && !TREE_INT_CST_HIGH (format_num_expr
));
1493 format_num
= TREE_INT_CST_LOW (format_num_expr
);
1495 for (inner_args
= TREE_OPERAND (param
, 1), i
= 1;
1497 inner_args
= TREE_CHAIN (inner_args
), i
++)
1498 if (i
== format_num
)
1500 check_function_arguments_recurse (callback
, ctx
,
1501 TREE_VALUE (inner_args
),
1503 found_format_arg
= true;
1508 /* If we found a format_arg attribute and did a recursive check,
1509 we are done with checking this argument. Otherwise, we continue
1510 and this will be considered a non-literal. */
1511 if (found_format_arg
)
1515 if (TREE_CODE (param
) == COND_EXPR
)
1517 /* Check both halves of the conditional expression. */
1518 check_function_arguments_recurse (callback
, ctx
,
1519 TREE_OPERAND (param
, 1), param_num
);
1520 check_function_arguments_recurse (callback
, ctx
,
1521 TREE_OPERAND (param
, 2), param_num
);
1525 (*callback
) (ctx
, param
, param_num
);