d-attribs.cc revision 1.1 1 1.1 mrg /* d-attribs.c -- D attributes handling.
2 1.1 mrg Copyright (C) 2015-2019 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg GCC is free software; you can redistribute it and/or modify
5 1.1 mrg it under the terms of the GNU General Public License as published by
6 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
7 1.1 mrg any later version.
8 1.1 mrg
9 1.1 mrg GCC is distributed in the hope that it will be useful,
10 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
11 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 1.1 mrg GNU General Public License for more details.
13 1.1 mrg
14 1.1 mrg You should have received a copy of the GNU General Public License
15 1.1 mrg along with GCC; see the file COPYING3. If not see
16 1.1 mrg <http://www.gnu.org/licenses/>. */
17 1.1 mrg
18 1.1 mrg /* Implementation of attribute handlers for user defined attributes and
19 1.1 mrg internal built-in functions. */
20 1.1 mrg
21 1.1 mrg #include "config.h"
22 1.1 mrg #include "system.h"
23 1.1 mrg #include "coretypes.h"
24 1.1 mrg
25 1.1 mrg #include "dmd/declaration.h"
26 1.1 mrg #include "dmd/mtype.h"
27 1.1 mrg
28 1.1 mrg #include "tree.h"
29 1.1 mrg #include "diagnostic.h"
30 1.1 mrg #include "tm.h"
31 1.1 mrg #include "cgraph.h"
32 1.1 mrg #include "toplev.h"
33 1.1 mrg #include "target.h"
34 1.1 mrg #include "common/common-target.h"
35 1.1 mrg #include "stringpool.h"
36 1.1 mrg #include "attribs.h"
37 1.1 mrg #include "varasm.h"
38 1.1 mrg
39 1.1 mrg #include "d-tree.h"
40 1.1 mrg
41 1.1 mrg
42 1.1 mrg /* Internal attribute handlers for built-in functions. */
43 1.1 mrg static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
44 1.1 mrg static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
45 1.1 mrg static tree handle_const_attribute (tree *, tree, tree, int, bool *);
46 1.1 mrg static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
47 1.1 mrg static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
48 1.1 mrg static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
49 1.1 mrg static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
50 1.1 mrg static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
51 1.1 mrg static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
52 1.1 mrg static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
53 1.1 mrg static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
54 1.1 mrg static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
55 1.1 mrg
56 1.1 mrg /* D attribute handlers for user defined attributes. */
57 1.1 mrg static tree d_handle_noinline_attribute (tree *, tree, tree, int, bool *);
58 1.1 mrg static tree d_handle_forceinline_attribute (tree *, tree, tree, int, bool *);
59 1.1 mrg static tree d_handle_flatten_attribute (tree *, tree, tree, int, bool *);
60 1.1 mrg static tree d_handle_target_attribute (tree *, tree, tree, int, bool *);
61 1.1 mrg static tree d_handle_noclone_attribute (tree *, tree, tree, int, bool *);
62 1.1 mrg static tree d_handle_section_attribute (tree *, tree, tree, int, bool *);
63 1.1 mrg static tree d_handle_alias_attribute (tree *, tree, tree, int, bool *);
64 1.1 mrg static tree d_handle_weak_attribute (tree *, tree, tree, int, bool *) ;
65 1.1 mrg
66 1.1 mrg /* Helper to define attribute exclusions. */
67 1.1 mrg #define ATTR_EXCL(name, function, type, variable) \
68 1.1 mrg { name, function, type, variable }
69 1.1 mrg
70 1.1 mrg /* Define attributes that are mutually exclusive with one another. */
71 1.1 mrg static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
72 1.1 mrg {
73 1.1 mrg ATTR_EXCL ("const", true, true, true),
74 1.1 mrg ATTR_EXCL ("malloc", true, true, true),
75 1.1 mrg ATTR_EXCL ("pure", true, true, true),
76 1.1 mrg ATTR_EXCL ("returns_twice", true, true, true),
77 1.1 mrg ATTR_EXCL (NULL, false, false, false),
78 1.1 mrg };
79 1.1 mrg
80 1.1 mrg static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
81 1.1 mrg {
82 1.1 mrg ATTR_EXCL ("noreturn", true, true, true),
83 1.1 mrg ATTR_EXCL (NULL, false, false, false),
84 1.1 mrg };
85 1.1 mrg
86 1.1 mrg static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
87 1.1 mrg {
88 1.1 mrg ATTR_EXCL ("const", true, true, true),
89 1.1 mrg ATTR_EXCL ("noreturn", true, true, true),
90 1.1 mrg ATTR_EXCL ("pure", true, true, true),
91 1.1 mrg ATTR_EXCL (NULL, false, false, false)
92 1.1 mrg };
93 1.1 mrg
94 1.1 mrg static const struct attribute_spec::exclusions attr_inline_exclusions[] =
95 1.1 mrg {
96 1.1 mrg ATTR_EXCL ("noinline", true, true, true),
97 1.1 mrg ATTR_EXCL (NULL, false, false, false),
98 1.1 mrg };
99 1.1 mrg
100 1.1 mrg static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
101 1.1 mrg {
102 1.1 mrg ATTR_EXCL ("forceinline", true, true, true),
103 1.1 mrg ATTR_EXCL (NULL, false, false, false),
104 1.1 mrg };
105 1.1 mrg
106 1.1 mrg /* Helper to define an attribute. */
107 1.1 mrg #define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \
108 1.1 mrg affects_type_identity, handler, exclude) \
109 1.1 mrg { name, min_len, max_len, decl_req, type_req, fn_type_req, \
110 1.1 mrg affects_type_identity, handler, exclude }
111 1.1 mrg
112 1.1 mrg /* Table of machine-independent attributes.
113 1.1 mrg For internal use (marking of built-ins) only. */
114 1.1 mrg const attribute_spec d_langhook_common_attribute_table[] =
115 1.1 mrg {
116 1.1 mrg ATTR_SPEC ("noreturn", 0, 0, true, false, false, false,
117 1.1 mrg handle_noreturn_attribute, attr_noreturn_exclusions),
118 1.1 mrg ATTR_SPEC ("leaf", 0, 0, true, false, false, false,
119 1.1 mrg handle_leaf_attribute, NULL),
120 1.1 mrg ATTR_SPEC ("const", 0, 0, true, false, false, false,
121 1.1 mrg handle_const_attribute, attr_const_pure_exclusions),
122 1.1 mrg ATTR_SPEC ("malloc", 0, 0, true, false, false, false,
123 1.1 mrg handle_malloc_attribute, NULL),
124 1.1 mrg ATTR_SPEC ("returns_twice", 0, 0, true, false, false, false,
125 1.1 mrg handle_returns_twice_attribute, attr_returns_twice_exclusions),
126 1.1 mrg ATTR_SPEC ("pure", 0, 0, true, false, false, false,
127 1.1 mrg handle_pure_attribute, attr_const_pure_exclusions),
128 1.1 mrg ATTR_SPEC ("nonnull", 0, -1, false, true, true, false,
129 1.1 mrg handle_nonnull_attribute, NULL),
130 1.1 mrg ATTR_SPEC ("nothrow", 0, 0, true, false, false, false,
131 1.1 mrg handle_nothrow_attribute, NULL),
132 1.1 mrg ATTR_SPEC ("transaction_pure", 0, 0, false, true, true, false,
133 1.1 mrg handle_transaction_pure_attribute, NULL),
134 1.1 mrg ATTR_SPEC ("no vops", 0, 0, true, false, false, false,
135 1.1 mrg handle_novops_attribute, NULL),
136 1.1 mrg ATTR_SPEC ("type generic", 0, 0, false, true, true, false,
137 1.1 mrg handle_type_generic_attribute, NULL),
138 1.1 mrg ATTR_SPEC ("fn spec", 1, 1, false, true, true, false,
139 1.1 mrg handle_fnspec_attribute, NULL),
140 1.1 mrg ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
141 1.1 mrg };
142 1.1 mrg
143 1.1 mrg /* Table of D language attributes exposed by `gcc.attribute' UDAs. */
144 1.1 mrg const attribute_spec d_langhook_attribute_table[] =
145 1.1 mrg {
146 1.1 mrg ATTR_SPEC ("noinline", 0, 0, true, false, false, false,
147 1.1 mrg d_handle_noinline_attribute, attr_noinline_exclusions),
148 1.1 mrg ATTR_SPEC ("forceinline", 0, 0, true, false, false, false,
149 1.1 mrg d_handle_forceinline_attribute, attr_inline_exclusions),
150 1.1 mrg ATTR_SPEC ("flatten", 0, 0, true, false, false, false,
151 1.1 mrg d_handle_flatten_attribute, NULL),
152 1.1 mrg ATTR_SPEC ("target", 1, -1, true, false, false, false,
153 1.1 mrg d_handle_target_attribute, NULL),
154 1.1 mrg ATTR_SPEC ("noclone", 0, 0, true, false, false, false,
155 1.1 mrg d_handle_noclone_attribute, NULL),
156 1.1 mrg ATTR_SPEC ("section", 1, 1, true, false, false, false,
157 1.1 mrg d_handle_section_attribute, NULL),
158 1.1 mrg ATTR_SPEC ("alias", 1, 1, true, false, false, false,
159 1.1 mrg d_handle_alias_attribute, NULL),
160 1.1 mrg ATTR_SPEC ("weak", 0, 0, true, false, false, false,
161 1.1 mrg d_handle_weak_attribute, NULL),
162 1.1 mrg ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL),
163 1.1 mrg };
164 1.1 mrg
165 1.1 mrg
166 1.1 mrg /* Insert the type attribute ATTRNAME with value VALUE into TYPE.
167 1.1 mrg Returns a new variant of the original type declaration. */
168 1.1 mrg
169 1.1 mrg tree
170 1.1 mrg insert_type_attribute (tree type, const char *attrname, tree value)
171 1.1 mrg {
172 1.1 mrg tree ident = get_identifier (attrname);
173 1.1 mrg
174 1.1 mrg if (value)
175 1.1 mrg value = tree_cons (NULL_TREE, value, NULL_TREE);
176 1.1 mrg
177 1.1 mrg tree attribs = merge_attributes (TYPE_ATTRIBUTES (type),
178 1.1 mrg tree_cons (ident, value, NULL_TREE));
179 1.1 mrg
180 1.1 mrg return build_type_attribute_variant (type, attribs);
181 1.1 mrg }
182 1.1 mrg
183 1.1 mrg /* Insert the decl attribute ATTRNAME with value VALUE into DECL. */
184 1.1 mrg
185 1.1 mrg tree
186 1.1 mrg insert_decl_attribute (tree decl, const char *attrname, tree value)
187 1.1 mrg {
188 1.1 mrg tree ident = get_identifier (attrname);
189 1.1 mrg
190 1.1 mrg if (value)
191 1.1 mrg value = tree_cons (NULL_TREE, value, NULL_TREE);
192 1.1 mrg
193 1.1 mrg tree attribs = merge_attributes (DECL_ATTRIBUTES (decl),
194 1.1 mrg tree_cons (ident, value, NULL_TREE));
195 1.1 mrg
196 1.1 mrg return build_decl_attribute_variant (decl, attribs);
197 1.1 mrg }
198 1.1 mrg
199 1.1 mrg /* Returns TRUE if NAME is an attribute recognized as being handled by
200 1.1 mrg the `gcc.attribute' module. */
201 1.1 mrg
202 1.1 mrg static bool
203 1.1 mrg uda_attribute_p (const char *name)
204 1.1 mrg {
205 1.1 mrg tree ident = get_identifier (name);
206 1.1 mrg
207 1.1 mrg /* Search both our language, and target attribute tables.
208 1.1 mrg Common and format attributes are kept internal. */
209 1.1 mrg for (const attribute_spec *p = d_langhook_attribute_table; p->name; p++)
210 1.1 mrg {
211 1.1 mrg if (get_identifier (p->name) == ident)
212 1.1 mrg return true;
213 1.1 mrg }
214 1.1 mrg
215 1.1 mrg for (const attribute_spec *p = targetm.attribute_table; p->name; p++)
216 1.1 mrg {
217 1.1 mrg if (get_identifier (p->name) == ident)
218 1.1 mrg return true;
219 1.1 mrg }
220 1.1 mrg
221 1.1 mrg return false;
222 1.1 mrg }
223 1.1 mrg
224 1.1 mrg /* [attribute/uda]
225 1.1 mrg
226 1.1 mrg User Defined Attributes (UDA) are compile time expressions that can be
227 1.1 mrg attached to a declaration. These attributes can then be queried, extracted,
228 1.1 mrg and manipulated at compile-time. There is no run-time component to them.
229 1.1 mrg
230 1.1 mrg Expand and merge all UDAs found in the EATTRS list that are of type
231 1.1 mrg `gcc.attribute.Attribute'. This symbol is internally recognized by the
232 1.1 mrg compiler and maps them to their equivalent GCC attribute. */
233 1.1 mrg
234 1.1 mrg tree
235 1.1 mrg build_attributes (Expressions *eattrs)
236 1.1 mrg {
237 1.1 mrg if (!eattrs)
238 1.1 mrg return NULL_TREE;
239 1.1 mrg
240 1.1 mrg expandTuples (eattrs);
241 1.1 mrg
242 1.1 mrg tree attribs = NULL_TREE;
243 1.1 mrg
244 1.1 mrg for (size_t i = 0; i < eattrs->dim; i++)
245 1.1 mrg {
246 1.1 mrg Expression *attr = (*eattrs)[i];
247 1.1 mrg Dsymbol *sym = attr->type->toDsymbol (0);
248 1.1 mrg
249 1.1 mrg if (!sym)
250 1.1 mrg continue;
251 1.1 mrg
252 1.1 mrg /* Attribute symbol must come from the `gcc.attribute' module. */
253 1.1 mrg Dsymbol *mod = (Dsymbol*) sym->getModule ();
254 1.1 mrg if (!(strcmp (mod->toChars (), "attribute") == 0
255 1.1 mrg && mod->parent != NULL
256 1.1 mrg && strcmp (mod->parent->toChars (), "gcc") == 0
257 1.1 mrg && !mod->parent->parent))
258 1.1 mrg continue;
259 1.1 mrg
260 1.1 mrg /* Get the result of the attribute if it hasn't already been folded. */
261 1.1 mrg if (attr->op == TOKcall)
262 1.1 mrg attr = attr->ctfeInterpret ();
263 1.1 mrg
264 1.1 mrg /* Should now have a struct `Attribute("attrib", "value", ...)'
265 1.1 mrg initializer list. */
266 1.1 mrg gcc_assert (attr->op == TOKstructliteral);
267 1.1 mrg Expressions *elems = ((StructLiteralExp*) attr)->elements;
268 1.1 mrg Expression *e0 = (*elems)[0];
269 1.1 mrg
270 1.1 mrg if (e0->op != TOKstring)
271 1.1 mrg {
272 1.1 mrg error ("expected string attribute, not %qs", e0->toChars ());
273 1.1 mrg return error_mark_node;
274 1.1 mrg }
275 1.1 mrg
276 1.1 mrg StringExp *se = (StringExp*) e0;
277 1.1 mrg gcc_assert (se->sz == 1);
278 1.1 mrg
279 1.1 mrg /* Empty string attribute, just ignore it. */
280 1.1 mrg if (se->len == 0)
281 1.1 mrg continue;
282 1.1 mrg
283 1.1 mrg /* Check if the attribute is recognized and handled.
284 1.1 mrg Done here to report the diagnostic at the right location. */
285 1.1 mrg const char *name = (const char *)(se->len ? se->string : "");
286 1.1 mrg if (!uda_attribute_p (name))
287 1.1 mrg {
288 1.1 mrg warning_at (make_location_t (e0->loc), OPT_Wattributes,
289 1.1 mrg "unknown attribute %qs", name);
290 1.1 mrg return error_mark_node;
291 1.1 mrg }
292 1.1 mrg
293 1.1 mrg /* Chain all attribute arguments together. */
294 1.1 mrg tree args = NULL_TREE;
295 1.1 mrg
296 1.1 mrg for (size_t j = 1; j < elems->dim; j++)
297 1.1 mrg {
298 1.1 mrg Expression *e = (*elems)[j];
299 1.1 mrg tree t;
300 1.1 mrg if (e->op == TOKstring && ((StringExp *) e)->sz == 1)
301 1.1 mrg {
302 1.1 mrg StringExp *s = (StringExp *) e;
303 1.1 mrg const char *string = (const char *)(s->len ? s->string : "");
304 1.1 mrg t = build_string (s->len, string);
305 1.1 mrg }
306 1.1 mrg else
307 1.1 mrg t = build_expr (e);
308 1.1 mrg
309 1.1 mrg args = chainon (args, build_tree_list (0, t));
310 1.1 mrg }
311 1.1 mrg
312 1.1 mrg tree list = build_tree_list (get_identifier (name), args);
313 1.1 mrg attribs = chainon (attribs, list);
314 1.1 mrg }
315 1.1 mrg
316 1.1 mrg return attribs;
317 1.1 mrg }
318 1.1 mrg
319 1.1 mrg /* Built-in attribute handlers. */
320 1.1 mrg
321 1.1 mrg /* Handle a "noreturn" attribute; arguments as in
322 1.1 mrg struct attribute_spec.handler. */
323 1.1 mrg
324 1.1 mrg static tree
325 1.1 mrg handle_noreturn_attribute (tree *node, tree ARG_UNUSED (name),
326 1.1 mrg tree ARG_UNUSED (args), int ARG_UNUSED (flags),
327 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
328 1.1 mrg {
329 1.1 mrg tree type = TREE_TYPE (*node);
330 1.1 mrg
331 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL)
332 1.1 mrg TREE_THIS_VOLATILE (*node) = 1;
333 1.1 mrg else if (TREE_CODE (type) == POINTER_TYPE
334 1.1 mrg && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
335 1.1 mrg TREE_TYPE (*node)
336 1.1 mrg = build_pointer_type
337 1.1 mrg (build_type_variant (TREE_TYPE (type),
338 1.1 mrg TYPE_READONLY (TREE_TYPE (type)), 1));
339 1.1 mrg else
340 1.1 mrg gcc_unreachable ();
341 1.1 mrg
342 1.1 mrg return NULL_TREE;
343 1.1 mrg }
344 1.1 mrg
345 1.1 mrg /* Handle a "leaf" attribute; arguments as in
346 1.1 mrg struct attribute_spec.handler. */
347 1.1 mrg
348 1.1 mrg static tree
349 1.1 mrg handle_leaf_attribute (tree *node, tree name,
350 1.1 mrg tree ARG_UNUSED (args),
351 1.1 mrg int ARG_UNUSED (flags), bool *no_add_attrs)
352 1.1 mrg {
353 1.1 mrg if (TREE_CODE (*node) != FUNCTION_DECL)
354 1.1 mrg {
355 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
356 1.1 mrg *no_add_attrs = true;
357 1.1 mrg }
358 1.1 mrg if (!TREE_PUBLIC (*node))
359 1.1 mrg {
360 1.1 mrg warning (OPT_Wattributes, "%qE attribute has no effect", name);
361 1.1 mrg *no_add_attrs = true;
362 1.1 mrg }
363 1.1 mrg
364 1.1 mrg return NULL_TREE;
365 1.1 mrg }
366 1.1 mrg
367 1.1 mrg /* Handle a "const" attribute; arguments as in
368 1.1 mrg struct attribute_spec.handler. */
369 1.1 mrg
370 1.1 mrg static tree
371 1.1 mrg handle_const_attribute (tree *node, tree ARG_UNUSED (name),
372 1.1 mrg tree ARG_UNUSED (args), int ARG_UNUSED (flags),
373 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
374 1.1 mrg {
375 1.1 mrg tree type = TREE_TYPE (*node);
376 1.1 mrg
377 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL)
378 1.1 mrg TREE_READONLY (*node) = 1;
379 1.1 mrg else if (TREE_CODE (type) == POINTER_TYPE
380 1.1 mrg && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
381 1.1 mrg TREE_TYPE (*node)
382 1.1 mrg = build_pointer_type
383 1.1 mrg (build_type_variant (TREE_TYPE (type), 1,
384 1.1 mrg TREE_THIS_VOLATILE (TREE_TYPE (type))));
385 1.1 mrg else
386 1.1 mrg gcc_unreachable ();
387 1.1 mrg
388 1.1 mrg return NULL_TREE;
389 1.1 mrg }
390 1.1 mrg
391 1.1 mrg /* Handle a "malloc" attribute; arguments as in
392 1.1 mrg struct attribute_spec.handler. */
393 1.1 mrg
394 1.1 mrg tree
395 1.1 mrg handle_malloc_attribute (tree *node, tree ARG_UNUSED (name),
396 1.1 mrg tree ARG_UNUSED (args), int ARG_UNUSED (flags),
397 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
398 1.1 mrg {
399 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL
400 1.1 mrg && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))));
401 1.1 mrg DECL_IS_MALLOC (*node) = 1;
402 1.1 mrg return NULL_TREE;
403 1.1 mrg }
404 1.1 mrg
405 1.1 mrg /* Handle a "pure" attribute; arguments as in
406 1.1 mrg struct attribute_spec.handler. */
407 1.1 mrg
408 1.1 mrg static tree
409 1.1 mrg handle_pure_attribute (tree *node, tree ARG_UNUSED (name),
410 1.1 mrg tree ARG_UNUSED (args), int ARG_UNUSED (flags),
411 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
412 1.1 mrg {
413 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
414 1.1 mrg DECL_PURE_P (*node) = 1;
415 1.1 mrg return NULL_TREE;
416 1.1 mrg }
417 1.1 mrg
418 1.1 mrg /* Handle a "no vops" attribute; arguments as in
419 1.1 mrg struct attribute_spec.handler. */
420 1.1 mrg
421 1.1 mrg static tree
422 1.1 mrg handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
423 1.1 mrg tree ARG_UNUSED (args), int ARG_UNUSED (flags),
424 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
425 1.1 mrg {
426 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
427 1.1 mrg DECL_IS_NOVOPS (*node) = 1;
428 1.1 mrg return NULL_TREE;
429 1.1 mrg }
430 1.1 mrg
431 1.1 mrg /* Helper for nonnull attribute handling; fetch the operand number
432 1.1 mrg from the attribute argument list. */
433 1.1 mrg
434 1.1 mrg static bool
435 1.1 mrg get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
436 1.1 mrg {
437 1.1 mrg /* Verify the arg number is a constant. */
438 1.1 mrg if (!tree_fits_uhwi_p (arg_num_expr))
439 1.1 mrg return false;
440 1.1 mrg
441 1.1 mrg *valp = TREE_INT_CST_LOW (arg_num_expr);
442 1.1 mrg return true;
443 1.1 mrg }
444 1.1 mrg
445 1.1 mrg /* Handle the "nonnull" attribute. */
446 1.1 mrg
447 1.1 mrg static tree
448 1.1 mrg handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
449 1.1 mrg tree args, int ARG_UNUSED (flags),
450 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
451 1.1 mrg {
452 1.1 mrg tree type = *node;
453 1.1 mrg
454 1.1 mrg /* If no arguments are specified, all pointer arguments should be
455 1.1 mrg non-null. Verify a full prototype is given so that the arguments
456 1.1 mrg will have the correct types when we actually check them later.
457 1.1 mrg Avoid diagnosing type-generic built-ins since those have no
458 1.1 mrg prototype. */
459 1.1 mrg if (!args)
460 1.1 mrg {
461 1.1 mrg gcc_assert (prototype_p (type)
462 1.1 mrg || !TYPE_ATTRIBUTES (type)
463 1.1 mrg || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
464 1.1 mrg
465 1.1 mrg return NULL_TREE;
466 1.1 mrg }
467 1.1 mrg
468 1.1 mrg /* Argument list specified. Verify that each argument number references
469 1.1 mrg a pointer argument. */
470 1.1 mrg for (; args; args = TREE_CHAIN (args))
471 1.1 mrg {
472 1.1 mrg tree argument;
473 1.1 mrg unsigned HOST_WIDE_INT arg_num = 0, ck_num;
474 1.1 mrg
475 1.1 mrg if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
476 1.1 mrg gcc_unreachable ();
477 1.1 mrg
478 1.1 mrg argument = TYPE_ARG_TYPES (type);
479 1.1 mrg if (argument)
480 1.1 mrg {
481 1.1 mrg for (ck_num = 1; ; ck_num++)
482 1.1 mrg {
483 1.1 mrg if (!argument || ck_num == arg_num)
484 1.1 mrg break;
485 1.1 mrg argument = TREE_CHAIN (argument);
486 1.1 mrg }
487 1.1 mrg
488 1.1 mrg gcc_assert (argument
489 1.1 mrg && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
490 1.1 mrg }
491 1.1 mrg }
492 1.1 mrg
493 1.1 mrg return NULL_TREE;
494 1.1 mrg }
495 1.1 mrg
496 1.1 mrg /* Handle a "nothrow" attribute; arguments as in
497 1.1 mrg struct attribute_spec.handler. */
498 1.1 mrg
499 1.1 mrg static tree
500 1.1 mrg handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),
501 1.1 mrg tree ARG_UNUSED (args), int ARG_UNUSED (flags),
502 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
503 1.1 mrg {
504 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
505 1.1 mrg TREE_NOTHROW (*node) = 1;
506 1.1 mrg return NULL_TREE;
507 1.1 mrg }
508 1.1 mrg
509 1.1 mrg /* Handle a "type_generic" attribute. */
510 1.1 mrg
511 1.1 mrg static tree
512 1.1 mrg handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
513 1.1 mrg tree ARG_UNUSED (args), int ARG_UNUSED (flags),
514 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
515 1.1 mrg {
516 1.1 mrg /* Ensure we have a function type. */
517 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
518 1.1 mrg
519 1.1 mrg /* Ensure we have a variadic function. */
520 1.1 mrg gcc_assert (!prototype_p (*node) || stdarg_p (*node));
521 1.1 mrg
522 1.1 mrg return NULL_TREE;
523 1.1 mrg }
524 1.1 mrg
525 1.1 mrg /* Handle a "transaction_pure" attribute. */
526 1.1 mrg
527 1.1 mrg static tree
528 1.1 mrg handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name),
529 1.1 mrg tree ARG_UNUSED (args),
530 1.1 mrg int ARG_UNUSED (flags),
531 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
532 1.1 mrg {
533 1.1 mrg /* Ensure we have a function type. */
534 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
535 1.1 mrg
536 1.1 mrg return NULL_TREE;
537 1.1 mrg }
538 1.1 mrg
539 1.1 mrg /* Handle a "returns_twice" attribute. */
540 1.1 mrg
541 1.1 mrg static tree
542 1.1 mrg handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),
543 1.1 mrg tree ARG_UNUSED (args),
544 1.1 mrg int ARG_UNUSED (flags),
545 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
546 1.1 mrg {
547 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
548 1.1 mrg
549 1.1 mrg DECL_IS_RETURNS_TWICE (*node) = 1;
550 1.1 mrg
551 1.1 mrg return NULL_TREE;
552 1.1 mrg }
553 1.1 mrg
554 1.1 mrg /* Handle a "fn spec" attribute; arguments as in
555 1.1 mrg struct attribute_spec.handler. */
556 1.1 mrg
557 1.1 mrg tree
558 1.1 mrg handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
559 1.1 mrg tree args, int ARG_UNUSED (flags),
560 1.1 mrg bool *no_add_attrs ATTRIBUTE_UNUSED)
561 1.1 mrg {
562 1.1 mrg gcc_assert (args
563 1.1 mrg && TREE_CODE (TREE_VALUE (args)) == STRING_CST
564 1.1 mrg && !TREE_CHAIN (args));
565 1.1 mrg return NULL_TREE;
566 1.1 mrg }
567 1.1 mrg
568 1.1 mrg /* Language specific attribute handlers. */
569 1.1 mrg
570 1.1 mrg /* Handle a "noinline" attribute. */
571 1.1 mrg
572 1.1 mrg static tree
573 1.1 mrg d_handle_noinline_attribute (tree *node, tree name,
574 1.1 mrg tree ARG_UNUSED (args),
575 1.1 mrg int ARG_UNUSED (flags), bool *no_add_attrs)
576 1.1 mrg {
577 1.1 mrg Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));
578 1.1 mrg
579 1.1 mrg if (t->ty == Tfunction)
580 1.1 mrg DECL_UNINLINABLE (*node) = 1;
581 1.1 mrg else
582 1.1 mrg {
583 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
584 1.1 mrg *no_add_attrs = true;
585 1.1 mrg }
586 1.1 mrg
587 1.1 mrg return NULL_TREE;
588 1.1 mrg }
589 1.1 mrg
590 1.1 mrg /* Handle a "forceinline" attribute. */
591 1.1 mrg
592 1.1 mrg static tree
593 1.1 mrg d_handle_forceinline_attribute (tree *node, tree name,
594 1.1 mrg tree ARG_UNUSED (args),
595 1.1 mrg int ARG_UNUSED (flags),
596 1.1 mrg bool *no_add_attrs)
597 1.1 mrg {
598 1.1 mrg Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));
599 1.1 mrg
600 1.1 mrg if (t->ty == Tfunction)
601 1.1 mrg {
602 1.1 mrg tree attributes = DECL_ATTRIBUTES (*node);
603 1.1 mrg
604 1.1 mrg /* Push attribute always_inline. */
605 1.1 mrg if (! lookup_attribute ("always_inline", attributes))
606 1.1 mrg DECL_ATTRIBUTES (*node) = tree_cons (get_identifier ("always_inline"),
607 1.1 mrg NULL_TREE, attributes);
608 1.1 mrg
609 1.1 mrg DECL_DECLARED_INLINE_P (*node) = 1;
610 1.1 mrg DECL_NO_INLINE_WARNING_P (*node) = 1;
611 1.1 mrg DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
612 1.1 mrg }
613 1.1 mrg else
614 1.1 mrg {
615 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
616 1.1 mrg *no_add_attrs = true;
617 1.1 mrg }
618 1.1 mrg
619 1.1 mrg return NULL_TREE;
620 1.1 mrg }
621 1.1 mrg
622 1.1 mrg /* Handle a "flatten" attribute. */
623 1.1 mrg
624 1.1 mrg static tree
625 1.1 mrg d_handle_flatten_attribute (tree *node, tree name,
626 1.1 mrg tree args ATTRIBUTE_UNUSED,
627 1.1 mrg int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
628 1.1 mrg {
629 1.1 mrg Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));
630 1.1 mrg
631 1.1 mrg if (t->ty != Tfunction)
632 1.1 mrg {
633 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
634 1.1 mrg *no_add_attrs = true;
635 1.1 mrg }
636 1.1 mrg
637 1.1 mrg return NULL_TREE;
638 1.1 mrg }
639 1.1 mrg
640 1.1 mrg /* Handle a "target" attribute. */
641 1.1 mrg
642 1.1 mrg static tree
643 1.1 mrg d_handle_target_attribute (tree *node, tree name, tree args, int flags,
644 1.1 mrg bool *no_add_attrs)
645 1.1 mrg {
646 1.1 mrg Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));
647 1.1 mrg
648 1.1 mrg /* Ensure we have a function type. */
649 1.1 mrg if (t->ty != Tfunction)
650 1.1 mrg {
651 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
652 1.1 mrg *no_add_attrs = true;
653 1.1 mrg }
654 1.1 mrg else if (! targetm.target_option.valid_attribute_p (*node, name, args, flags))
655 1.1 mrg *no_add_attrs = true;
656 1.1 mrg
657 1.1 mrg return NULL_TREE;
658 1.1 mrg }
659 1.1 mrg
660 1.1 mrg /* Handle a "noclone" attribute. */
661 1.1 mrg
662 1.1 mrg static tree
663 1.1 mrg d_handle_noclone_attribute (tree *node, tree name,
664 1.1 mrg tree ARG_UNUSED (args),
665 1.1 mrg int ARG_UNUSED (flags),
666 1.1 mrg bool *no_add_attrs)
667 1.1 mrg {
668 1.1 mrg Type *t = TYPE_LANG_FRONTEND (TREE_TYPE (*node));
669 1.1 mrg
670 1.1 mrg if (t->ty == Tfunction)
671 1.1 mrg {
672 1.1 mrg tree attributes = DECL_ATTRIBUTES (*node);
673 1.1 mrg
674 1.1 mrg /* Push attribute noclone. */
675 1.1 mrg if (! lookup_attribute ("noclone", attributes))
676 1.1 mrg DECL_ATTRIBUTES (*node) = tree_cons (get_identifier ("noclone"),
677 1.1 mrg NULL_TREE, attributes);
678 1.1 mrg }
679 1.1 mrg else
680 1.1 mrg {
681 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
682 1.1 mrg *no_add_attrs = true;
683 1.1 mrg }
684 1.1 mrg
685 1.1 mrg return NULL_TREE;
686 1.1 mrg }
687 1.1 mrg
688 1.1 mrg /* Handle a "section" attribute; arguments as in
689 1.1 mrg struct attribute_spec.handler. */
690 1.1 mrg
691 1.1 mrg static tree
692 1.1 mrg d_handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,
693 1.1 mrg int ARG_UNUSED (flags), bool *no_add_attrs)
694 1.1 mrg {
695 1.1 mrg tree decl = *node;
696 1.1 mrg
697 1.1 mrg if (targetm_common.have_named_sections)
698 1.1 mrg {
699 1.1 mrg if (VAR_OR_FUNCTION_DECL_P (decl)
700 1.1 mrg && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
701 1.1 mrg {
702 1.1 mrg if (VAR_P (decl)
703 1.1 mrg && current_function_decl != NULL_TREE
704 1.1 mrg && !TREE_STATIC (decl))
705 1.1 mrg {
706 1.1 mrg error_at (DECL_SOURCE_LOCATION (decl),
707 1.1 mrg "section attribute cannot be specified for "
708 1.1 mrg "local variables");
709 1.1 mrg *no_add_attrs = true;
710 1.1 mrg }
711 1.1 mrg
712 1.1 mrg /* The decl may have already been given a section attribute
713 1.1 mrg from a previous declaration. Ensure they match. */
714 1.1 mrg else if (DECL_SECTION_NAME (decl) != NULL
715 1.1 mrg && strcmp (DECL_SECTION_NAME (decl),
716 1.1 mrg TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
717 1.1 mrg {
718 1.1 mrg error ("section of %q+D conflicts with previous declaration",
719 1.1 mrg *node);
720 1.1 mrg *no_add_attrs = true;
721 1.1 mrg }
722 1.1 mrg else if (VAR_P (decl)
723 1.1 mrg && !targetm.have_tls && targetm.emutls.tmpl_section
724 1.1 mrg && DECL_THREAD_LOCAL_P (decl))
725 1.1 mrg {
726 1.1 mrg error ("section of %q+D cannot be overridden", *node);
727 1.1 mrg *no_add_attrs = true;
728 1.1 mrg }
729 1.1 mrg else
730 1.1 mrg set_decl_section_name (decl,
731 1.1 mrg TREE_STRING_POINTER (TREE_VALUE (args)));
732 1.1 mrg }
733 1.1 mrg else
734 1.1 mrg {
735 1.1 mrg error ("section attribute not allowed for %q+D", *node);
736 1.1 mrg *no_add_attrs = true;
737 1.1 mrg }
738 1.1 mrg }
739 1.1 mrg else
740 1.1 mrg {
741 1.1 mrg error_at (DECL_SOURCE_LOCATION (*node),
742 1.1 mrg "section attributes are not supported for this target");
743 1.1 mrg *no_add_attrs = true;
744 1.1 mrg }
745 1.1 mrg
746 1.1 mrg return NULL_TREE;
747 1.1 mrg }
748 1.1 mrg
749 1.1 mrg /* Handle an "alias" attribute; arguments as in
750 1.1 mrg struct attribute_spec.handler. */
751 1.1 mrg
752 1.1 mrg static tree
753 1.1 mrg d_handle_alias_attribute (tree *node, tree ARG_UNUSED (name),
754 1.1 mrg tree args, int ARG_UNUSED (flags),
755 1.1 mrg bool *no_add_attrs ATTRIBUTE_UNUSED)
756 1.1 mrg {
757 1.1 mrg tree decl = *node;
758 1.1 mrg
759 1.1 mrg if (TREE_CODE (decl) != FUNCTION_DECL
760 1.1 mrg && TREE_CODE (decl) != VAR_DECL)
761 1.1 mrg {
762 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
763 1.1 mrg *no_add_attrs = true;
764 1.1 mrg return NULL_TREE;
765 1.1 mrg }
766 1.1 mrg else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
767 1.1 mrg || (TREE_CODE (decl) != FUNCTION_DECL
768 1.1 mrg && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
769 1.1 mrg /* A static variable declaration is always a tentative definition,
770 1.1 mrg but the alias is a non-tentative definition which overrides. */
771 1.1 mrg || (TREE_CODE (decl) != FUNCTION_DECL
772 1.1 mrg && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
773 1.1 mrg {
774 1.1 mrg error ("%q+D defined both normally and as %qE attribute", decl, name);
775 1.1 mrg *no_add_attrs = true;
776 1.1 mrg return NULL_TREE;
777 1.1 mrg }
778 1.1 mrg else if (decl_function_context (decl))
779 1.1 mrg {
780 1.1 mrg error ("%q+D alias functions must be global", name);
781 1.1 mrg *no_add_attrs = true;
782 1.1 mrg return NULL_TREE;
783 1.1 mrg }
784 1.1 mrg else
785 1.1 mrg {
786 1.1 mrg tree id;
787 1.1 mrg
788 1.1 mrg id = TREE_VALUE (args);
789 1.1 mrg if (TREE_CODE (id) != STRING_CST)
790 1.1 mrg {
791 1.1 mrg error ("attribute %qE argument not a string", name);
792 1.1 mrg *no_add_attrs = true;
793 1.1 mrg return NULL_TREE;
794 1.1 mrg }
795 1.1 mrg id = get_identifier (TREE_STRING_POINTER (id));
796 1.1 mrg /* This counts as a use of the object pointed to. */
797 1.1 mrg TREE_USED (id) = 1;
798 1.1 mrg
799 1.1 mrg if (TREE_CODE (decl) == FUNCTION_DECL)
800 1.1 mrg DECL_INITIAL (decl) = error_mark_node;
801 1.1 mrg else
802 1.1 mrg TREE_STATIC (decl) = 1;
803 1.1 mrg
804 1.1 mrg return NULL_TREE;
805 1.1 mrg }
806 1.1 mrg }
807 1.1 mrg
808 1.1 mrg /* Handle a "weak" attribute; arguments as in
809 1.1 mrg struct attribute_spec.handler. */
810 1.1 mrg
811 1.1 mrg static tree
812 1.1 mrg d_handle_weak_attribute (tree *node, tree name,
813 1.1 mrg tree ARG_UNUSED (args),
814 1.1 mrg int ARG_UNUSED (flags),
815 1.1 mrg bool * ARG_UNUSED (no_add_attrs))
816 1.1 mrg {
817 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL
818 1.1 mrg && DECL_DECLARED_INLINE_P (*node))
819 1.1 mrg {
820 1.1 mrg warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
821 1.1 mrg *no_add_attrs = true;
822 1.1 mrg }
823 1.1 mrg else if (VAR_OR_FUNCTION_DECL_P (*node))
824 1.1 mrg {
825 1.1 mrg struct symtab_node *n = symtab_node::get (*node);
826 1.1 mrg if (n && n->refuse_visibility_changes)
827 1.1 mrg error ("%q+D declared weak after being used", *node);
828 1.1 mrg declare_weak (*node);
829 1.1 mrg }
830 1.1 mrg else
831 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name);
832 1.1 mrg
833 1.1 mrg return NULL_TREE;
834 1.1 mrg }
835 1.1 mrg
836