1 1.1 mrg /* d-attribs.c -- D attributes handling. 2 1.1.1.3 mrg Copyright (C) 2015-2022 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.1.2 mrg #include "dmd/attrib.h" 26 1.1 mrg #include "dmd/declaration.h" 27 1.1.1.3 mrg #include "dmd/expression.h" 28 1.1.1.3 mrg #include "dmd/module.h" 29 1.1 mrg #include "dmd/mtype.h" 30 1.1.1.3 mrg #include "dmd/template.h" 31 1.1 mrg 32 1.1 mrg #include "tree.h" 33 1.1 mrg #include "diagnostic.h" 34 1.1 mrg #include "tm.h" 35 1.1 mrg #include "cgraph.h" 36 1.1 mrg #include "toplev.h" 37 1.1 mrg #include "target.h" 38 1.1 mrg #include "common/common-target.h" 39 1.1 mrg #include "stringpool.h" 40 1.1 mrg #include "attribs.h" 41 1.1 mrg #include "varasm.h" 42 1.1.1.3 mrg #include "fold-const.h" 43 1.1.1.3 mrg #include "opts.h" 44 1.1 mrg 45 1.1 mrg #include "d-tree.h" 46 1.1 mrg 47 1.1 mrg 48 1.1 mrg /* Internal attribute handlers for built-in functions. */ 49 1.1 mrg static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); 50 1.1 mrg static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); 51 1.1 mrg static tree handle_const_attribute (tree *, tree, tree, int, bool *); 52 1.1 mrg static tree handle_malloc_attribute (tree *, tree, tree, int, bool *); 53 1.1 mrg static tree handle_pure_attribute (tree *, tree, tree, int, bool *); 54 1.1 mrg static tree handle_novops_attribute (tree *, tree, tree, int, bool *); 55 1.1 mrg static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); 56 1.1 mrg static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); 57 1.1 mrg static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); 58 1.1 mrg static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *); 59 1.1 mrg static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); 60 1.1 mrg static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); 61 1.1 mrg 62 1.1 mrg /* D attribute handlers for user defined attributes. */ 63 1.1 mrg static tree d_handle_noinline_attribute (tree *, tree, tree, int, bool *); 64 1.1.1.3 mrg static tree d_handle_always_inline_attribute (tree *, tree, tree, int, bool *); 65 1.1 mrg static tree d_handle_flatten_attribute (tree *, tree, tree, int, bool *); 66 1.1 mrg static tree d_handle_target_attribute (tree *, tree, tree, int, bool *); 67 1.1.1.3 mrg static tree d_handle_target_clones_attribute (tree *, tree, tree, int, bool *); 68 1.1.1.3 mrg static tree d_handle_optimize_attribute (tree *, tree, tree, int, bool *); 69 1.1 mrg static tree d_handle_noclone_attribute (tree *, tree, tree, int, bool *); 70 1.1.1.3 mrg static tree d_handle_noicf_attribute (tree *, tree, tree, int, bool *); 71 1.1.1.3 mrg static tree d_handle_noipa_attribute (tree *, tree, tree, int, bool *); 72 1.1 mrg static tree d_handle_section_attribute (tree *, tree, tree, int, bool *); 73 1.1.1.3 mrg static tree d_handle_symver_attribute (tree *, tree, tree, int, bool *); 74 1.1 mrg static tree d_handle_weak_attribute (tree *, tree, tree, int, bool *) ; 75 1.1.1.3 mrg static tree d_handle_noplt_attribute (tree *, tree, tree, int, bool *) ; 76 1.1.1.3 mrg static tree d_handle_alloc_size_attribute (tree *, tree, tree, int, bool *); 77 1.1.1.3 mrg static tree d_handle_cold_attribute (tree *, tree, tree, int, bool *); 78 1.1.1.3 mrg static tree d_handle_restrict_attribute (tree *, tree, tree, int, bool *); 79 1.1.1.3 mrg static tree d_handle_used_attribute (tree *, tree, tree, int, bool *); 80 1.1 mrg 81 1.1 mrg /* Helper to define attribute exclusions. */ 82 1.1 mrg #define ATTR_EXCL(name, function, type, variable) \ 83 1.1 mrg { name, function, type, variable } 84 1.1 mrg 85 1.1 mrg /* Define attributes that are mutually exclusive with one another. */ 86 1.1 mrg static const struct attribute_spec::exclusions attr_noreturn_exclusions[] = 87 1.1 mrg { 88 1.1.1.3 mrg ATTR_EXCL ("alloc_size", true, true, true), 89 1.1 mrg ATTR_EXCL ("const", true, true, true), 90 1.1 mrg ATTR_EXCL ("malloc", true, true, true), 91 1.1 mrg ATTR_EXCL ("pure", true, true, true), 92 1.1 mrg ATTR_EXCL ("returns_twice", true, true, true), 93 1.1 mrg ATTR_EXCL (NULL, false, false, false), 94 1.1 mrg }; 95 1.1 mrg 96 1.1 mrg static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] = 97 1.1 mrg { 98 1.1 mrg ATTR_EXCL ("noreturn", true, true, true), 99 1.1 mrg ATTR_EXCL (NULL, false, false, false), 100 1.1 mrg }; 101 1.1 mrg 102 1.1 mrg static const struct attribute_spec::exclusions attr_const_pure_exclusions[] = 103 1.1 mrg { 104 1.1.1.3 mrg ATTR_EXCL ("alloc_size", true, true, true), 105 1.1 mrg ATTR_EXCL ("const", true, true, true), 106 1.1 mrg ATTR_EXCL ("noreturn", true, true, true), 107 1.1 mrg ATTR_EXCL ("pure", true, true, true), 108 1.1 mrg ATTR_EXCL (NULL, false, false, false) 109 1.1 mrg }; 110 1.1 mrg 111 1.1 mrg static const struct attribute_spec::exclusions attr_inline_exclusions[] = 112 1.1 mrg { 113 1.1 mrg ATTR_EXCL ("noinline", true, true, true), 114 1.1.1.3 mrg ATTR_EXCL ("target_clones", true, true, true), 115 1.1 mrg ATTR_EXCL (NULL, false, false, false), 116 1.1 mrg }; 117 1.1 mrg 118 1.1 mrg static const struct attribute_spec::exclusions attr_noinline_exclusions[] = 119 1.1 mrg { 120 1.1.1.3 mrg ATTR_EXCL ("always_inline", true, true, true), 121 1.1 mrg ATTR_EXCL (NULL, false, false, false), 122 1.1 mrg }; 123 1.1 mrg 124 1.1.1.3 mrg static const struct attribute_spec::exclusions attr_target_exclusions[] = 125 1.1.1.3 mrg { 126 1.1.1.3 mrg ATTR_EXCL ("target_clones", true, true, true), 127 1.1.1.3 mrg ATTR_EXCL (NULL, false, false, false), 128 1.1.1.3 mrg }; 129 1.1.1.3 mrg 130 1.1.1.3 mrg static const struct attribute_spec::exclusions attr_target_clones_exclusions[] = 131 1.1.1.3 mrg { 132 1.1.1.3 mrg ATTR_EXCL ("always_inline", true, true, true), 133 1.1.1.3 mrg ATTR_EXCL ("target", true, true, true), 134 1.1.1.3 mrg ATTR_EXCL (NULL, false, false, false), 135 1.1.1.3 mrg }; 136 1.1.1.3 mrg 137 1.1.1.3 mrg static const struct attribute_spec::exclusions attr_alloc_exclusions[] = 138 1.1.1.3 mrg { 139 1.1.1.3 mrg ATTR_EXCL ("const", true, true, true), 140 1.1.1.3 mrg ATTR_EXCL ("noreturn", true, true, true), 141 1.1.1.3 mrg ATTR_EXCL ("pure", true, true, true), 142 1.1.1.3 mrg ATTR_EXCL (NULL, false, false, false), 143 1.1.1.3 mrg }; 144 1.1.1.3 mrg 145 1.1.1.3 mrg extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] = 146 1.1.1.3 mrg { 147 1.1.1.3 mrg ATTR_EXCL ("cold", true, true, true), 148 1.1.1.3 mrg ATTR_EXCL ("hot", true, true, true), 149 1.1.1.3 mrg ATTR_EXCL (NULL, false, false, false) 150 1.1.1.3 mrg }; 151 1.1.1.3 mrg 152 1.1 mrg /* Helper to define an attribute. */ 153 1.1 mrg #define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \ 154 1.1 mrg affects_type_identity, handler, exclude) \ 155 1.1 mrg { name, min_len, max_len, decl_req, type_req, fn_type_req, \ 156 1.1 mrg affects_type_identity, handler, exclude } 157 1.1 mrg 158 1.1 mrg /* Table of machine-independent attributes. 159 1.1 mrg For internal use (marking of built-ins) only. */ 160 1.1 mrg const attribute_spec d_langhook_common_attribute_table[] = 161 1.1 mrg { 162 1.1 mrg ATTR_SPEC ("noreturn", 0, 0, true, false, false, false, 163 1.1 mrg handle_noreturn_attribute, attr_noreturn_exclusions), 164 1.1 mrg ATTR_SPEC ("leaf", 0, 0, true, false, false, false, 165 1.1 mrg handle_leaf_attribute, NULL), 166 1.1 mrg ATTR_SPEC ("const", 0, 0, true, false, false, false, 167 1.1 mrg handle_const_attribute, attr_const_pure_exclusions), 168 1.1 mrg ATTR_SPEC ("malloc", 0, 0, true, false, false, false, 169 1.1 mrg handle_malloc_attribute, NULL), 170 1.1 mrg ATTR_SPEC ("returns_twice", 0, 0, true, false, false, false, 171 1.1 mrg handle_returns_twice_attribute, attr_returns_twice_exclusions), 172 1.1 mrg ATTR_SPEC ("pure", 0, 0, true, false, false, false, 173 1.1 mrg handle_pure_attribute, attr_const_pure_exclusions), 174 1.1 mrg ATTR_SPEC ("nonnull", 0, -1, false, true, true, false, 175 1.1 mrg handle_nonnull_attribute, NULL), 176 1.1 mrg ATTR_SPEC ("nothrow", 0, 0, true, false, false, false, 177 1.1 mrg handle_nothrow_attribute, NULL), 178 1.1 mrg ATTR_SPEC ("transaction_pure", 0, 0, false, true, true, false, 179 1.1 mrg handle_transaction_pure_attribute, NULL), 180 1.1 mrg ATTR_SPEC ("no vops", 0, 0, true, false, false, false, 181 1.1 mrg handle_novops_attribute, NULL), 182 1.1 mrg ATTR_SPEC ("type generic", 0, 0, false, true, true, false, 183 1.1 mrg handle_type_generic_attribute, NULL), 184 1.1 mrg ATTR_SPEC ("fn spec", 1, 1, false, true, true, false, 185 1.1 mrg handle_fnspec_attribute, NULL), 186 1.1 mrg ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL), 187 1.1 mrg }; 188 1.1 mrg 189 1.1 mrg /* Table of D language attributes exposed by `gcc.attribute' UDAs. */ 190 1.1 mrg const attribute_spec d_langhook_attribute_table[] = 191 1.1 mrg { 192 1.1 mrg ATTR_SPEC ("noinline", 0, 0, true, false, false, false, 193 1.1 mrg d_handle_noinline_attribute, attr_noinline_exclusions), 194 1.1.1.3 mrg ATTR_SPEC ("always_inline", 0, 0, true, false, false, false, 195 1.1.1.3 mrg d_handle_always_inline_attribute, attr_inline_exclusions), 196 1.1 mrg ATTR_SPEC ("flatten", 0, 0, true, false, false, false, 197 1.1 mrg d_handle_flatten_attribute, NULL), 198 1.1 mrg ATTR_SPEC ("target", 1, -1, true, false, false, false, 199 1.1.1.3 mrg d_handle_target_attribute, attr_target_exclusions), 200 1.1.1.3 mrg ATTR_SPEC ("target_clones", 1, -1, true, false, false, false, 201 1.1.1.3 mrg d_handle_target_clones_attribute, attr_target_clones_exclusions), 202 1.1.1.3 mrg ATTR_SPEC ("optimize", 1, -1, true, false, false, false, 203 1.1.1.3 mrg d_handle_optimize_attribute, NULL), 204 1.1 mrg ATTR_SPEC ("noclone", 0, 0, true, false, false, false, 205 1.1 mrg d_handle_noclone_attribute, NULL), 206 1.1.1.3 mrg ATTR_SPEC ("no_icf", 0, 0, true, false, false, false, 207 1.1.1.3 mrg d_handle_noicf_attribute, NULL), 208 1.1.1.3 mrg ATTR_SPEC ("noipa", 0, 0, true, false, false, false, 209 1.1.1.3 mrg d_handle_noipa_attribute, NULL), 210 1.1 mrg ATTR_SPEC ("section", 1, 1, true, false, false, false, 211 1.1 mrg d_handle_section_attribute, NULL), 212 1.1.1.3 mrg ATTR_SPEC ("symver", 1, -1, true, false, false, false, 213 1.1.1.3 mrg d_handle_symver_attribute, NULL), 214 1.1 mrg ATTR_SPEC ("weak", 0, 0, true, false, false, false, 215 1.1 mrg d_handle_weak_attribute, NULL), 216 1.1.1.3 mrg ATTR_SPEC ("noplt", 0, 0, true, false, false, false, 217 1.1.1.3 mrg d_handle_noplt_attribute, NULL), 218 1.1.1.3 mrg ATTR_SPEC ("alloc_size", 1, 3, false, true, true, false, 219 1.1.1.3 mrg d_handle_alloc_size_attribute, attr_alloc_exclusions), 220 1.1.1.3 mrg ATTR_SPEC ("cold", 0, 0, true, false, false, false, 221 1.1.1.3 mrg d_handle_cold_attribute, attr_cold_hot_exclusions), 222 1.1.1.3 mrg ATTR_SPEC ("restrict", 0, 0, true, false, false, false, 223 1.1.1.3 mrg d_handle_restrict_attribute, NULL), 224 1.1.1.3 mrg ATTR_SPEC ("used", 0, 0, true, false, false, false, 225 1.1.1.3 mrg d_handle_used_attribute, NULL), 226 1.1 mrg ATTR_SPEC (NULL, 0, 0, false, false, false, false, NULL, NULL), 227 1.1 mrg }; 228 1.1 mrg 229 1.1 mrg 230 1.1 mrg /* Insert the type attribute ATTRNAME with value VALUE into TYPE. 231 1.1 mrg Returns a new variant of the original type declaration. */ 232 1.1 mrg 233 1.1 mrg tree 234 1.1 mrg insert_type_attribute (tree type, const char *attrname, tree value) 235 1.1 mrg { 236 1.1 mrg tree ident = get_identifier (attrname); 237 1.1 mrg 238 1.1 mrg if (value) 239 1.1 mrg value = tree_cons (NULL_TREE, value, NULL_TREE); 240 1.1 mrg 241 1.1 mrg tree attribs = merge_attributes (TYPE_ATTRIBUTES (type), 242 1.1 mrg tree_cons (ident, value, NULL_TREE)); 243 1.1 mrg 244 1.1 mrg return build_type_attribute_variant (type, attribs); 245 1.1 mrg } 246 1.1 mrg 247 1.1 mrg /* Insert the decl attribute ATTRNAME with value VALUE into DECL. */ 248 1.1 mrg 249 1.1 mrg tree 250 1.1 mrg insert_decl_attribute (tree decl, const char *attrname, tree value) 251 1.1 mrg { 252 1.1 mrg tree ident = get_identifier (attrname); 253 1.1 mrg 254 1.1 mrg if (value) 255 1.1 mrg value = tree_cons (NULL_TREE, value, NULL_TREE); 256 1.1 mrg 257 1.1 mrg tree attribs = merge_attributes (DECL_ATTRIBUTES (decl), 258 1.1 mrg tree_cons (ident, value, NULL_TREE)); 259 1.1 mrg 260 1.1 mrg return build_decl_attribute_variant (decl, attribs); 261 1.1 mrg } 262 1.1 mrg 263 1.1 mrg /* Returns TRUE if NAME is an attribute recognized as being handled by 264 1.1 mrg the `gcc.attribute' module. */ 265 1.1 mrg 266 1.1 mrg static bool 267 1.1 mrg uda_attribute_p (const char *name) 268 1.1 mrg { 269 1.1 mrg tree ident = get_identifier (name); 270 1.1 mrg 271 1.1 mrg /* Search both our language, and target attribute tables. 272 1.1 mrg Common and format attributes are kept internal. */ 273 1.1 mrg for (const attribute_spec *p = d_langhook_attribute_table; p->name; p++) 274 1.1 mrg { 275 1.1 mrg if (get_identifier (p->name) == ident) 276 1.1 mrg return true; 277 1.1 mrg } 278 1.1 mrg 279 1.1.1.2 mrg if (targetm.attribute_table) 280 1.1 mrg { 281 1.1.1.2 mrg for (const attribute_spec *p = targetm.attribute_table; p->name; p++) 282 1.1.1.2 mrg { 283 1.1.1.2 mrg if (get_identifier (p->name) == ident) 284 1.1.1.2 mrg return true; 285 1.1.1.2 mrg } 286 1.1 mrg } 287 1.1 mrg 288 1.1 mrg return false; 289 1.1 mrg } 290 1.1 mrg 291 1.1 mrg /* [attribute/uda] 292 1.1 mrg 293 1.1 mrg User Defined Attributes (UDA) are compile time expressions that can be 294 1.1 mrg attached to a declaration. These attributes can then be queried, extracted, 295 1.1 mrg and manipulated at compile-time. There is no run-time component to them. 296 1.1 mrg 297 1.1 mrg Expand and merge all UDAs found in the EATTRS list that are of type 298 1.1 mrg `gcc.attribute.Attribute'. This symbol is internally recognized by the 299 1.1 mrg compiler and maps them to their equivalent GCC attribute. */ 300 1.1 mrg 301 1.1.1.2 mrg static tree 302 1.1 mrg build_attributes (Expressions *eattrs) 303 1.1 mrg { 304 1.1 mrg if (!eattrs) 305 1.1 mrg return NULL_TREE; 306 1.1 mrg 307 1.1 mrg expandTuples (eattrs); 308 1.1 mrg 309 1.1 mrg tree attribs = NULL_TREE; 310 1.1 mrg 311 1.1.1.3 mrg for (size_t i = 0; i < eattrs->length; i++) 312 1.1 mrg { 313 1.1 mrg Expression *attr = (*eattrs)[i]; 314 1.1 mrg Dsymbol *sym = attr->type->toDsymbol (0); 315 1.1 mrg 316 1.1 mrg if (!sym) 317 1.1.1.3 mrg { 318 1.1.1.3 mrg /* If attribute is a template symbol, perhaps arguments were not 319 1.1.1.3 mrg supplied, so warn about attribute having no effect. */ 320 1.1.1.3 mrg if (TemplateExp *te = attr->isTemplateExp ()) 321 1.1.1.3 mrg { 322 1.1.1.3 mrg if (!te->td || !te->td->onemember) 323 1.1.1.3 mrg continue; 324 1.1.1.3 mrg 325 1.1.1.3 mrg sym = te->td->onemember; 326 1.1.1.3 mrg } 327 1.1.1.3 mrg else 328 1.1.1.3 mrg continue; 329 1.1.1.3 mrg } 330 1.1 mrg 331 1.1 mrg /* Attribute symbol must come from the `gcc.attribute' module. */ 332 1.1.1.3 mrg Dsymbol *mod = sym->getModule (); 333 1.1.1.3 mrg if (!(strcmp (mod->toChars (), "attributes") == 0 334 1.1 mrg && mod->parent != NULL 335 1.1 mrg && strcmp (mod->parent->toChars (), "gcc") == 0 336 1.1 mrg && !mod->parent->parent)) 337 1.1 mrg continue; 338 1.1 mrg 339 1.1 mrg /* Get the result of the attribute if it hasn't already been folded. */ 340 1.1.1.3 mrg if (attr->op == EXP::call) 341 1.1 mrg attr = attr->ctfeInterpret (); 342 1.1 mrg 343 1.1.1.3 mrg if (attr->op != EXP::structLiteral) 344 1.1.1.3 mrg { 345 1.1.1.3 mrg warning_at (make_location_t (attr->loc), OPT_Wattributes, 346 1.1.1.3 mrg "%qE attribute has no effect", 347 1.1.1.3 mrg get_identifier (sym->toChars ())); 348 1.1.1.3 mrg continue; 349 1.1.1.3 mrg } 350 1.1.1.3 mrg 351 1.1 mrg /* Should now have a struct `Attribute("attrib", "value", ...)' 352 1.1 mrg initializer list. */ 353 1.1.1.3 mrg Expressions *elems = attr->isStructLiteralExp ()->elements; 354 1.1 mrg Expression *e0 = (*elems)[0]; 355 1.1 mrg 356 1.1.1.3 mrg if (e0->op != EXP::string_) 357 1.1 mrg { 358 1.1.1.3 mrg warning_at (make_location_t (attr->loc), OPT_Wattributes, 359 1.1.1.3 mrg "unknown attribute %qs", e0->toChars()); 360 1.1.1.3 mrg continue; 361 1.1 mrg } 362 1.1 mrg 363 1.1.1.3 mrg StringExp *se = e0->toStringExp (); 364 1.1 mrg gcc_assert (se->sz == 1); 365 1.1 mrg 366 1.1 mrg /* Empty string attribute, just ignore it. */ 367 1.1 mrg if (se->len == 0) 368 1.1 mrg continue; 369 1.1 mrg 370 1.1 mrg /* Check if the attribute is recognized and handled. 371 1.1 mrg Done here to report the diagnostic at the right location. */ 372 1.1 mrg const char *name = (const char *)(se->len ? se->string : ""); 373 1.1 mrg if (!uda_attribute_p (name)) 374 1.1 mrg { 375 1.1.1.3 mrg warning_at (make_location_t (attr->loc), OPT_Wattributes, 376 1.1 mrg "unknown attribute %qs", name); 377 1.1.1.3 mrg continue; 378 1.1 mrg } 379 1.1 mrg 380 1.1 mrg /* Chain all attribute arguments together. */ 381 1.1 mrg tree args = NULL_TREE; 382 1.1 mrg 383 1.1.1.3 mrg for (size_t j = 1; j < elems->length; j++) 384 1.1 mrg { 385 1.1 mrg Expression *e = (*elems)[j]; 386 1.1.1.3 mrg /* Stop after the first `void' argument. */ 387 1.1.1.3 mrg if (e == NULL) 388 1.1.1.3 mrg break; 389 1.1.1.3 mrg 390 1.1.1.3 mrg StringExp *s = e->isStringExp (); 391 1.1 mrg tree t; 392 1.1.1.3 mrg if (s != NULL && s->sz == 1) 393 1.1 mrg { 394 1.1 mrg const char *string = (const char *)(s->len ? s->string : ""); 395 1.1 mrg t = build_string (s->len, string); 396 1.1 mrg } 397 1.1 mrg else 398 1.1 mrg t = build_expr (e); 399 1.1 mrg 400 1.1 mrg args = chainon (args, build_tree_list (0, t)); 401 1.1 mrg } 402 1.1 mrg 403 1.1 mrg tree list = build_tree_list (get_identifier (name), args); 404 1.1 mrg attribs = chainon (attribs, list); 405 1.1 mrg } 406 1.1 mrg 407 1.1 mrg return attribs; 408 1.1 mrg } 409 1.1 mrg 410 1.1.1.2 mrg /* If any GCC attributes are found in the declaration SYM, apply them to the 411 1.1.1.2 mrg type or decl NODE. */ 412 1.1.1.2 mrg 413 1.1.1.2 mrg void 414 1.1.1.2 mrg apply_user_attributes (Dsymbol *sym, tree node) 415 1.1.1.2 mrg { 416 1.1.1.2 mrg if (!sym->userAttribDecl) 417 1.1.1.2 mrg { 418 1.1.1.2 mrg if (DECL_P (node) && DECL_ATTRIBUTES (node) != NULL) 419 1.1.1.2 mrg decl_attributes (&node, DECL_ATTRIBUTES (node), 0); 420 1.1.1.2 mrg 421 1.1.1.2 mrg return; 422 1.1.1.2 mrg } 423 1.1.1.2 mrg 424 1.1.1.2 mrg location_t saved_location = input_location; 425 1.1.1.2 mrg input_location = make_location_t (sym->loc); 426 1.1.1.2 mrg 427 1.1.1.2 mrg Expressions *attrs = sym->userAttribDecl->getAttributes (); 428 1.1.1.2 mrg decl_attributes (&node, build_attributes (attrs), 429 1.1.1.2 mrg TYPE_P (node) ? ATTR_FLAG_TYPE_IN_PLACE : 0); 430 1.1.1.2 mrg 431 1.1.1.2 mrg input_location = saved_location; 432 1.1.1.2 mrg } 433 1.1.1.2 mrg 434 1.1.1.3 mrg /* Built-in attribute handlers. 435 1.1.1.3 mrg These functions take the arguments: 436 1.1.1.3 mrg (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */ 437 1.1 mrg 438 1.1 mrg /* Handle a "noreturn" attribute; arguments as in 439 1.1 mrg struct attribute_spec.handler. */ 440 1.1 mrg 441 1.1 mrg static tree 442 1.1.1.3 mrg handle_noreturn_attribute (tree *node, tree, tree, int, bool *) 443 1.1 mrg { 444 1.1 mrg tree type = TREE_TYPE (*node); 445 1.1 mrg 446 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL) 447 1.1 mrg TREE_THIS_VOLATILE (*node) = 1; 448 1.1 mrg else if (TREE_CODE (type) == POINTER_TYPE 449 1.1 mrg && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) 450 1.1 mrg TREE_TYPE (*node) 451 1.1 mrg = build_pointer_type 452 1.1 mrg (build_type_variant (TREE_TYPE (type), 453 1.1 mrg TYPE_READONLY (TREE_TYPE (type)), 1)); 454 1.1 mrg else 455 1.1 mrg gcc_unreachable (); 456 1.1 mrg 457 1.1 mrg return NULL_TREE; 458 1.1 mrg } 459 1.1 mrg 460 1.1 mrg /* Handle a "leaf" attribute; arguments as in 461 1.1 mrg struct attribute_spec.handler. */ 462 1.1 mrg 463 1.1 mrg static tree 464 1.1.1.3 mrg handle_leaf_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) 465 1.1 mrg { 466 1.1 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 467 1.1 mrg { 468 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 469 1.1 mrg *no_add_attrs = true; 470 1.1 mrg } 471 1.1 mrg if (!TREE_PUBLIC (*node)) 472 1.1 mrg { 473 1.1 mrg warning (OPT_Wattributes, "%qE attribute has no effect", name); 474 1.1 mrg *no_add_attrs = true; 475 1.1 mrg } 476 1.1 mrg 477 1.1 mrg return NULL_TREE; 478 1.1 mrg } 479 1.1 mrg 480 1.1 mrg /* Handle a "const" attribute; arguments as in 481 1.1 mrg struct attribute_spec.handler. */ 482 1.1 mrg 483 1.1 mrg static tree 484 1.1.1.3 mrg handle_const_attribute (tree *node, tree, tree, int, bool *) 485 1.1 mrg { 486 1.1 mrg tree type = TREE_TYPE (*node); 487 1.1 mrg 488 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL) 489 1.1 mrg TREE_READONLY (*node) = 1; 490 1.1 mrg else if (TREE_CODE (type) == POINTER_TYPE 491 1.1 mrg && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) 492 1.1 mrg TREE_TYPE (*node) 493 1.1 mrg = build_pointer_type 494 1.1 mrg (build_type_variant (TREE_TYPE (type), 1, 495 1.1 mrg TREE_THIS_VOLATILE (TREE_TYPE (type)))); 496 1.1 mrg else 497 1.1 mrg gcc_unreachable (); 498 1.1 mrg 499 1.1 mrg return NULL_TREE; 500 1.1 mrg } 501 1.1 mrg 502 1.1 mrg /* Handle a "malloc" attribute; arguments as in 503 1.1 mrg struct attribute_spec.handler. */ 504 1.1 mrg 505 1.1 mrg tree 506 1.1.1.3 mrg handle_malloc_attribute (tree *node, tree, tree, int, bool *) 507 1.1 mrg { 508 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL 509 1.1 mrg && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))); 510 1.1 mrg DECL_IS_MALLOC (*node) = 1; 511 1.1 mrg return NULL_TREE; 512 1.1 mrg } 513 1.1 mrg 514 1.1 mrg /* Handle a "pure" attribute; arguments as in 515 1.1 mrg struct attribute_spec.handler. */ 516 1.1 mrg 517 1.1 mrg static tree 518 1.1.1.3 mrg handle_pure_attribute (tree *node, tree, tree, int, bool *) 519 1.1 mrg { 520 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); 521 1.1 mrg DECL_PURE_P (*node) = 1; 522 1.1 mrg return NULL_TREE; 523 1.1 mrg } 524 1.1 mrg 525 1.1 mrg /* Handle a "no vops" attribute; arguments as in 526 1.1 mrg struct attribute_spec.handler. */ 527 1.1 mrg 528 1.1 mrg static tree 529 1.1.1.3 mrg handle_novops_attribute (tree *node, tree, tree, int, bool *) 530 1.1 mrg { 531 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); 532 1.1 mrg DECL_IS_NOVOPS (*node) = 1; 533 1.1 mrg return NULL_TREE; 534 1.1 mrg } 535 1.1 mrg 536 1.1 mrg /* Helper for nonnull attribute handling; fetch the operand number 537 1.1 mrg from the attribute argument list. */ 538 1.1 mrg 539 1.1 mrg static bool 540 1.1 mrg get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp) 541 1.1 mrg { 542 1.1 mrg /* Verify the arg number is a constant. */ 543 1.1 mrg if (!tree_fits_uhwi_p (arg_num_expr)) 544 1.1 mrg return false; 545 1.1 mrg 546 1.1 mrg *valp = TREE_INT_CST_LOW (arg_num_expr); 547 1.1 mrg return true; 548 1.1 mrg } 549 1.1 mrg 550 1.1 mrg /* Handle the "nonnull" attribute. */ 551 1.1 mrg 552 1.1 mrg static tree 553 1.1.1.3 mrg handle_nonnull_attribute (tree *node, tree, tree args, int, bool *) 554 1.1 mrg { 555 1.1 mrg tree type = *node; 556 1.1 mrg 557 1.1 mrg /* If no arguments are specified, all pointer arguments should be 558 1.1 mrg non-null. Verify a full prototype is given so that the arguments 559 1.1 mrg will have the correct types when we actually check them later. 560 1.1 mrg Avoid diagnosing type-generic built-ins since those have no 561 1.1 mrg prototype. */ 562 1.1 mrg if (!args) 563 1.1 mrg { 564 1.1 mrg gcc_assert (prototype_p (type) 565 1.1 mrg || !TYPE_ATTRIBUTES (type) 566 1.1 mrg || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))); 567 1.1 mrg 568 1.1 mrg return NULL_TREE; 569 1.1 mrg } 570 1.1 mrg 571 1.1 mrg /* Argument list specified. Verify that each argument number references 572 1.1 mrg a pointer argument. */ 573 1.1 mrg for (; args; args = TREE_CHAIN (args)) 574 1.1 mrg { 575 1.1 mrg tree argument; 576 1.1 mrg unsigned HOST_WIDE_INT arg_num = 0, ck_num; 577 1.1 mrg 578 1.1 mrg if (!get_nonnull_operand (TREE_VALUE (args), &arg_num)) 579 1.1 mrg gcc_unreachable (); 580 1.1 mrg 581 1.1 mrg argument = TYPE_ARG_TYPES (type); 582 1.1 mrg if (argument) 583 1.1 mrg { 584 1.1 mrg for (ck_num = 1; ; ck_num++) 585 1.1 mrg { 586 1.1 mrg if (!argument || ck_num == arg_num) 587 1.1 mrg break; 588 1.1 mrg argument = TREE_CHAIN (argument); 589 1.1 mrg } 590 1.1 mrg 591 1.1 mrg gcc_assert (argument 592 1.1 mrg && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE); 593 1.1 mrg } 594 1.1 mrg } 595 1.1 mrg 596 1.1 mrg return NULL_TREE; 597 1.1 mrg } 598 1.1 mrg 599 1.1 mrg /* Handle a "nothrow" attribute; arguments as in 600 1.1 mrg struct attribute_spec.handler. */ 601 1.1 mrg 602 1.1 mrg static tree 603 1.1.1.3 mrg handle_nothrow_attribute (tree *node, tree, tree, int, bool *) 604 1.1 mrg { 605 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); 606 1.1 mrg TREE_NOTHROW (*node) = 1; 607 1.1 mrg return NULL_TREE; 608 1.1 mrg } 609 1.1 mrg 610 1.1.1.3 mrg /* Handle a "type generic" attribute; arguments as in 611 1.1.1.3 mrg struct attribute_spec.handler. */ 612 1.1 mrg 613 1.1 mrg static tree 614 1.1.1.3 mrg handle_type_generic_attribute (tree *node, tree, tree, int, bool *) 615 1.1 mrg { 616 1.1 mrg /* Ensure we have a function type. */ 617 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); 618 1.1 mrg 619 1.1 mrg /* Ensure we have a variadic function. */ 620 1.1 mrg gcc_assert (!prototype_p (*node) || stdarg_p (*node)); 621 1.1 mrg 622 1.1 mrg return NULL_TREE; 623 1.1 mrg } 624 1.1 mrg 625 1.1.1.3 mrg /* Handle a "transaction_pure" attribute; arguments as in 626 1.1.1.3 mrg struct attribute_spec.handler. */ 627 1.1 mrg 628 1.1 mrg static tree 629 1.1.1.3 mrg handle_transaction_pure_attribute (tree *node, tree, tree, int, bool *) 630 1.1 mrg { 631 1.1 mrg /* Ensure we have a function type. */ 632 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); 633 1.1 mrg 634 1.1 mrg return NULL_TREE; 635 1.1 mrg } 636 1.1 mrg 637 1.1.1.3 mrg /* Handle a "returns_twice" attribute; arguments as in 638 1.1.1.3 mrg struct attribute_spec.handler. */ 639 1.1 mrg 640 1.1 mrg static tree 641 1.1.1.3 mrg handle_returns_twice_attribute (tree *node, tree, tree, int, bool *) 642 1.1 mrg { 643 1.1 mrg gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); 644 1.1 mrg 645 1.1 mrg DECL_IS_RETURNS_TWICE (*node) = 1; 646 1.1 mrg 647 1.1 mrg return NULL_TREE; 648 1.1 mrg } 649 1.1 mrg 650 1.1 mrg /* Handle a "fn spec" attribute; arguments as in 651 1.1 mrg struct attribute_spec.handler. */ 652 1.1 mrg 653 1.1 mrg tree 654 1.1.1.3 mrg handle_fnspec_attribute (tree *, tree, tree args, int, bool *) 655 1.1 mrg { 656 1.1 mrg gcc_assert (args 657 1.1 mrg && TREE_CODE (TREE_VALUE (args)) == STRING_CST 658 1.1 mrg && !TREE_CHAIN (args)); 659 1.1 mrg return NULL_TREE; 660 1.1 mrg } 661 1.1 mrg 662 1.1.1.3 mrg /* Language specific attribute handlers. 663 1.1.1.3 mrg These functions take the arguments: 664 1.1.1.3 mrg (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */ 665 1.1 mrg 666 1.1.1.3 mrg /* Handle a "noinline" attribute; arguments as in 667 1.1.1.3 mrg struct attribute_spec.handler. */ 668 1.1 mrg 669 1.1 mrg static tree 670 1.1.1.3 mrg d_handle_noinline_attribute (tree *node, tree name, tree, int, 671 1.1.1.3 mrg bool *no_add_attrs) 672 1.1 mrg { 673 1.1.1.3 mrg if (TREE_CODE (*node) == FUNCTION_DECL) 674 1.1 mrg DECL_UNINLINABLE (*node) = 1; 675 1.1 mrg else 676 1.1 mrg { 677 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 678 1.1 mrg *no_add_attrs = true; 679 1.1 mrg } 680 1.1 mrg 681 1.1 mrg return NULL_TREE; 682 1.1 mrg } 683 1.1 mrg 684 1.1.1.3 mrg /* Handle a "always_inline" attribute; arguments as in 685 1.1.1.3 mrg struct attribute_spec.handler. */ 686 1.1 mrg 687 1.1 mrg static tree 688 1.1.1.3 mrg d_handle_always_inline_attribute (tree *node, tree name, tree, int, 689 1.1.1.3 mrg bool *no_add_attrs) 690 1.1 mrg { 691 1.1.1.3 mrg if (TREE_CODE (*node) == FUNCTION_DECL) 692 1.1 mrg { 693 1.1 mrg DECL_DECLARED_INLINE_P (*node) = 1; 694 1.1 mrg DECL_DISREGARD_INLINE_LIMITS (*node) = 1; 695 1.1 mrg } 696 1.1 mrg else 697 1.1 mrg { 698 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 699 1.1 mrg *no_add_attrs = true; 700 1.1 mrg } 701 1.1 mrg 702 1.1 mrg return NULL_TREE; 703 1.1 mrg } 704 1.1 mrg 705 1.1.1.3 mrg /* Handle a "flatten" attribute; arguments as in 706 1.1.1.3 mrg struct attribute_spec.handler. */ 707 1.1 mrg 708 1.1 mrg static tree 709 1.1.1.3 mrg d_handle_flatten_attribute (tree *node, tree name, tree, int, 710 1.1.1.3 mrg bool *no_add_attrs) 711 1.1 mrg { 712 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 713 1.1 mrg { 714 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 715 1.1 mrg *no_add_attrs = true; 716 1.1 mrg } 717 1.1 mrg 718 1.1 mrg return NULL_TREE; 719 1.1 mrg } 720 1.1 mrg 721 1.1.1.3 mrg /* Handle a "target" attribute; arguments as in 722 1.1.1.3 mrg struct attribute_spec.handler. */ 723 1.1 mrg 724 1.1 mrg static tree 725 1.1 mrg d_handle_target_attribute (tree *node, tree name, tree args, int flags, 726 1.1 mrg bool *no_add_attrs) 727 1.1 mrg { 728 1.1 mrg /* Ensure we have a function type. */ 729 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 730 1.1 mrg { 731 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 732 1.1 mrg *no_add_attrs = true; 733 1.1 mrg } 734 1.1.1.3 mrg else if (!targetm.target_option.valid_attribute_p (*node, name, args, flags)) 735 1.1 mrg *no_add_attrs = true; 736 1.1 mrg 737 1.1.1.3 mrg /* Check that there's no empty string in values of the attribute. */ 738 1.1.1.3 mrg for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t)) 739 1.1.1.3 mrg { 740 1.1.1.3 mrg tree value = TREE_VALUE (t); 741 1.1.1.3 mrg if (TREE_CODE (value) != STRING_CST 742 1.1.1.3 mrg || (TREE_STRING_LENGTH (value) != 0 743 1.1.1.3 mrg && TREE_STRING_POINTER (value)[0] != '\0')) 744 1.1.1.3 mrg continue; 745 1.1.1.3 mrg 746 1.1.1.3 mrg warning (OPT_Wattributes, "empty string in attribute %<target%>"); 747 1.1.1.3 mrg *no_add_attrs = true; 748 1.1.1.3 mrg } 749 1.1.1.3 mrg 750 1.1 mrg return NULL_TREE; 751 1.1 mrg } 752 1.1 mrg 753 1.1.1.3 mrg /* Handle a "target_clones" attribute; arguments as in 754 1.1.1.3 mrg struct attribute_spec.handler. */ 755 1.1 mrg 756 1.1 mrg static tree 757 1.1.1.3 mrg d_handle_target_clones_attribute (tree *node, tree name, tree, int, 758 1.1.1.3 mrg bool *no_add_attrs) 759 1.1 mrg { 760 1.1.1.3 mrg /* Ensure we have a function type. */ 761 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 762 1.1 mrg { 763 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 764 1.1.1.3 mrg *no_add_attrs = true; 765 1.1 mrg } 766 1.1 mrg else 767 1.1 mrg { 768 1.1.1.3 mrg /* Do not inline functions with multiple clone targets. */ 769 1.1.1.3 mrg DECL_UNINLINABLE (*node) = 1; 770 1.1 mrg } 771 1.1 mrg 772 1.1 mrg return NULL_TREE; 773 1.1 mrg } 774 1.1 mrg 775 1.1.1.3 mrg /* Arguments being collected for optimization. */ 776 1.1.1.3 mrg static GTY(()) vec <const char *, va_gc> *optimize_args; 777 1.1 mrg 778 1.1.1.3 mrg /* Inner function to convert a TREE_LIST to argv string to parse the optimize 779 1.1.1.3 mrg options in ARGS. */ 780 1.1.1.3 mrg 781 1.1.1.3 mrg static bool 782 1.1.1.3 mrg parse_optimize_options (tree args) 783 1.1 mrg { 784 1.1.1.3 mrg bool ret = true; 785 1.1 mrg 786 1.1.1.3 mrg /* Build up argv vector. Just in case the string is stored away, use garbage 787 1.1.1.3 mrg collected strings. */ 788 1.1.1.3 mrg vec_safe_truncate (optimize_args, 0); 789 1.1.1.3 mrg vec_safe_push (optimize_args, (const char *) NULL); 790 1.1.1.3 mrg 791 1.1.1.3 mrg for (tree ap = args; ap != NULL_TREE; ap = TREE_CHAIN (ap)) 792 1.1 mrg { 793 1.1.1.3 mrg tree value = TREE_VALUE (ap); 794 1.1.1.3 mrg 795 1.1.1.3 mrg if (TREE_CODE (value) == INTEGER_CST) 796 1.1 mrg { 797 1.1.1.3 mrg char buffer[20]; 798 1.1.1.3 mrg sprintf (buffer, "-O%ld", (long) TREE_INT_CST_LOW (value)); 799 1.1.1.3 mrg vec_safe_push (optimize_args, ggc_strdup (buffer)); 800 1.1.1.3 mrg } 801 1.1.1.3 mrg else if (TREE_CODE (value) == STRING_CST) 802 1.1.1.3 mrg { 803 1.1.1.3 mrg size_t len = TREE_STRING_LENGTH (value); 804 1.1.1.3 mrg const char *p = TREE_STRING_POINTER (value); 805 1.1 mrg 806 1.1.1.3 mrg /* If the user supplied -Oxxx or -fxxx, only allow -Oxxx or -fxxx 807 1.1.1.3 mrg options. */ 808 1.1.1.3 mrg if (*p == '-' && p[1] != 'O' && p[1] != 'f') 809 1.1 mrg { 810 1.1.1.3 mrg ret = false; 811 1.1.1.3 mrg warning (OPT_Wattributes, 812 1.1.1.3 mrg "bad option %qs to attribute %<optimize%>", p); 813 1.1.1.3 mrg continue; 814 1.1 mrg } 815 1.1.1.3 mrg 816 1.1.1.3 mrg /* Can't use GC memory here. */ 817 1.1.1.3 mrg char *q = XOBNEWVEC (&opts_obstack, char, len + 3); 818 1.1.1.3 mrg char *r = q; 819 1.1.1.3 mrg 820 1.1.1.3 mrg if (*p != '-') 821 1.1 mrg { 822 1.1.1.3 mrg *r++ = '-'; 823 1.1.1.3 mrg 824 1.1.1.3 mrg /* Assume that Ox is -Ox, a numeric value is -Ox, a s by 825 1.1.1.3 mrg itself is -Os, and any other switch begins with a -f. */ 826 1.1.1.3 mrg if ((*p >= '0' && *p <= '9') || (p[0] == 's' && p[1] == '\0')) 827 1.1.1.3 mrg *r++ = 'O'; 828 1.1.1.3 mrg else if (*p != 'O') 829 1.1.1.3 mrg *r++ = 'f'; 830 1.1 mrg } 831 1.1.1.3 mrg 832 1.1.1.3 mrg memcpy (r, p, len); 833 1.1.1.3 mrg r[len] = '\0'; 834 1.1.1.3 mrg vec_safe_push (optimize_args, (const char *) q); 835 1.1 mrg } 836 1.1.1.3 mrg } 837 1.1.1.3 mrg 838 1.1.1.3 mrg unsigned opt_argc = optimize_args->length (); 839 1.1.1.3 mrg const char **opt_argv 840 1.1.1.3 mrg = (const char **) alloca (sizeof (char *) * (opt_argc + 1)); 841 1.1.1.3 mrg 842 1.1.1.3 mrg for (unsigned i = 1; i < opt_argc; i++) 843 1.1.1.3 mrg opt_argv[i] = (*optimize_args)[i]; 844 1.1.1.3 mrg 845 1.1.1.3 mrg /* Now parse the options. */ 846 1.1.1.3 mrg struct cl_decoded_option *decoded_options; 847 1.1.1.3 mrg unsigned int decoded_options_count; 848 1.1.1.3 mrg 849 1.1.1.3 mrg decode_cmdline_options_to_array_default_mask (opt_argc, opt_argv, 850 1.1.1.3 mrg &decoded_options, 851 1.1.1.3 mrg &decoded_options_count); 852 1.1.1.3 mrg /* Drop non-Optimization options. */ 853 1.1.1.3 mrg unsigned j = 1; 854 1.1.1.3 mrg for (unsigned i = 1; i < decoded_options_count; ++i) 855 1.1.1.3 mrg { 856 1.1.1.3 mrg unsigned opt_index = decoded_options[i].opt_index; 857 1.1.1.3 mrg if (opt_index >= cl_options_count 858 1.1.1.3 mrg || ! (cl_options[opt_index].flags & CL_OPTIMIZATION)) 859 1.1 mrg { 860 1.1.1.3 mrg ret = false; 861 1.1.1.3 mrg warning (OPT_Wattributes, 862 1.1.1.3 mrg "bad option %qs to attribute %<optimize%>", 863 1.1.1.3 mrg decoded_options[i].orig_option_with_args_text); 864 1.1.1.3 mrg continue; 865 1.1 mrg } 866 1.1.1.3 mrg if (i != j) 867 1.1.1.3 mrg decoded_options[j] = decoded_options[i]; 868 1.1.1.3 mrg j++; 869 1.1.1.3 mrg } 870 1.1.1.3 mrg decoded_options_count = j; 871 1.1.1.3 mrg /* And apply them. */ 872 1.1.1.3 mrg decode_options (&global_options, &global_options_set, 873 1.1.1.3 mrg decoded_options, decoded_options_count, 874 1.1.1.3 mrg input_location, global_dc, NULL); 875 1.1.1.3 mrg 876 1.1.1.3 mrg targetm.override_options_after_change(); 877 1.1.1.3 mrg 878 1.1.1.3 mrg optimize_args->truncate (0); 879 1.1.1.3 mrg return ret; 880 1.1.1.3 mrg } 881 1.1.1.3 mrg 882 1.1.1.3 mrg /* Handle a "optimize" attribute; arguments as in 883 1.1.1.3 mrg struct attribute_spec.handler. */ 884 1.1.1.3 mrg 885 1.1.1.3 mrg static tree 886 1.1.1.3 mrg d_handle_optimize_attribute (tree *node, tree name, tree args, int, 887 1.1.1.3 mrg bool *no_add_attrs) 888 1.1.1.3 mrg { 889 1.1.1.3 mrg /* Ensure we have a function type. */ 890 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 891 1.1.1.3 mrg { 892 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 893 1.1.1.3 mrg *no_add_attrs = true; 894 1.1 mrg } 895 1.1 mrg else 896 1.1 mrg { 897 1.1.1.3 mrg struct cl_optimization cur_opts; 898 1.1.1.3 mrg tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node); 899 1.1.1.3 mrg 900 1.1.1.3 mrg /* Save current options. */ 901 1.1.1.3 mrg cl_optimization_save (&cur_opts, &global_options, &global_options_set); 902 1.1.1.3 mrg tree prev_target_node = build_target_option_node (&global_options, 903 1.1.1.3 mrg &global_options_set); 904 1.1.1.3 mrg 905 1.1.1.3 mrg /* If we previously had some optimization options, use them as the 906 1.1.1.3 mrg default. */ 907 1.1.1.3 mrg gcc_options *saved_global_options = NULL; 908 1.1.1.3 mrg if (flag_checking) 909 1.1.1.3 mrg { 910 1.1.1.3 mrg saved_global_options = XNEW (gcc_options); 911 1.1.1.3 mrg *saved_global_options = global_options; 912 1.1.1.3 mrg } 913 1.1.1.3 mrg 914 1.1.1.3 mrg if (old_opts) 915 1.1.1.3 mrg cl_optimization_restore (&global_options, &global_options_set, 916 1.1.1.3 mrg TREE_OPTIMIZATION (old_opts)); 917 1.1.1.3 mrg 918 1.1.1.3 mrg /* Parse options, and update the vector. */ 919 1.1.1.3 mrg parse_optimize_options (args); 920 1.1.1.3 mrg DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) 921 1.1.1.3 mrg = build_optimization_node (&global_options, &global_options_set); 922 1.1.1.3 mrg tree target_node = build_target_option_node (&global_options, 923 1.1.1.3 mrg &global_options_set); 924 1.1.1.3 mrg if (prev_target_node != target_node) 925 1.1.1.3 mrg DECL_FUNCTION_SPECIFIC_TARGET (*node) = target_node; 926 1.1.1.3 mrg 927 1.1.1.3 mrg /* Restore current options. */ 928 1.1.1.3 mrg cl_optimization_restore (&global_options, &global_options_set, 929 1.1.1.3 mrg &cur_opts); 930 1.1.1.3 mrg cl_target_option_restore (&global_options, &global_options_set, 931 1.1.1.3 mrg TREE_TARGET_OPTION (prev_target_node)); 932 1.1.1.3 mrg if (saved_global_options != NULL) 933 1.1.1.3 mrg { 934 1.1.1.3 mrg cl_optimization_compare (saved_global_options, &global_options); 935 1.1.1.3 mrg free (saved_global_options); 936 1.1.1.3 mrg } 937 1.1.1.3 mrg } 938 1.1.1.3 mrg 939 1.1.1.3 mrg return NULL_TREE; 940 1.1.1.3 mrg } 941 1.1.1.3 mrg 942 1.1.1.3 mrg /* Handle a "noclone" attribute; arguments as in 943 1.1.1.3 mrg struct attribute_spec.handler. */ 944 1.1.1.3 mrg 945 1.1.1.3 mrg static tree 946 1.1.1.3 mrg d_handle_noclone_attribute (tree *node, tree name, tree, int, 947 1.1.1.3 mrg bool *no_add_attrs) 948 1.1.1.3 mrg { 949 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 950 1.1.1.3 mrg { 951 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 952 1.1 mrg *no_add_attrs = true; 953 1.1 mrg } 954 1.1 mrg 955 1.1 mrg return NULL_TREE; 956 1.1 mrg } 957 1.1 mrg 958 1.1.1.3 mrg /* Handle a "no_icf" attribute; arguments as in 959 1.1 mrg struct attribute_spec.handler. */ 960 1.1 mrg 961 1.1 mrg static tree 962 1.1.1.3 mrg d_handle_noicf_attribute (tree *node, tree name, tree, int, 963 1.1.1.3 mrg bool *no_add_attrs) 964 1.1 mrg { 965 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 966 1.1.1.3 mrg { 967 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 968 1.1.1.3 mrg *no_add_attrs = true; 969 1.1.1.3 mrg } 970 1.1.1.3 mrg 971 1.1.1.3 mrg return NULL_TREE; 972 1.1.1.3 mrg } 973 1.1 mrg 974 1.1.1.3 mrg /* Handle a "noipa" attribute; arguments as in 975 1.1.1.3 mrg struct attribute_spec.handler. */ 976 1.1.1.3 mrg 977 1.1.1.3 mrg static tree 978 1.1.1.3 mrg d_handle_noipa_attribute (tree *node, tree name, tree, int, 979 1.1.1.3 mrg bool *no_add_attrs) 980 1.1.1.3 mrg { 981 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 982 1.1 mrg { 983 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 984 1.1 mrg *no_add_attrs = true; 985 1.1.1.3 mrg } 986 1.1.1.3 mrg 987 1.1.1.3 mrg return NULL_TREE; 988 1.1.1.3 mrg } 989 1.1.1.3 mrg 990 1.1.1.3 mrg /* Handle a "section" attribute; arguments as in 991 1.1.1.3 mrg struct attribute_spec.handler. */ 992 1.1.1.3 mrg 993 1.1.1.3 mrg static tree 994 1.1.1.3 mrg d_handle_section_attribute (tree *node, tree name, tree args, int flags, 995 1.1.1.3 mrg bool *no_add_attrs) 996 1.1.1.3 mrg { 997 1.1.1.3 mrg if (!targetm_common.have_named_sections) 998 1.1.1.3 mrg { 999 1.1.1.3 mrg error ("section attributes are not supported for this target"); 1000 1.1.1.3 mrg *no_add_attrs = true; 1001 1.1 mrg return NULL_TREE; 1002 1.1 mrg } 1003 1.1.1.3 mrg 1004 1.1.1.3 mrg if (!VAR_OR_FUNCTION_DECL_P (*node)) 1005 1.1 mrg { 1006 1.1.1.3 mrg error ("section attribute not allowed for %q+D", *node); 1007 1.1 mrg *no_add_attrs = true; 1008 1.1 mrg return NULL_TREE; 1009 1.1 mrg } 1010 1.1.1.3 mrg 1011 1.1.1.3 mrg if (TREE_CODE (TREE_VALUE (args)) != STRING_CST) 1012 1.1 mrg { 1013 1.1.1.3 mrg error ("section attribute argument not a string constant"); 1014 1.1 mrg *no_add_attrs = true; 1015 1.1 mrg return NULL_TREE; 1016 1.1 mrg } 1017 1.1.1.3 mrg 1018 1.1.1.3 mrg if (VAR_P (*node) 1019 1.1.1.3 mrg && current_function_decl != NULL_TREE 1020 1.1.1.3 mrg && !TREE_STATIC (*node)) 1021 1.1 mrg { 1022 1.1.1.3 mrg error ("section attribute cannot be specified for local variables"); 1023 1.1.1.3 mrg *no_add_attrs = true; 1024 1.1.1.3 mrg return NULL_TREE; 1025 1.1.1.3 mrg } 1026 1.1 mrg 1027 1.1.1.3 mrg /* The decl may have already been given a section attribute 1028 1.1.1.3 mrg from a previous declaration. Ensure they match. */ 1029 1.1.1.3 mrg if (DECL_SECTION_NAME (*node) != NULL 1030 1.1.1.3 mrg && strcmp (DECL_SECTION_NAME (*node), 1031 1.1.1.3 mrg TREE_STRING_POINTER (TREE_VALUE (args))) != 0) 1032 1.1.1.3 mrg { 1033 1.1.1.3 mrg error ("section of %q+D conflicts with previous declaration", *node); 1034 1.1.1.3 mrg *no_add_attrs = true; 1035 1.1.1.3 mrg return NULL_TREE; 1036 1.1.1.3 mrg } 1037 1.1.1.3 mrg 1038 1.1.1.3 mrg if (VAR_P (*node) 1039 1.1.1.3 mrg && !targetm.have_tls && targetm.emutls.tmpl_section 1040 1.1.1.3 mrg && DECL_THREAD_LOCAL_P (*node)) 1041 1.1.1.3 mrg { 1042 1.1.1.3 mrg error ("section of %q+D cannot be overridden", *node); 1043 1.1.1.3 mrg *no_add_attrs = true; 1044 1.1.1.3 mrg return NULL_TREE; 1045 1.1.1.3 mrg } 1046 1.1.1.3 mrg 1047 1.1.1.3 mrg tree res = targetm.handle_generic_attribute (node, name, args, flags, 1048 1.1.1.3 mrg no_add_attrs); 1049 1.1.1.3 mrg 1050 1.1.1.3 mrg /* If the back end confirms the attribute can be added then continue onto 1051 1.1.1.3 mrg final processing. */ 1052 1.1.1.3 mrg if (*no_add_attrs) 1053 1.1.1.3 mrg return NULL_TREE; 1054 1.1.1.3 mrg 1055 1.1.1.3 mrg set_decl_section_name (*node, TREE_STRING_POINTER (TREE_VALUE (args))); 1056 1.1.1.3 mrg return res; 1057 1.1.1.3 mrg } 1058 1.1.1.3 mrg 1059 1.1.1.3 mrg /* Handle a "symver" and attribute; arguments as in 1060 1.1.1.3 mrg struct attribute_spec.handler. */ 1061 1.1.1.3 mrg 1062 1.1.1.3 mrg static tree 1063 1.1.1.3 mrg d_handle_symver_attribute (tree *node, tree, tree args, int, bool *no_add_attrs) 1064 1.1.1.3 mrg { 1065 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL) 1066 1.1.1.3 mrg { 1067 1.1.1.3 mrg warning (OPT_Wattributes, 1068 1.1.1.3 mrg "%<symver%> attribute only applies to functions and variables"); 1069 1.1.1.3 mrg *no_add_attrs = true; 1070 1.1.1.3 mrg return NULL_TREE; 1071 1.1.1.3 mrg } 1072 1.1.1.3 mrg 1073 1.1.1.3 mrg if (!decl_in_symtab_p (*node)) 1074 1.1.1.3 mrg { 1075 1.1.1.3 mrg warning (OPT_Wattributes, 1076 1.1.1.3 mrg "%<symver%> attribute is only applicable to symbols"); 1077 1.1.1.3 mrg *no_add_attrs = true; 1078 1.1.1.3 mrg return NULL_TREE; 1079 1.1.1.3 mrg } 1080 1.1.1.3 mrg 1081 1.1.1.3 mrg for (; args; args = TREE_CHAIN (args)) 1082 1.1.1.3 mrg { 1083 1.1.1.3 mrg tree symver = TREE_VALUE (args); 1084 1.1.1.3 mrg if (TREE_CODE (symver) != STRING_CST) 1085 1.1 mrg { 1086 1.1.1.3 mrg error ("%<symver%> attribute argument not a string constant"); 1087 1.1 mrg *no_add_attrs = true; 1088 1.1 mrg return NULL_TREE; 1089 1.1 mrg } 1090 1.1 mrg 1091 1.1.1.3 mrg const char *symver_str = TREE_STRING_POINTER (symver); 1092 1.1 mrg 1093 1.1.1.3 mrg int ats = 0; 1094 1.1.1.3 mrg for (int n = 0; (int)n < TREE_STRING_LENGTH (symver); n++) 1095 1.1.1.3 mrg if (symver_str[n] == '@') 1096 1.1.1.3 mrg ats++; 1097 1.1.1.3 mrg 1098 1.1.1.3 mrg if (ats != 1 && ats != 2) 1099 1.1.1.3 mrg { 1100 1.1.1.3 mrg error ("symver attribute argument must have format %<name@nodename%>"); 1101 1.1.1.3 mrg error ("%<symver%> attribute argument %qs must contain one or two " 1102 1.1.1.3 mrg "%<@%>", symver_str); 1103 1.1.1.3 mrg *no_add_attrs = true; 1104 1.1.1.3 mrg return NULL_TREE; 1105 1.1.1.3 mrg } 1106 1.1 mrg } 1107 1.1.1.3 mrg 1108 1.1.1.3 mrg return NULL_TREE; 1109 1.1 mrg } 1110 1.1 mrg 1111 1.1 mrg /* Handle a "weak" attribute; arguments as in 1112 1.1 mrg struct attribute_spec.handler. */ 1113 1.1 mrg 1114 1.1 mrg static tree 1115 1.1.1.3 mrg d_handle_weak_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) 1116 1.1 mrg { 1117 1.1 mrg if (TREE_CODE (*node) == FUNCTION_DECL 1118 1.1 mrg && DECL_DECLARED_INLINE_P (*node)) 1119 1.1 mrg { 1120 1.1 mrg warning (OPT_Wattributes, "inline function %q+D declared weak", *node); 1121 1.1 mrg *no_add_attrs = true; 1122 1.1 mrg } 1123 1.1 mrg else if (VAR_OR_FUNCTION_DECL_P (*node)) 1124 1.1 mrg { 1125 1.1 mrg struct symtab_node *n = symtab_node::get (*node); 1126 1.1 mrg if (n && n->refuse_visibility_changes) 1127 1.1 mrg error ("%q+D declared weak after being used", *node); 1128 1.1 mrg declare_weak (*node); 1129 1.1 mrg } 1130 1.1 mrg else 1131 1.1 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 1132 1.1 mrg 1133 1.1 mrg return NULL_TREE; 1134 1.1 mrg } 1135 1.1 mrg 1136 1.1.1.3 mrg /* Handle a "noplt" attribute; arguments as in 1137 1.1.1.3 mrg struct attribute_spec.handler. */ 1138 1.1.1.3 mrg 1139 1.1.1.3 mrg static tree 1140 1.1.1.3 mrg d_handle_noplt_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) 1141 1.1.1.3 mrg { 1142 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 1143 1.1.1.3 mrg { 1144 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 1145 1.1.1.3 mrg *no_add_attrs = true; 1146 1.1.1.3 mrg } 1147 1.1.1.3 mrg 1148 1.1.1.3 mrg return NULL_TREE; 1149 1.1.1.3 mrg } 1150 1.1.1.3 mrg 1151 1.1.1.3 mrg /* Verify that argument value POS at position ARGNO to attribute ATNAME applied 1152 1.1.1.3 mrg to function FNTYPE refers to a function parameter at position POS and is a 1153 1.1.1.3 mrg valid integer type. When ZERO_BASED is true, POS is adjusted to be 1-based. 1154 1.1.1.3 mrg If successful, POS is returned. Otherwise, issue appropriate warnings and 1155 1.1.1.3 mrg return null. A non-zero 1-based ARGNO should be passed in by callers only 1156 1.1.1.3 mrg for attributes with more than one argument. */ 1157 1.1.1.3 mrg 1158 1.1.1.3 mrg static tree 1159 1.1.1.3 mrg positional_argument (const_tree fntype, const_tree atname, tree pos, 1160 1.1.1.3 mrg int argno, bool zero_based) 1161 1.1.1.3 mrg { 1162 1.1.1.3 mrg tree postype = TREE_TYPE (pos); 1163 1.1.1.3 mrg 1164 1.1.1.3 mrg if (pos == error_mark_node || !postype) 1165 1.1.1.3 mrg { 1166 1.1.1.3 mrg /* Only mention the positional argument number when it's non-zero. */ 1167 1.1.1.3 mrg if (argno < 1) 1168 1.1.1.3 mrg warning (OPT_Wattributes, 1169 1.1.1.3 mrg "%qE attribute argument is invalid", atname); 1170 1.1.1.3 mrg else 1171 1.1.1.3 mrg warning (OPT_Wattributes, 1172 1.1.1.3 mrg "%qE attribute argument %i is invalid", atname, argno); 1173 1.1.1.3 mrg 1174 1.1.1.3 mrg return NULL_TREE; 1175 1.1.1.3 mrg } 1176 1.1.1.3 mrg 1177 1.1.1.3 mrg if (!INTEGRAL_TYPE_P (postype)) 1178 1.1.1.3 mrg { 1179 1.1.1.3 mrg /* Handle this case specially to avoid mentioning the value 1180 1.1.1.3 mrg of pointer constants in diagnostics. Only mention 1181 1.1.1.3 mrg the positional argument number when it's non-zero. */ 1182 1.1.1.3 mrg if (argno < 1) 1183 1.1.1.3 mrg warning (OPT_Wattributes, 1184 1.1.1.3 mrg "%qE attribute argument has type %qT", 1185 1.1.1.3 mrg atname, postype); 1186 1.1.1.3 mrg else 1187 1.1.1.3 mrg warning (OPT_Wattributes, 1188 1.1.1.3 mrg "%qE attribute argument %i has type %qT", 1189 1.1.1.3 mrg atname, argno, postype); 1190 1.1.1.3 mrg 1191 1.1.1.3 mrg return NULL_TREE; 1192 1.1.1.3 mrg } 1193 1.1.1.3 mrg 1194 1.1.1.3 mrg if (TREE_CODE (pos) != INTEGER_CST) 1195 1.1.1.3 mrg { 1196 1.1.1.3 mrg /* Only mention the argument number when it's non-zero. */ 1197 1.1.1.3 mrg if (argno < 1) 1198 1.1.1.3 mrg warning (OPT_Wattributes, 1199 1.1.1.3 mrg "%qE attribute argument value %qE is not an integer " 1200 1.1.1.3 mrg "constant", 1201 1.1.1.3 mrg atname, pos); 1202 1.1.1.3 mrg else 1203 1.1.1.3 mrg warning (OPT_Wattributes, 1204 1.1.1.3 mrg "%qE attribute argument %i value %qE is not an integer " 1205 1.1.1.3 mrg "constant", 1206 1.1.1.3 mrg atname, argno, pos); 1207 1.1.1.3 mrg 1208 1.1.1.3 mrg return NULL_TREE; 1209 1.1.1.3 mrg } 1210 1.1.1.3 mrg 1211 1.1.1.3 mrg /* Validate the value of the position argument. If 0-based, then it should 1212 1.1.1.3 mrg not be negative. If 1-based, it should be greater than zero. */ 1213 1.1.1.3 mrg if ((zero_based && tree_int_cst_sgn (pos) < 0) 1214 1.1.1.3 mrg || (!zero_based && tree_int_cst_sgn (pos) < 1)) 1215 1.1.1.3 mrg { 1216 1.1.1.3 mrg if (argno < 1) 1217 1.1.1.3 mrg warning (OPT_Wattributes, 1218 1.1.1.3 mrg "%qE attribute argument value %qE does not refer to " 1219 1.1.1.3 mrg "a function parameter", 1220 1.1.1.3 mrg atname, pos); 1221 1.1.1.3 mrg else 1222 1.1.1.3 mrg warning (OPT_Wattributes, 1223 1.1.1.3 mrg "%qE attribute argument %i value %qE does not refer to " 1224 1.1.1.3 mrg "a function parameter", 1225 1.1.1.3 mrg atname, argno, pos); 1226 1.1.1.3 mrg 1227 1.1.1.3 mrg return NULL_TREE; 1228 1.1.1.3 mrg } 1229 1.1.1.3 mrg 1230 1.1.1.3 mrg /* Adjust the value of pos to be 1-based. */ 1231 1.1.1.3 mrg tree adjusted_pos = (zero_based) 1232 1.1.1.3 mrg ? int_const_binop (PLUS_EXPR, pos, integer_one_node) : pos; 1233 1.1.1.3 mrg 1234 1.1.1.3 mrg if (!prototype_p (fntype)) 1235 1.1.1.3 mrg return adjusted_pos; 1236 1.1.1.3 mrg 1237 1.1.1.3 mrg /* Verify that the argument position does not exceed the number 1238 1.1.1.3 mrg of formal arguments to the function. */ 1239 1.1.1.3 mrg unsigned nargs = type_num_arguments (fntype); 1240 1.1.1.3 mrg if (!nargs 1241 1.1.1.3 mrg || !tree_fits_uhwi_p (adjusted_pos) 1242 1.1.1.3 mrg || !IN_RANGE (tree_to_uhwi (adjusted_pos), 1, nargs)) 1243 1.1.1.3 mrg { 1244 1.1.1.3 mrg if (argno < 1) 1245 1.1.1.3 mrg warning (OPT_Wattributes, 1246 1.1.1.3 mrg "%qE attribute argument value %qE exceeds the number " 1247 1.1.1.3 mrg "of function parameters %u", 1248 1.1.1.3 mrg atname, pos, nargs); 1249 1.1.1.3 mrg else 1250 1.1.1.3 mrg warning (OPT_Wattributes, 1251 1.1.1.3 mrg "%qE attribute argument %i value %qE exceeds the number " 1252 1.1.1.3 mrg "of function parameters %u", 1253 1.1.1.3 mrg atname, argno, pos, nargs); 1254 1.1.1.3 mrg 1255 1.1.1.3 mrg return NULL_TREE; 1256 1.1.1.3 mrg } 1257 1.1.1.3 mrg 1258 1.1.1.3 mrg /* Verify that the type of the referenced formal argument matches 1259 1.1.1.3 mrg the expected type. */ 1260 1.1.1.3 mrg unsigned HOST_WIDE_INT ipos = tree_to_uhwi (adjusted_pos); 1261 1.1.1.3 mrg 1262 1.1.1.3 mrg /* Zero was handled above. */ 1263 1.1.1.3 mrg gcc_assert (ipos != 0); 1264 1.1.1.3 mrg 1265 1.1.1.3 mrg if (tree argtype = type_argument_type (fntype, ipos)) 1266 1.1.1.3 mrg { 1267 1.1.1.3 mrg /* Accept types that match INTEGRAL_TYPE_P except for bool. */ 1268 1.1.1.3 mrg if (!INTEGRAL_TYPE_P (argtype) || TREE_CODE (argtype) == BOOLEAN_TYPE) 1269 1.1.1.3 mrg { 1270 1.1.1.3 mrg if (argno < 1) 1271 1.1.1.3 mrg warning (OPT_Wattributes, 1272 1.1.1.3 mrg "%qE attribute argument value %qE refers to " 1273 1.1.1.3 mrg "parameter type %qT", 1274 1.1.1.3 mrg atname, pos, argtype); 1275 1.1.1.3 mrg else 1276 1.1.1.3 mrg warning (OPT_Wattributes, 1277 1.1.1.3 mrg "%qE attribute argument %i value %qE refers to " 1278 1.1.1.3 mrg "parameter type %qT", 1279 1.1.1.3 mrg atname, argno, pos, argtype); 1280 1.1.1.3 mrg 1281 1.1.1.3 mrg return NULL_TREE; 1282 1.1.1.3 mrg } 1283 1.1.1.3 mrg 1284 1.1.1.3 mrg return adjusted_pos; 1285 1.1.1.3 mrg } 1286 1.1.1.3 mrg 1287 1.1.1.3 mrg /* Argument position exceeding number of parameters was handled above. */ 1288 1.1.1.3 mrg gcc_unreachable (); 1289 1.1.1.3 mrg } 1290 1.1.1.3 mrg 1291 1.1.1.3 mrg /* Handle a "alloc_size" attribute; arguments as in 1292 1.1.1.3 mrg struct attribute_spec.handler. */ 1293 1.1.1.3 mrg 1294 1.1.1.3 mrg static tree 1295 1.1.1.3 mrg d_handle_alloc_size_attribute (tree *node, tree name, tree args, int, 1296 1.1.1.3 mrg bool *no_add_attrs) 1297 1.1.1.3 mrg { 1298 1.1.1.3 mrg tree fntype = *node; 1299 1.1.1.3 mrg tree rettype = TREE_TYPE (fntype); 1300 1.1.1.3 mrg if (!POINTER_TYPE_P (rettype)) 1301 1.1.1.3 mrg { 1302 1.1.1.3 mrg warning (OPT_Wattributes, 1303 1.1.1.3 mrg "%qE attribute ignored on a function returning %qT", 1304 1.1.1.3 mrg name, rettype); 1305 1.1.1.3 mrg *no_add_attrs = true; 1306 1.1.1.3 mrg return NULL_TREE; 1307 1.1.1.3 mrg } 1308 1.1.1.3 mrg 1309 1.1.1.3 mrg /* The first argument SIZE_ARG is never null. */ 1310 1.1.1.3 mrg tree size_arg = TREE_VALUE (args); 1311 1.1.1.3 mrg tree next = TREE_CHAIN (args); 1312 1.1.1.3 mrg 1313 1.1.1.3 mrg /* NUM_ARG is null when the attribute includes just one argument, or is 1314 1.1.1.3 mrg explictly set to null if it has been left uninitialized by the caller. */ 1315 1.1.1.3 mrg tree num_arg = NULL_TREE; 1316 1.1.1.3 mrg if (next != NULL_TREE) 1317 1.1.1.3 mrg { 1318 1.1.1.3 mrg if (TREE_VALUE (next) != TYPE_MIN_VALUE (d_int_type)) 1319 1.1.1.3 mrg num_arg = TREE_VALUE (next); 1320 1.1.1.3 mrg 1321 1.1.1.3 mrg next = TREE_CHAIN (next); 1322 1.1.1.3 mrg } 1323 1.1.1.3 mrg 1324 1.1.1.3 mrg /* If ZERO_ARG is set and true, arguments positions are treated as 0-based. 1325 1.1.1.3 mrg Otherwise the default is 1-based. */ 1326 1.1.1.3 mrg bool zero_based = false; 1327 1.1.1.3 mrg if (next != NULL_TREE) 1328 1.1.1.3 mrg zero_based = integer_truep (TREE_VALUE (next)); 1329 1.1.1.3 mrg 1330 1.1.1.3 mrg /* Update the argument values with the real argument position. */ 1331 1.1.1.3 mrg if (tree val = positional_argument (fntype, name, size_arg, num_arg ? 1 : 0, 1332 1.1.1.3 mrg zero_based)) 1333 1.1.1.3 mrg TREE_VALUE (args) = val; 1334 1.1.1.3 mrg else 1335 1.1.1.3 mrg *no_add_attrs = true; 1336 1.1.1.3 mrg 1337 1.1.1.3 mrg if (num_arg != NULL_TREE) 1338 1.1.1.3 mrg { 1339 1.1.1.3 mrg args = TREE_CHAIN (args); 1340 1.1.1.3 mrg if (tree val = positional_argument (fntype, name, num_arg, 2, zero_based)) 1341 1.1.1.3 mrg TREE_VALUE (args) = val; 1342 1.1.1.3 mrg else 1343 1.1.1.3 mrg *no_add_attrs = true; 1344 1.1.1.3 mrg } 1345 1.1.1.3 mrg 1346 1.1.1.3 mrg /* Terminate the original TREE_CHAIN in `args' to remove any remaining 1347 1.1.1.3 mrg D-specific `alloc_size` arguments. */ 1348 1.1.1.3 mrg TREE_CHAIN (args) = NULL_TREE; 1349 1.1.1.3 mrg 1350 1.1.1.3 mrg return NULL_TREE; 1351 1.1.1.3 mrg } 1352 1.1.1.3 mrg 1353 1.1.1.3 mrg /* Handle a "cold" and attribute; arguments as in 1354 1.1.1.3 mrg struct attribute_spec.handler. */ 1355 1.1.1.3 mrg 1356 1.1.1.3 mrg static tree 1357 1.1.1.3 mrg d_handle_cold_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) 1358 1.1.1.3 mrg { 1359 1.1.1.3 mrg if (TREE_CODE (*node) != FUNCTION_DECL) 1360 1.1.1.3 mrg { 1361 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 1362 1.1.1.3 mrg *no_add_attrs = true; 1363 1.1.1.3 mrg } 1364 1.1.1.3 mrg 1365 1.1.1.3 mrg return NULL_TREE; 1366 1.1.1.3 mrg } 1367 1.1.1.3 mrg 1368 1.1.1.3 mrg /* Handle a "restrict" attribute; arguments as in 1369 1.1.1.3 mrg struct attribute_spec.handler. */ 1370 1.1.1.3 mrg 1371 1.1.1.3 mrg static tree 1372 1.1.1.3 mrg d_handle_restrict_attribute (tree *node, tree name, tree, int, 1373 1.1.1.3 mrg bool *no_add_attrs) 1374 1.1.1.3 mrg { 1375 1.1.1.3 mrg if (TREE_CODE (*node) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (*node))) 1376 1.1.1.3 mrg { 1377 1.1.1.3 mrg TREE_TYPE (*node) = build_qualified_type (TREE_TYPE (*node), 1378 1.1.1.3 mrg TYPE_QUAL_RESTRICT); 1379 1.1.1.3 mrg } 1380 1.1.1.3 mrg else 1381 1.1.1.3 mrg { 1382 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 1383 1.1.1.3 mrg *no_add_attrs = true; 1384 1.1.1.3 mrg } 1385 1.1.1.3 mrg 1386 1.1.1.3 mrg return NULL_TREE; 1387 1.1.1.3 mrg } 1388 1.1.1.3 mrg 1389 1.1.1.3 mrg /* Handle a "used" attribute; arguments as in 1390 1.1.1.3 mrg struct attribute_spec.handler. */ 1391 1.1.1.3 mrg 1392 1.1.1.3 mrg static tree 1393 1.1.1.3 mrg d_handle_used_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) 1394 1.1.1.3 mrg { 1395 1.1.1.3 mrg if (TREE_CODE (*node) == FUNCTION_DECL 1396 1.1.1.3 mrg || (VAR_P (*node) && TREE_STATIC (*node)) 1397 1.1.1.3 mrg || (TREE_CODE (*node) == TYPE_DECL)) 1398 1.1.1.3 mrg { 1399 1.1.1.3 mrg TREE_USED (*node) = 1; 1400 1.1.1.3 mrg DECL_PRESERVE_P (*node) = 1; 1401 1.1.1.3 mrg if (VAR_P (*node)) 1402 1.1.1.3 mrg DECL_READ_P (*node) = 1; 1403 1.1.1.3 mrg } 1404 1.1.1.3 mrg else 1405 1.1.1.3 mrg { 1406 1.1.1.3 mrg warning (OPT_Wattributes, "%qE attribute ignored", name); 1407 1.1.1.3 mrg *no_add_attrs = true; 1408 1.1.1.3 mrg } 1409 1.1.1.3 mrg 1410 1.1.1.3 mrg return NULL_TREE; 1411 1.1.1.3 mrg } 1412