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 /*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,
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 (*)
49 unsigned HOST_WIDE_INT
),
51 unsigned HOST_WIDE_INT
);
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
)
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
)
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
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. */
160 handle_packed_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
161 int flags
, bool *no_add_attrs
)
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,
174 struct Foo const *ptr; // creates a variant w/o packed flag
175 } __ attribute__((packed)); // packs it now.
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. */
192 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
193 *no_add_attrs
= true;
199 /* Handle a "nocommon" attribute; arguments as in
200 struct attribute_spec.handler. */
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;
211 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
212 *no_add_attrs
= true;
218 /* Handle a "common" attribute; arguments as in
219 struct attribute_spec.handler. */
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;
229 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
230 *no_add_attrs
= true;
236 /* Handle a "noreturn" attribute; arguments as in
237 struct attribute_spec.handler. */
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
)
252 (build_type_variant (TREE_TYPE (type
),
253 TREE_READONLY (TREE_TYPE (type
)), 1));
256 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
257 *no_add_attrs
= true;
263 /* Handle a "noinline" attribute; arguments as in
264 struct attribute_spec.handler. */
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;
275 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
276 *no_add_attrs
= true;
282 /* Handle a "always_inline" attribute; arguments as in
283 struct attribute_spec.handler. */
286 handle_always_inline_attribute (tree
*node
, tree name
,
287 tree args ATTRIBUTE_UNUSED
,
288 int flags ATTRIBUTE_UNUSED
,
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. */
298 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
299 *no_add_attrs
= true;
305 /* Handle a "used" attribute; arguments as in
306 struct attribute_spec.handler. */
309 handle_used_attribute (tree
*pnode
, tree name
, tree args ATTRIBUTE_UNUSED
,
310 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
314 if (TREE_CODE (node
) == FUNCTION_DECL
315 || (TREE_CODE (node
) == VAR_DECL
&& TREE_STATIC (node
)))
317 TREE_USED (node
) = 1;
321 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
322 *no_add_attrs
= true;
328 /* Handle a "unused" attribute; arguments as in
329 struct attribute_spec.handler. */
332 handle_unused_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
333 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
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;
347 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
348 *no_add_attrs
= true;
353 if (!(flags
& (int) ATTR_FLAG_TYPE_IN_PLACE
))
354 *node
= build_type_copy (*node
);
355 TREE_USED (*node
) = 1;
361 /* Handle a "const" attribute; arguments as in
362 struct attribute_spec.handler. */
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
)
377 (build_type_variant (TREE_TYPE (type
), 1,
378 TREE_THIS_VOLATILE (TREE_TYPE (type
))));
381 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
382 *no_add_attrs
= true;
388 /* Handle a "transparent_union" attribute; arguments as in
389 struct attribute_spec.handler. */
392 handle_transparent_union_attribute (tree
*node
, tree name
,
393 tree args ATTRIBUTE_UNUSED
, int flags
,
396 tree decl
= NULL_TREE
;
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;
410 && TREE_CODE (*type
) == UNION_TYPE
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;
425 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
426 *no_add_attrs
= true;
432 /* Handle a "constructor" attribute; arguments as in
433 struct attribute_spec.handler. */
436 handle_constructor_attribute (tree
*node
, tree name
,
437 tree args ATTRIBUTE_UNUSED
,
438 int flags ATTRIBUTE_UNUSED
,
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;
453 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
454 *no_add_attrs
= true;
460 /* Handle a "destructor" attribute; arguments as in
461 struct attribute_spec.handler. */
464 handle_destructor_attribute (tree
*node
, tree name
,
465 tree args ATTRIBUTE_UNUSED
,
466 int flags ATTRIBUTE_UNUSED
,
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;
481 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
482 *no_add_attrs
= true;
488 /* Handle a "mode" attribute; arguments as in
489 struct attribute_spec.handler. */
492 handle_mode_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
493 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
497 *no_add_attrs
= true;
499 if (TREE_CODE (TREE_VALUE (args
)) != IDENTIFIER_NODE
)
500 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
504 const char *p
= IDENTIFIER_POINTER (TREE_VALUE (args
));
505 int len
= strlen (p
);
506 enum machine_mode mode
= VOIDmode
;
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';
520 /* Change this type to have a type with the specified mode.
521 First check for the special modes. */
522 if (! strcmp (p
, "byte"))
524 else if (!strcmp (p
, "word"))
526 else if (! strcmp (p
, "pointer"))
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
);
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
));
552 if (TREE_CODE (type
) == POINTER_TYPE
)
554 ptr_type
= build_pointer_type_for_mode (TREE_TYPE (type
),
558 else if (TREE_CODE (type
) == REFERENCE_TYPE
)
560 ptr_type
= build_reference_type_for_mode (TREE_TYPE (type
),
566 /* No need to layout the type here. The caller should do this. */
573 /* Handle a "section" attribute; arguments as in
574 struct attribute_spec.handler. */
577 handle_section_attribute (tree
*node
, tree name ATTRIBUTE_UNUSED
, tree args
,
578 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
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",
605 *no_add_attrs
= true;
608 DECL_SECTION_NAME (decl
) = TREE_VALUE (args
);
612 error ("%Jsection attribute not allowed for '%D'", *node
, *node
);
613 *no_add_attrs
= true;
618 error ("%Jsection attributes are not supported for this target", *node
);
619 *no_add_attrs
= true;
625 /* Handle a "aligned" attribute; arguments as in
626 struct attribute_spec.handler. */
629 handle_aligned_attribute (tree
*node
, tree name ATTRIBUTE_UNUSED
, tree args
,
630 int flags
, bool *no_add_attrs
)
632 tree decl
= NULL_TREE
;
635 tree align_expr
= (args
? TREE_VALUE (args
)
636 : size_int (BIGGEST_ALIGNMENT
/ BITS_PER_UNIT
));
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;
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;
697 DECL_ALIGN (decl
) = (1 << i
) * BITS_PER_UNIT
;
698 DECL_USER_ALIGN (decl
) = 1;
704 /* Handle a "weak" attribute; arguments as in
705 struct attribute_spec.handler. */
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
);
718 /* Handle an "alias" attribute; arguments as in
719 struct attribute_spec.handler. */
722 handle_alias_attribute (tree
*node
, tree name
, tree args
,
723 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
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)
737 id
= TREE_VALUE (args
);
738 if (TREE_CODE (id
) != STRING_CST
)
740 error ("alias arg not a string");
741 *no_add_attrs
= true;
744 id
= get_identifier (TREE_STRING_POINTER (id
));
745 /* This counts as a use of the object pointed to. */
748 if (TREE_CODE (decl
) == FUNCTION_DECL
)
749 DECL_INITIAL (decl
) = error_mark_node
;
751 DECL_EXTERNAL (decl
) = 0;
755 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
756 *no_add_attrs
= true;
762 /* Handle an "visibility" attribute; arguments as in
763 struct attribute_spec.handler. */
766 handle_visibility_attribute (tree
*node
, tree name
, tree args
,
767 int flags ATTRIBUTE_UNUSED
,
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
));
781 if (TREE_CODE (id
) != STRING_CST
)
783 error ("visibility arg not a string");
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
;
796 error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
801 /* Handle an "tls_model" attribute; arguments as in
802 struct attribute_spec.handler. */
805 handle_tls_model_attribute (tree
*node
, tree name
, tree args
,
806 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
810 if (! DECL_THREAD_LOCAL (decl
))
812 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
813 *no_add_attrs
= true;
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;
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;
840 /* Handle a "no_instrument_function" attribute; arguments as in
841 struct attribute_spec.handler. */
844 handle_no_instrument_function_attribute (tree
*node
, tree name
,
845 tree args ATTRIBUTE_UNUSED
,
846 int flags ATTRIBUTE_UNUSED
,
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;
862 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl
) = 1;
867 /* Handle a "malloc" attribute; arguments as in
868 struct attribute_spec.handler. */
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. */
879 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
880 *no_add_attrs
= true;
886 /* Handle a "no_limit_stack" attribute; arguments as in
887 struct attribute_spec.handler. */
890 handle_no_limit_stack_attribute (tree
*node
, tree name
,
891 tree args ATTRIBUTE_UNUSED
,
892 int flags ATTRIBUTE_UNUSED
,
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;
908 DECL_NO_LIMIT_STACK (decl
) = 1;
913 /* Handle a "pure" attribute; arguments as in
914 struct attribute_spec.handler. */
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. */
925 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
926 *no_add_attrs
= true;
932 /* Handle a "deprecated" attribute; arguments as in
933 struct attribute_spec.handler. */
936 handle_deprecated_attribute (tree
*node
, tree name
,
937 tree args ATTRIBUTE_UNUSED
, int flags
,
940 tree type
= NULL_TREE
;
942 const char *what
= NULL
;
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;
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;
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
)));
980 warning ("`%s' attribute ignored for `%s'",
981 IDENTIFIER_POINTER (name
), what
);
983 warning ("`%s' attribute ignored",
984 IDENTIFIER_POINTER (name
));
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. */
1001 handle_vector_size_attribute (tree
*node
, tree name
, tree args
,
1002 int flags ATTRIBUTE_UNUSED
,
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
));
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
));
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
1055 : MODE_VECTOR_FLOAT
);
1057 mode
= GET_MODE_WIDER_MODE (mode
))
1058 if (vecsize
== GET_MODE_SIZE (mode
)
1059 && nunits
== (unsigned HOST_WIDE_INT
) GET_MODE_NUNITS (mode
))
1065 if (new_mode
== VOIDmode
)
1067 error ("no vector mode with the size and type specified could be found");
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
)
1083 if (TYPE_MODE (other_type
) == mode
&& type
== array_type
)
1085 new_type
= other_type
;
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
));
1099 error ("no vector mode with the size and type specified could be found");
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
));
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
;
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
);
1139 /* HACK. GROSS. This is absolutely disgusting. I wish there was a
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. */
1150 vector_size_helper (tree type
, tree bottom
)
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
),
1174 TYPE_ARG_TYPES (type
));
1179 TREE_READONLY (outer
) = TREE_READONLY (type
);
1180 TREE_THIS_VOLATILE (outer
) = TREE_THIS_VOLATILE (type
);
1185 /* Handle the "nonnull" attribute. */
1187 handle_nonnull_attribute (tree
*node
, tree name ATTRIBUTE_UNUSED
,
1188 tree args
, int flags ATTRIBUTE_UNUSED
,
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. */
1199 if (! TYPE_ARG_TYPES (type
))
1201 error ("nonnull attribute without arguments on a non-prototype");
1202 *no_add_attrs
= true;
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
))
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;
1222 argument
= TYPE_ARG_TYPES (type
);
1225 for (ck_num
= 1; ; ck_num
++)
1227 if (! argument
|| ck_num
== arg_num
)
1229 argument
= TREE_CHAIN (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;
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;
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. */
1260 check_function_nonnull (tree attrs
, tree params
)
1262 tree a
, args
, param
;
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
))
1280 if (! args
|| nonnull_check_p (args
, param_num
))
1281 check_function_arguments_recurse (check_nonnull_arg
, NULL
,
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
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
))
1304 if (arg_num
== param_num
)
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. */
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
)
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. */
1334 get_nonnull_operand (tree arg_num_expr
, unsigned HOST_WIDE_INT
*valp
)
1336 /* Strip any conversions from the arg number and verify they
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)
1347 *valp
= TREE_INT_CST_LOW (arg_num_expr
);
1351 /* Handle a "nothrow" attribute; arguments as in
1352 struct attribute_spec.handler. */
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. */
1363 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name
));
1364 *no_add_attrs
= true;
1372 /* Handle a "cleanup" attribute; arguments as in
1373 struct attribute_spec.handler. */
1376 handle_cleanup_attribute (tree
*node
, tree name
, tree args
,
1377 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
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;
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;
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;
1411 /* That the function has proper type is checked with the
1412 eventual call to build_function_call. */
1418 /* Handle a "warn_unused_result" attribute. No special handling. */
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;
1437 /* Check for valid arguments being passed to a function. */
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. */
1445 check_function_nonnull (attrs
, params
);
1447 /* Check for errors in format strings. */
1450 check_function_format (NULL
, attrs
, params
);
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. */
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
);
1471 if (TREE_CODE (param
) == CALL_EXPR
)
1473 tree type
= TREE_TYPE (TREE_TYPE (TREE_OPERAND (param
, 0)));
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
);
1483 attrs
= TREE_CHAIN (attrs
))
1484 if (is_attribute_p ("format_arg", TREE_PURPOSE (attrs
)))
1487 tree format_num_expr
;
1491 /* Extract the argument number, which was previously checked
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)
1503 format_num
= TREE_INT_CST_LOW (format_num_expr
);
1505 for (inner_args
= TREE_OPERAND (param
, 1), i
= 1;
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
),
1513 found_format_arg
= true;
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
)
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
);
1535 (*callback
) (ctx
, param
, param_num
);