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