comparison gcc/c-family/c-attribs.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* C-family attributes handling. 1 /* C-family attributes handling.
2 Copyright (C) 1992-2017 Free Software Foundation, Inc. 2 Copyright (C) 1992-2018 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free 7 the terms of the GNU General Public License as published by the Free
141 bool *); 141 bool *);
142 static tree handle_simd_attribute (tree *, tree, tree, int, bool *); 142 static tree handle_simd_attribute (tree *, tree, tree, int, bool *);
143 static tree handle_omp_declare_target_attribute (tree *, tree, tree, int, 143 static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
144 bool *); 144 bool *);
145 static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *); 145 static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *);
146 static tree handle_bnd_variable_size_attribute (tree *, tree, tree, int, bool *);
147 static tree handle_bnd_legacy (tree *, tree, tree, int, bool *);
148 static tree handle_bnd_instrument (tree *, tree, tree, int, bool *);
149 static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *); 146 static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
150 static tree handle_patchable_function_entry_attribute (tree *, tree, tree, 147 static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
151 int, bool *); 148 int, bool *);
152 149
150 /* Helper to define attribute exclusions. */
151 #define ATTR_EXCL(name, function, type, variable) \
152 { name, function, type, variable }
153
154 /* Define attributes that are mutually exclusive with one another. */
155 static const struct attribute_spec::exclusions attr_aligned_exclusions[] =
156 {
157 /* Attribute name exclusion applies to:
158 function, type, variable */
159 ATTR_EXCL ("aligned", true, false, false),
160 ATTR_EXCL ("packed", true, false, false),
161 ATTR_EXCL (NULL, false, false, false)
162 };
163
164 static const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
165 {
166 ATTR_EXCL ("cold", true, true, true),
167 ATTR_EXCL ("hot", true, true, true),
168 ATTR_EXCL (NULL, false, false, false)
169 };
170
171 static const struct attribute_spec::exclusions attr_common_exclusions[] =
172 {
173 ATTR_EXCL ("common", true, true, true),
174 ATTR_EXCL ("nocommon", true, true, true),
175 ATTR_EXCL (NULL, false, false, false),
176 };
177
178 static const struct attribute_spec::exclusions attr_inline_exclusions[] =
179 {
180 ATTR_EXCL ("noinline", true, true, true),
181 ATTR_EXCL (NULL, false, false, false),
182 };
183
184 static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
185 {
186 ATTR_EXCL ("always_inline", true, true, true),
187 ATTR_EXCL ("gnu_inline", true, true, true),
188 ATTR_EXCL (NULL, false, false, false),
189 };
190
191 static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
192 {
193 ATTR_EXCL ("alloc_align", true, true, true),
194 ATTR_EXCL ("alloc_size", true, true, true),
195 ATTR_EXCL ("const", true, true, true),
196 ATTR_EXCL ("malloc", true, true, true),
197 ATTR_EXCL ("pure", true, true, true),
198 ATTR_EXCL ("returns_twice", true, true, true),
199 ATTR_EXCL ("warn_unused_result", true, true, true),
200 ATTR_EXCL (NULL, false, false, false),
201 };
202
203 static const struct attribute_spec::exclusions
204 attr_warn_unused_result_exclusions[] =
205 {
206 ATTR_EXCL ("noreturn", true, true, true),
207 ATTR_EXCL ("warn_unused_result", true, true, true),
208 ATTR_EXCL (NULL, false, false, false),
209 };
210
211 static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
212 {
213 ATTR_EXCL ("noreturn", true, true, true),
214 ATTR_EXCL (NULL, false, false, false),
215 };
216
217 /* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */
218 static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
219 {
220 ATTR_EXCL ("const", true, true, true),
221 ATTR_EXCL ("noreturn", true, true, true),
222 ATTR_EXCL ("pure", true, true, true),
223 ATTR_EXCL (NULL, false, false, false),
224 };
225
226 static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
227 {
228 ATTR_EXCL ("const", true, true, true),
229 ATTR_EXCL ("alloc_align", true, true, true),
230 ATTR_EXCL ("alloc_size", true, true, true),
231 ATTR_EXCL ("malloc", true, true, true),
232 ATTR_EXCL ("noreturn", true, true, true),
233 ATTR_EXCL ("pure", true, true, true),
234 ATTR_EXCL (NULL, false, false, false)
235 };
236
153 /* Table of machine-independent attributes common to all C-like languages. 237 /* Table of machine-independent attributes common to all C-like languages.
154 238
155 All attributes referencing arguments should be additionally processed
156 in chkp_copy_function_type_adding_bounds for correct instrumentation
157 by Pointer Bounds Checker.
158 Current list of processed common attributes: nonnull. */ 239 Current list of processed common attributes: nonnull. */
159 const struct attribute_spec c_common_attribute_table[] = 240 const struct attribute_spec c_common_attribute_table[] =
160 { 241 {
161 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, 242 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
162 affects_type_identity } */ 243 affects_type_identity, handler, exclude } */
163 { "packed", 0, 0, false, false, false, 244 { "packed", 0, 0, false, false, false, false,
164 handle_packed_attribute , false}, 245 handle_packed_attribute,
165 { "nocommon", 0, 0, true, false, false, 246 attr_aligned_exclusions },
166 handle_nocommon_attribute, false}, 247 { "nocommon", 0, 0, true, false, false, false,
167 { "common", 0, 0, true, false, false, 248 handle_nocommon_attribute,
168 handle_common_attribute, false }, 249 attr_common_exclusions },
250 { "common", 0, 0, true, false, false, false,
251 handle_common_attribute,
252 attr_common_exclusions },
169 /* FIXME: logically, noreturn attributes should be listed as 253 /* FIXME: logically, noreturn attributes should be listed as
170 "false, true, true" and apply to function types. But implementing this 254 "false, true, true" and apply to function types. But implementing this
171 would require all the places in the compiler that use TREE_THIS_VOLATILE 255 would require all the places in the compiler that use TREE_THIS_VOLATILE
172 on a decl to identify non-returning functions to be located and fixed 256 on a decl to identify non-returning functions to be located and fixed
173 to check the function type instead. */ 257 to check the function type instead. */
174 { "noreturn", 0, 0, true, false, false, 258 { "noreturn", 0, 0, true, false, false, false,
175 handle_noreturn_attribute, false }, 259 handle_noreturn_attribute,
176 { "volatile", 0, 0, true, false, false, 260 attr_noreturn_exclusions },
177 handle_noreturn_attribute, false }, 261 { "volatile", 0, 0, true, false, false, false,
178 { "stack_protect", 0, 0, true, false, false, 262 handle_noreturn_attribute, NULL },
179 handle_stack_protect_attribute, false }, 263 { "stack_protect", 0, 0, true, false, false, false,
180 { "noinline", 0, 0, true, false, false, 264 handle_stack_protect_attribute, NULL },
181 handle_noinline_attribute, false }, 265 { "noinline", 0, 0, true, false, false, false,
182 { "noclone", 0, 0, true, false, false, 266 handle_noinline_attribute,
183 handle_noclone_attribute, false }, 267 attr_noinline_exclusions },
184 { "no_icf", 0, 0, true, false, false, 268 { "noclone", 0, 0, true, false, false, false,
185 handle_noicf_attribute, false }, 269 handle_noclone_attribute, NULL },
186 { "noipa", 0, 0, true, false, false, 270 { "no_icf", 0, 0, true, false, false, false,
187 handle_noipa_attribute, false }, 271 handle_noicf_attribute, NULL },
188 { "leaf", 0, 0, true, false, false, 272 { "noipa", 0, 0, true, false, false, false,
189 handle_leaf_attribute, false }, 273 handle_noipa_attribute, NULL },
190 { "always_inline", 0, 0, true, false, false, 274 { "leaf", 0, 0, true, false, false, false,
191 handle_always_inline_attribute, false }, 275 handle_leaf_attribute, NULL },
192 { "gnu_inline", 0, 0, true, false, false, 276 { "always_inline", 0, 0, true, false, false, false,
193 handle_gnu_inline_attribute, false }, 277 handle_always_inline_attribute,
194 { "artificial", 0, 0, true, false, false, 278 attr_inline_exclusions },
195 handle_artificial_attribute, false }, 279 { "gnu_inline", 0, 0, true, false, false, false,
196 { "flatten", 0, 0, true, false, false, 280 handle_gnu_inline_attribute,
197 handle_flatten_attribute, false }, 281 attr_inline_exclusions },
198 { "used", 0, 0, true, false, false, 282 { "artificial", 0, 0, true, false, false, false,
199 handle_used_attribute, false }, 283 handle_artificial_attribute, NULL },
200 { "unused", 0, 0, false, false, false, 284 { "flatten", 0, 0, true, false, false, false,
201 handle_unused_attribute, false }, 285 handle_flatten_attribute, NULL },
202 { "externally_visible", 0, 0, true, false, false, 286 { "used", 0, 0, true, false, false, false,
203 handle_externally_visible_attribute, false }, 287 handle_used_attribute, NULL },
204 { "no_reorder", 0, 0, true, false, false, 288 { "unused", 0, 0, false, false, false, false,
205 handle_no_reorder_attribute, false }, 289 handle_unused_attribute, NULL },
290 { "externally_visible", 0, 0, true, false, false, false,
291 handle_externally_visible_attribute, NULL },
292 { "no_reorder", 0, 0, true, false, false, false,
293 handle_no_reorder_attribute, NULL },
206 /* The same comments as for noreturn attributes apply to const ones. */ 294 /* The same comments as for noreturn attributes apply to const ones. */
207 { "const", 0, 0, true, false, false, 295 { "const", 0, 0, true, false, false, false,
208 handle_const_attribute, false }, 296 handle_const_attribute,
209 { "scalar_storage_order", 1, 1, false, false, false, 297 attr_const_pure_exclusions },
210 handle_scalar_storage_order_attribute, false }, 298 { "scalar_storage_order", 1, 1, false, false, false, false,
211 { "transparent_union", 0, 0, false, false, false, 299 handle_scalar_storage_order_attribute, NULL },
212 handle_transparent_union_attribute, false }, 300 { "transparent_union", 0, 0, false, false, false, false,
213 { "constructor", 0, 1, true, false, false, 301 handle_transparent_union_attribute, NULL },
214 handle_constructor_attribute, false }, 302 { "constructor", 0, 1, true, false, false, false,
215 { "destructor", 0, 1, true, false, false, 303 handle_constructor_attribute, NULL },
216 handle_destructor_attribute, false }, 304 { "destructor", 0, 1, true, false, false, false,
217 { "mode", 1, 1, false, true, false, 305 handle_destructor_attribute, NULL },
218 handle_mode_attribute, false }, 306 { "mode", 1, 1, false, true, false, false,
219 { "section", 1, 1, true, false, false, 307 handle_mode_attribute, NULL },
220 handle_section_attribute, false }, 308 { "section", 1, 1, true, false, false, false,
221 { "aligned", 0, 1, false, false, false, 309 handle_section_attribute, NULL },
222 handle_aligned_attribute, false }, 310 { "aligned", 0, 1, false, false, false, false,
223 { "warn_if_not_aligned", 0, 1, false, false, false, 311 handle_aligned_attribute,
224 handle_warn_if_not_aligned_attribute, 312 attr_aligned_exclusions },
225 false }, 313 { "warn_if_not_aligned", 0, 1, false, false, false, false,
226 { "weak", 0, 0, true, false, false, 314 handle_warn_if_not_aligned_attribute, NULL },
227 handle_weak_attribute, false }, 315 { "weak", 0, 0, true, false, false, false,
228 { "noplt", 0, 0, true, false, false, 316 handle_weak_attribute, NULL },
229 handle_noplt_attribute, false }, 317 { "noplt", 0, 0, true, false, false, false,
230 { "ifunc", 1, 1, true, false, false, 318 handle_noplt_attribute, NULL },
231 handle_ifunc_attribute, false }, 319 { "ifunc", 1, 1, true, false, false, false,
232 { "alias", 1, 1, true, false, false, 320 handle_ifunc_attribute, NULL },
233 handle_alias_attribute, false }, 321 { "alias", 1, 1, true, false, false, false,
234 { "weakref", 0, 1, true, false, false, 322 handle_alias_attribute, NULL },
235 handle_weakref_attribute, false }, 323 { "weakref", 0, 1, true, false, false, false,
236 { "no_instrument_function", 0, 0, true, false, false, 324 handle_weakref_attribute, NULL },
325 { "no_instrument_function", 0, 0, true, false, false, false,
237 handle_no_instrument_function_attribute, 326 handle_no_instrument_function_attribute,
238 false }, 327 NULL },
239 { "no_profile_instrument_function", 0, 0, true, false, false, 328 { "no_profile_instrument_function", 0, 0, true, false, false, false,
240 handle_no_profile_instrument_function_attribute, 329 handle_no_profile_instrument_function_attribute,
241 false }, 330 NULL },
242 { "malloc", 0, 0, true, false, false, 331 { "malloc", 0, 0, true, false, false, false,
243 handle_malloc_attribute, false }, 332 handle_malloc_attribute, attr_alloc_exclusions },
244 { "returns_twice", 0, 0, true, false, false, 333 { "returns_twice", 0, 0, true, false, false, false,
245 handle_returns_twice_attribute, false }, 334 handle_returns_twice_attribute,
246 { "no_stack_limit", 0, 0, true, false, false, 335 attr_returns_twice_exclusions },
247 handle_no_limit_stack_attribute, false }, 336 { "no_stack_limit", 0, 0, true, false, false, false,
248 { "pure", 0, 0, true, false, false, 337 handle_no_limit_stack_attribute, NULL },
249 handle_pure_attribute, false }, 338 { "pure", 0, 0, true, false, false, false,
250 { "transaction_callable", 0, 0, false, true, false, 339 handle_pure_attribute,
251 handle_tm_attribute, false }, 340 attr_const_pure_exclusions },
252 { "transaction_unsafe", 0, 0, false, true, false, 341 { "transaction_callable", 0, 0, false, true, false, false,
253 handle_tm_attribute, true }, 342 handle_tm_attribute, NULL },
254 { "transaction_safe", 0, 0, false, true, false, 343 { "transaction_unsafe", 0, 0, false, true, false, true,
255 handle_tm_attribute, true }, 344 handle_tm_attribute, NULL },
256 { "transaction_safe_dynamic", 0, 0, true, false, false, 345 { "transaction_safe", 0, 0, false, true, false, true,
257 handle_tm_attribute, false }, 346 handle_tm_attribute, NULL },
258 { "transaction_may_cancel_outer", 0, 0, false, true, false, 347 { "transaction_safe_dynamic", 0, 0, true, false, false, false,
259 handle_tm_attribute, false }, 348 handle_tm_attribute, NULL },
349 { "transaction_may_cancel_outer", 0, 0, false, true, false, false,
350 handle_tm_attribute, NULL },
260 /* ??? These two attributes didn't make the transition from the 351 /* ??? These two attributes didn't make the transition from the
261 Intel language document to the multi-vendor language document. */ 352 Intel language document to the multi-vendor language document. */
262 { "transaction_pure", 0, 0, false, true, false, 353 { "transaction_pure", 0, 0, false, true, false, false,
263 handle_tm_attribute, false }, 354 handle_tm_attribute, NULL },
264 { "transaction_wrap", 1, 1, true, false, false, 355 { "transaction_wrap", 1, 1, true, false, false, false,
265 handle_tm_wrap_attribute, false }, 356 handle_tm_wrap_attribute, NULL },
266 /* For internal use (marking of builtins) only. The name contains space 357 /* For internal use (marking of builtins) only. The name contains space
267 to prevent its usage in source code. */ 358 to prevent its usage in source code. */
268 { "no vops", 0, 0, true, false, false, 359 { "no vops", 0, 0, true, false, false, false,
269 handle_novops_attribute, false }, 360 handle_novops_attribute, NULL },
270 { "deprecated", 0, 1, false, false, false, 361 { "deprecated", 0, 1, false, false, false, false,
271 handle_deprecated_attribute, false }, 362 handle_deprecated_attribute, NULL },
272 { "vector_size", 1, 1, false, true, false, 363 { "vector_size", 1, 1, false, true, false, true,
273 handle_vector_size_attribute, true }, 364 handle_vector_size_attribute, NULL },
274 { "visibility", 1, 1, false, false, false, 365 { "visibility", 1, 1, false, false, false, false,
275 handle_visibility_attribute, false }, 366 handle_visibility_attribute, NULL },
276 { "tls_model", 1, 1, true, false, false, 367 { "tls_model", 1, 1, true, false, false, false,
277 handle_tls_model_attribute, false }, 368 handle_tls_model_attribute, NULL },
278 { "nonnull", 0, -1, false, true, true, 369 { "nonnull", 0, -1, false, true, true, false,
279 handle_nonnull_attribute, false }, 370 handle_nonnull_attribute, NULL },
280 { "nonstring", 0, 0, true, false, false, 371 { "nonstring", 0, 0, true, false, false, false,
281 handle_nonstring_attribute, false }, 372 handle_nonstring_attribute, NULL },
282 { "nothrow", 0, 0, true, false, false, 373 { "nothrow", 0, 0, true, false, false, false,
283 handle_nothrow_attribute, false }, 374 handle_nothrow_attribute, NULL },
284 { "may_alias", 0, 0, false, true, false, NULL, false }, 375 { "may_alias", 0, 0, false, true, false, false, NULL, NULL },
285 { "cleanup", 1, 1, true, false, false, 376 { "cleanup", 1, 1, true, false, false, false,
286 handle_cleanup_attribute, false }, 377 handle_cleanup_attribute, NULL },
287 { "warn_unused_result", 0, 0, false, true, true, 378 { "warn_unused_result", 0, 0, false, true, true, false,
288 handle_warn_unused_result_attribute, false }, 379 handle_warn_unused_result_attribute,
289 { "sentinel", 0, 1, false, true, true, 380 attr_warn_unused_result_exclusions },
290 handle_sentinel_attribute, false }, 381 { "sentinel", 0, 1, false, true, true, false,
382 handle_sentinel_attribute, NULL },
291 /* For internal use (marking of builtins) only. The name contains space 383 /* For internal use (marking of builtins) only. The name contains space
292 to prevent its usage in source code. */ 384 to prevent its usage in source code. */
293 { "type generic", 0, 0, false, true, true, 385 { "type generic", 0, 0, false, true, true, false,
294 handle_type_generic_attribute, false }, 386 handle_type_generic_attribute, NULL },
295 { "alloc_size", 1, 2, false, true, true, 387 { "alloc_size", 1, 2, false, true, true, false,
296 handle_alloc_size_attribute, false }, 388 handle_alloc_size_attribute,
297 { "cold", 0, 0, true, false, false, 389 attr_alloc_exclusions },
298 handle_cold_attribute, false }, 390 { "cold", 0, 0, true, false, false, false,
299 { "hot", 0, 0, true, false, false, 391 handle_cold_attribute,
300 handle_hot_attribute, false }, 392 attr_cold_hot_exclusions },
393 { "hot", 0, 0, true, false, false, false,
394 handle_hot_attribute,
395 attr_cold_hot_exclusions },
301 { "no_address_safety_analysis", 396 { "no_address_safety_analysis",
302 0, 0, true, false, false, 397 0, 0, true, false, false, false,
303 handle_no_address_safety_analysis_attribute, 398 handle_no_address_safety_analysis_attribute,
304 false }, 399 NULL },
305 { "no_sanitize", 1, 1, true, false, false, 400 { "no_sanitize", 1, -1, true, false, false, false,
306 handle_no_sanitize_attribute, 401 handle_no_sanitize_attribute, NULL },
307 false }, 402 { "no_sanitize_address", 0, 0, true, false, false, false,
308 { "no_sanitize_address", 0, 0, true, false, false, 403 handle_no_sanitize_address_attribute, NULL },
309 handle_no_sanitize_address_attribute, 404 { "no_sanitize_thread", 0, 0, true, false, false, false,
310 false }, 405 handle_no_sanitize_thread_attribute, NULL },
311 { "no_sanitize_thread", 0, 0, true, false, false, 406 { "no_sanitize_undefined", 0, 0, true, false, false, false,
312 handle_no_sanitize_thread_attribute, 407 handle_no_sanitize_undefined_attribute, NULL },
313 false }, 408 { "asan odr indicator", 0, 0, true, false, false, false,
314 { "no_sanitize_undefined", 0, 0, true, false, false, 409 handle_asan_odr_indicator_attribute, NULL },
315 handle_no_sanitize_undefined_attribute, 410 { "warning", 1, 1, true, false, false, false,
316 false }, 411 handle_error_attribute, NULL },
317 { "asan odr indicator", 0, 0, true, false, false, 412 { "error", 1, 1, true, false, false, false,
318 handle_asan_odr_indicator_attribute, 413 handle_error_attribute, NULL },
319 false }, 414 { "target", 1, -1, true, false, false, false,
320 { "warning", 1, 1, true, false, false, 415 handle_target_attribute, NULL },
321 handle_error_attribute, false }, 416 { "target_clones", 1, -1, true, false, false, false,
322 { "error", 1, 1, true, false, false, 417 handle_target_clones_attribute, NULL },
323 handle_error_attribute, false }, 418 { "optimize", 1, -1, true, false, false, false,
324 { "target", 1, -1, true, false, false, 419 handle_optimize_attribute, NULL },
325 handle_target_attribute, false },
326 { "target_clones", 1, -1, true, false, false,
327 handle_target_clones_attribute, false },
328 { "optimize", 1, -1, true, false, false,
329 handle_optimize_attribute, false },
330 /* For internal use only. The leading '*' both prevents its usage in 420 /* For internal use only. The leading '*' both prevents its usage in
331 source code and signals that it may be overridden by machine tables. */ 421 source code and signals that it may be overridden by machine tables. */
332 { "*tm regparm", 0, 0, false, true, true, 422 { "*tm regparm", 0, 0, false, true, true, false,
333 ignore_attribute, false }, 423 ignore_attribute, NULL },
334 { "no_split_stack", 0, 0, true, false, false, 424 { "no_split_stack", 0, 0, true, false, false, false,
335 handle_no_split_stack_attribute, false }, 425 handle_no_split_stack_attribute, NULL },
336 /* For internal use (marking of builtins and runtime functions) only. 426 /* For internal use (marking of builtins and runtime functions) only.
337 The name contains space to prevent its usage in source code. */ 427 The name contains space to prevent its usage in source code. */
338 { "fn spec", 1, 1, false, true, true, 428 { "fn spec", 1, 1, false, true, true, false,
339 handle_fnspec_attribute, false }, 429 handle_fnspec_attribute, NULL },
340 { "warn_unused", 0, 0, false, false, false, 430 { "warn_unused", 0, 0, false, false, false, false,
341 handle_warn_unused_attribute, false }, 431 handle_warn_unused_attribute, NULL },
342 { "returns_nonnull", 0, 0, false, true, true, 432 { "returns_nonnull", 0, 0, false, true, true, false,
343 handle_returns_nonnull_attribute, false }, 433 handle_returns_nonnull_attribute, NULL },
344 { "omp declare simd", 0, -1, true, false, false, 434 { "omp declare simd", 0, -1, true, false, false, false,
345 handle_omp_declare_simd_attribute, false }, 435 handle_omp_declare_simd_attribute, NULL },
346 { "cilk simd function", 0, -1, true, false, false, 436 { "simd", 0, 1, true, false, false, false,
347 handle_omp_declare_simd_attribute, false }, 437 handle_simd_attribute, NULL },
348 { "simd", 0, 1, true, false, false, 438 { "omp declare target", 0, 0, true, false, false, false,
349 handle_simd_attribute, false }, 439 handle_omp_declare_target_attribute, NULL },
350 { "omp declare target", 0, 0, true, false, false, 440 { "omp declare target link", 0, 0, true, false, false, false,
351 handle_omp_declare_target_attribute, false }, 441 handle_omp_declare_target_attribute, NULL },
352 { "omp declare target link", 0, 0, true, false, false, 442 { "omp declare target implicit", 0, 0, true, false, false, false,
353 handle_omp_declare_target_attribute, false }, 443 handle_omp_declare_target_attribute, NULL },
354 { "alloc_align", 1, 1, false, true, true, 444 { "alloc_align", 1, 1, false, true, true, false,
355 handle_alloc_align_attribute, false }, 445 handle_alloc_align_attribute,
356 { "assume_aligned", 1, 2, false, true, true, 446 attr_alloc_exclusions },
357 handle_assume_aligned_attribute, false }, 447 { "assume_aligned", 1, 2, false, true, true, false,
358 { "designated_init", 0, 0, false, true, false, 448 handle_assume_aligned_attribute, NULL },
359 handle_designated_init_attribute, false }, 449 { "designated_init", 0, 0, false, true, false, false,
360 { "bnd_variable_size", 0, 0, true, false, false, 450 handle_designated_init_attribute, NULL },
361 handle_bnd_variable_size_attribute, false }, 451 { "fallthrough", 0, 0, false, false, false, false,
362 { "bnd_legacy", 0, 0, true, false, false, 452 handle_fallthrough_attribute, NULL },
363 handle_bnd_legacy, false }, 453 { "patchable_function_entry", 1, 2, true, false, false, false,
364 { "bnd_instrument", 0, 0, true, false, false,
365 handle_bnd_instrument, false },
366 { "fallthrough", 0, 0, false, false, false,
367 handle_fallthrough_attribute, false },
368 { "patchable_function_entry", 1, 2, true, false, false,
369 handle_patchable_function_entry_attribute, 454 handle_patchable_function_entry_attribute,
370 false }, 455 NULL },
371 { "nocf_check", 0, 0, false, true, true, 456 { "nocf_check", 0, 0, false, true, true, true,
372 handle_nocf_check_attribute, true }, 457 handle_nocf_check_attribute, NULL },
373 { NULL, 0, 0, false, false, false, NULL, false } 458 { NULL, 0, 0, false, false, false, false, NULL, NULL }
374 }; 459 };
375 460
376 /* Give the specifications for the format attributes, used by C and all 461 /* Give the specifications for the format attributes, used by C and all
377 descendants. 462 descendants.
378 463
379 All attributes referencing arguments should be additionally processed
380 in chkp_copy_function_type_adding_bounds for correct instrumentation
381 by Pointer Bounds Checker.
382 Current list of processed format attributes: format, format_arg. */ 464 Current list of processed format attributes: format, format_arg. */
383 const struct attribute_spec c_common_format_attribute_table[] = 465 const struct attribute_spec c_common_format_attribute_table[] =
384 { 466 {
385 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, 467 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
386 affects_type_identity } */ 468 affects_type_identity, handler, exclude } */
387 { "format", 3, 3, false, true, true, 469 { "format", 3, 3, false, true, true, false,
388 handle_format_attribute, false }, 470 handle_format_attribute, NULL },
389 { "format_arg", 1, 1, false, true, true, 471 { "format_arg", 1, 1, false, true, true, false,
390 handle_format_arg_attribute, false }, 472 handle_format_arg_attribute, NULL },
391 { NULL, 0, 0, false, false, false, NULL, false } 473 { NULL, 0, 0, false, false, false, false, NULL, NULL }
392 }; 474 };
393 475
394 /* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain 476 /* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain
395 identifier as an argument, so the front end shouldn't look it up. */ 477 identifier as an argument, so the front end shouldn't look it up. */
396 478
420 int flags, bool *no_add_attrs) 502 int flags, bool *no_add_attrs)
421 { 503 {
422 if (TYPE_P (*node)) 504 if (TYPE_P (*node))
423 { 505 {
424 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 506 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
425 *node = build_variant_type_copy (*node); 507 {
426 TYPE_PACKED (*node) = 1; 508 warning (OPT_Wattributes,
509 "%qE attribute ignored for type %qT", name, *node);
510 *no_add_attrs = true;
511 }
512 else
513 TYPE_PACKED (*node) = 1;
427 } 514 }
428 else if (TREE_CODE (*node) == FIELD_DECL) 515 else if (TREE_CODE (*node) == FIELD_DECL)
429 { 516 {
430 if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT 517 if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
431 /* Still pack bitfields. */ 518 /* Still pack bitfields. */
524 int ARG_UNUSED (flags), bool *no_add_attrs) 611 int ARG_UNUSED (flags), bool *no_add_attrs)
525 { 612 {
526 if (TREE_CODE (*node) == FUNCTION_DECL 613 if (TREE_CODE (*node) == FUNCTION_DECL
527 || TREE_CODE (*node) == LABEL_DECL) 614 || TREE_CODE (*node) == LABEL_DECL)
528 { 615 {
529 if (lookup_attribute ("cold", DECL_ATTRIBUTES (*node)) != NULL) 616 /* Attribute hot processing is done later with lookup_attribute. */
530 {
531 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
532 "with attribute %qs", name, "cold");
533 *no_add_attrs = true;
534 }
535 /* Most of the rest of the hot processing is done later with
536 lookup_attribute. */
537 } 617 }
538 else 618 else
539 { 619 {
540 warning (OPT_Wattributes, "%qE attribute ignored", name); 620 warning (OPT_Wattributes, "%qE attribute ignored", name);
541 *no_add_attrs = true; 621 *no_add_attrs = true;
552 int ARG_UNUSED (flags), bool *no_add_attrs) 632 int ARG_UNUSED (flags), bool *no_add_attrs)
553 { 633 {
554 if (TREE_CODE (*node) == FUNCTION_DECL 634 if (TREE_CODE (*node) == FUNCTION_DECL
555 || TREE_CODE (*node) == LABEL_DECL) 635 || TREE_CODE (*node) == LABEL_DECL)
556 { 636 {
557 if (lookup_attribute ("hot", DECL_ATTRIBUTES (*node)) != NULL) 637 /* Attribute cold processing is done later with lookup_attribute. */
558 {
559 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
560 "with attribute %qs", name, "hot");
561 *no_add_attrs = true;
562 }
563 /* Most of the rest of the cold processing is done later with
564 lookup_attribute. */
565 } 638 }
566 else 639 else
567 { 640 {
568 warning (OPT_Wattributes, "%qE attribute ignored", name); 641 warning (OPT_Wattributes, "%qE attribute ignored", name);
569 *no_add_attrs = true; 642 *no_add_attrs = true;
600 673
601 static tree 674 static tree
602 handle_no_sanitize_attribute (tree *node, tree name, tree args, int, 675 handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
603 bool *no_add_attrs) 676 bool *no_add_attrs)
604 { 677 {
678 unsigned int flags = 0;
605 *no_add_attrs = true; 679 *no_add_attrs = true;
606 tree id = TREE_VALUE (args);
607 if (TREE_CODE (*node) != FUNCTION_DECL) 680 if (TREE_CODE (*node) != FUNCTION_DECL)
608 { 681 {
609 warning (OPT_Wattributes, "%qE attribute ignored", name); 682 warning (OPT_Wattributes, "%qE attribute ignored", name);
610 return NULL_TREE; 683 return NULL_TREE;
611 } 684 }
612 685
613 if (TREE_CODE (id) != STRING_CST) 686 for (; args; args = TREE_CHAIN (args))
614 { 687 {
615 error ("no_sanitize argument not a string"); 688 tree id = TREE_VALUE (args);
616 return NULL_TREE; 689 if (TREE_CODE (id) != STRING_CST)
617 } 690 {
618 691 error ("no_sanitize argument not a string");
619 char *string = ASTRDUP (TREE_STRING_POINTER (id)); 692 return NULL_TREE;
620 unsigned int flags = parse_no_sanitize_attribute (string); 693 }
694
695 char *string = ASTRDUP (TREE_STRING_POINTER (id));
696 flags |= parse_no_sanitize_attribute (string);
697 }
621 698
622 add_no_sanitize_value (*node, flags); 699 add_no_sanitize_value (*node, flags);
623 700
624 return NULL_TREE; 701 return NULL_TREE;
625 } 702 }
1086 /* Handle a "const" attribute; arguments as in 1163 /* Handle a "const" attribute; arguments as in
1087 struct attribute_spec.handler. */ 1164 struct attribute_spec.handler. */
1088 1165
1089 static tree 1166 static tree
1090 handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args), 1167 handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1091 int ARG_UNUSED (flags), bool *no_add_attrs) 1168 int flags, bool *no_add_attrs)
1092 { 1169 {
1093 tree type = TREE_TYPE (*node); 1170 tree type = TREE_TYPE (*node);
1094 1171
1095 /* See FIXME comment on noreturn in c_common_attribute_table. */ 1172 /* See FIXME comment on noreturn in c_common_attribute_table. */
1096 if (TREE_CODE (*node) == FUNCTION_DECL) 1173 if (TREE_CODE (*node) == FUNCTION_DECL)
1107 { 1184 {
1108 warning (OPT_Wattributes, "%qE attribute ignored", name); 1185 warning (OPT_Wattributes, "%qE attribute ignored", name);
1109 *no_add_attrs = true; 1186 *no_add_attrs = true;
1110 } 1187 }
1111 1188
1189 /* void __builtin_unreachable(void) is const. Accept other such
1190 built-ins but warn on user-defined functions that return void. */
1191 if (!(flags & ATTR_FLAG_BUILT_IN)
1192 && TREE_CODE (*node) == FUNCTION_DECL
1193 && VOID_TYPE_P (TREE_TYPE (type)))
1194 warning (OPT_Wattributes, "%qE attribute on function "
1195 "returning %<void%>", name);
1196
1112 return NULL_TREE; 1197 return NULL_TREE;
1113 } 1198 }
1114 1199
1115 /* Handle a "scalar_storage_order" attribute; arguments as in 1200 /* Handle a "scalar_storage_order" attribute; arguments as in
1116 struct attribute_spec.handler. */ 1201 struct attribute_spec.handler. */
1263 goto invalid; 1348 goto invalid;
1264 1349
1265 if (pri <= MAX_RESERVED_INIT_PRIORITY) 1350 if (pri <= MAX_RESERVED_INIT_PRIORITY)
1266 { 1351 {
1267 if (is_destructor) 1352 if (is_destructor)
1268 warning (0, 1353 warning (OPT_Wprio_ctor_dtor,
1269 "destructor priorities from 0 to %d are reserved " 1354 "destructor priorities from 0 to %d are reserved "
1270 "for the implementation", 1355 "for the implementation",
1271 MAX_RESERVED_INIT_PRIORITY); 1356 MAX_RESERVED_INIT_PRIORITY);
1272 else 1357 else
1273 warning (0, 1358 warning (OPT_Wprio_ctor_dtor,
1274 "constructor priorities from 0 to %d are reserved " 1359 "constructor priorities from 0 to %d are reserved "
1275 "for the implementation", 1360 "for the implementation",
1276 MAX_RESERVED_INIT_PRIORITY); 1361 MAX_RESERVED_INIT_PRIORITY);
1277 } 1362 }
1278 return pri; 1363 return pri;
1437 { 1522 {
1438 error ("unknown machine mode %qE", ident); 1523 error ("unknown machine mode %qE", ident);
1439 return NULL_TREE; 1524 return NULL_TREE;
1440 } 1525 }
1441 1526
1527 /* Allow the target a chance to translate MODE into something supported.
1528 See PR86324. */
1529 mode = targetm.translate_mode_attribute (mode);
1530
1442 valid_mode = false; 1531 valid_mode = false;
1443 switch (GET_MODE_CLASS (mode)) 1532 switch (GET_MODE_CLASS (mode))
1444 { 1533 {
1445 case MODE_INT: 1534 case MODE_INT:
1446 case MODE_PARTIAL_INT: 1535 case MODE_PARTIAL_INT:
1689 1778
1690 /* Common codes shared by handle_warn_if_not_aligned_attribute and 1779 /* Common codes shared by handle_warn_if_not_aligned_attribute and
1691 handle_aligned_attribute. */ 1780 handle_aligned_attribute. */
1692 1781
1693 static tree 1782 static tree
1694 common_handle_aligned_attribute (tree *node, tree args, int flags, 1783 common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
1695 bool *no_add_attrs, 1784 bool *no_add_attrs,
1696 bool warn_if_not_aligned_p) 1785 bool warn_if_not_aligned_p)
1697 { 1786 {
1698 tree decl = NULL_TREE; 1787 tree decl = NULL_TREE;
1699 tree *type = NULL; 1788 tree *type = NULL;
1700 int is_type = 0; 1789 bool is_type = false;
1701 tree align_expr; 1790 tree align_expr;
1702 int i; 1791
1792 /* The last (already pushed) declaration with all validated attributes
1793 merged in or the current about-to-be-pushed one if one hasn't been
1794 yet. */
1795 tree last_decl = node[1] ? node[1] : *node;
1703 1796
1704 if (args) 1797 if (args)
1705 { 1798 {
1706 align_expr = TREE_VALUE (args); 1799 align_expr = TREE_VALUE (args);
1707 if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE 1800 if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE
1716 decl = *node; 1809 decl = *node;
1717 type = &TREE_TYPE (decl); 1810 type = &TREE_TYPE (decl);
1718 is_type = TREE_CODE (*node) == TYPE_DECL; 1811 is_type = TREE_CODE (*node) == TYPE_DECL;
1719 } 1812 }
1720 else if (TYPE_P (*node)) 1813 else if (TYPE_P (*node))
1721 type = node, is_type = 1; 1814 type = node, is_type = true;
1722 1815
1723 if ((i = check_user_alignment (align_expr, true)) == -1 1816 /* Log2 of specified alignment. */
1724 || !check_cxx_fundamental_alignment_constraints (*node, i, flags)) 1817 int pow2align = check_user_alignment (align_expr, true);
1725 *no_add_attrs = true; 1818 if (pow2align == -1
1726 else if (is_type) 1819 || !check_cxx_fundamental_alignment_constraints (*node, pow2align, flags))
1820 {
1821 *no_add_attrs = true;
1822 return NULL_TREE;
1823 }
1824
1825 /* The alignment in bits corresponding to the specified alignment. */
1826 unsigned bitalign = (1U << pow2align) * BITS_PER_UNIT;
1827
1828 /* The alignment of the current declaration and that of the last
1829 pushed declaration, determined on demand below. */
1830 unsigned curalign = 0;
1831 unsigned lastalign = 0;
1832
1833 if (is_type)
1727 { 1834 {
1728 if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) 1835 if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1729 /* OK, modify the type in place. */; 1836 /* OK, modify the type in place. */;
1730 /* If we have a TYPE_DECL, then copy the type, so that we 1837 /* If we have a TYPE_DECL, then copy the type, so that we
1731 don't accidentally modify a builtin type. See pushdecl. */ 1838 don't accidentally modify a builtin type. See pushdecl. */
1742 else 1849 else
1743 *type = build_variant_type_copy (*type); 1850 *type = build_variant_type_copy (*type);
1744 1851
1745 if (warn_if_not_aligned_p) 1852 if (warn_if_not_aligned_p)
1746 { 1853 {
1747 SET_TYPE_WARN_IF_NOT_ALIGN (*type, (1U << i) * BITS_PER_UNIT); 1854 SET_TYPE_WARN_IF_NOT_ALIGN (*type, bitalign);
1748 warn_if_not_aligned_p = false; 1855 warn_if_not_aligned_p = false;
1749 } 1856 }
1750 else 1857 else
1751 { 1858 {
1752 SET_TYPE_ALIGN (*type, (1U << i) * BITS_PER_UNIT); 1859 SET_TYPE_ALIGN (*type, bitalign);
1753 TYPE_USER_ALIGN (*type) = 1; 1860 TYPE_USER_ALIGN (*type) = 1;
1754 } 1861 }
1755 } 1862 }
1756 else if (! VAR_OR_FUNCTION_DECL_P (decl) 1863 else if (! VAR_OR_FUNCTION_DECL_P (decl)
1757 && TREE_CODE (decl) != FIELD_DECL) 1864 && TREE_CODE (decl) != FIELD_DECL)
1758 { 1865 {
1759 error ("alignment may not be specified for %q+D", decl); 1866 error ("alignment may not be specified for %q+D", decl);
1760 *no_add_attrs = true; 1867 *no_add_attrs = true;
1761 } 1868 }
1869 else if (TREE_CODE (decl) == FUNCTION_DECL
1870 && ((curalign = DECL_ALIGN (decl)) > bitalign
1871 || ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
1872 {
1873 /* Either a prior attribute on the same declaration or one
1874 on a prior declaration of the same function specifies
1875 stricter alignment than this attribute. */
1876 bool note = lastalign != 0;
1877 if (lastalign)
1878 curalign = lastalign;
1879
1880 curalign /= BITS_PER_UNIT;
1881 bitalign /= BITS_PER_UNIT;
1882
1883 bool diagd = true;
1884 auto_diagnostic_group d;
1885 if (DECL_USER_ALIGN (decl) || DECL_USER_ALIGN (last_decl))
1886 diagd = warning (OPT_Wattributes,
1887 "ignoring attribute %<%E (%u)%> because it conflicts "
1888 "with attribute %<%E (%u)%>",
1889 name, bitalign, name, curalign);
1890 else if (!warn_if_not_aligned_p)
1891 /* Do not error out for attribute warn_if_not_aligned. */
1892 error ("alignment for %q+D must be at least %d", decl, curalign);
1893
1894 if (diagd && note)
1895 inform (DECL_SOURCE_LOCATION (last_decl), "previous declaration here");
1896
1897 *no_add_attrs = true;
1898 }
1762 else if (DECL_USER_ALIGN (decl) 1899 else if (DECL_USER_ALIGN (decl)
1763 && DECL_ALIGN (decl) > (1U << i) * BITS_PER_UNIT) 1900 && DECL_ALIGN (decl) > bitalign)
1764 /* C++-11 [dcl.align/4]: 1901 /* C++-11 [dcl.align/4]:
1765 1902
1766 When multiple alignment-specifiers are specified for an 1903 When multiple alignment-specifiers are specified for an
1767 entity, the alignment requirement shall be set to the 1904 entity, the alignment requirement shall be set to the
1768 strictest specified alignment. 1905 strictest specified alignment.
1770 This formally comes from the c++11 specification but we are 1907 This formally comes from the c++11 specification but we are
1771 doing it for the GNU attribute syntax as well. */ 1908 doing it for the GNU attribute syntax as well. */
1772 *no_add_attrs = true; 1909 *no_add_attrs = true;
1773 else if (!warn_if_not_aligned_p 1910 else if (!warn_if_not_aligned_p
1774 && TREE_CODE (decl) == FUNCTION_DECL 1911 && TREE_CODE (decl) == FUNCTION_DECL
1775 && DECL_ALIGN (decl) > (1U << i) * BITS_PER_UNIT) 1912 && DECL_ALIGN (decl) > bitalign)
1776 { 1913 {
1777 /* Don't warn function alignment here if warn_if_not_aligned_p is 1914 /* Don't warn function alignment here if warn_if_not_aligned_p is
1778 true. It will be warned later. */ 1915 true. It will be warned later. */
1779 if (DECL_USER_ALIGN (decl)) 1916 if (DECL_USER_ALIGN (decl))
1780 error ("alignment for %q+D was previously specified as %d " 1917 error ("alignment for %q+D was previously specified as %d "
1789 { 1926 {
1790 if (warn_if_not_aligned_p) 1927 if (warn_if_not_aligned_p)
1791 { 1928 {
1792 if (TREE_CODE (decl) == FIELD_DECL && !DECL_C_BIT_FIELD (decl)) 1929 if (TREE_CODE (decl) == FIELD_DECL && !DECL_C_BIT_FIELD (decl))
1793 { 1930 {
1794 SET_DECL_WARN_IF_NOT_ALIGN (decl, (1U << i) * BITS_PER_UNIT); 1931 SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign);
1795 warn_if_not_aligned_p = false; 1932 warn_if_not_aligned_p = false;
1796 } 1933 }
1797 } 1934 }
1798 else 1935 else
1799 { 1936 {
1800 SET_DECL_ALIGN (decl, (1U << i) * BITS_PER_UNIT); 1937 SET_DECL_ALIGN (decl, bitalign);
1801 DECL_USER_ALIGN (decl) = 1; 1938 DECL_USER_ALIGN (decl) = 1;
1802 } 1939 }
1803 } 1940 }
1804 1941
1805 if (warn_if_not_aligned_p) 1942 if (warn_if_not_aligned_p)
1814 1951
1815 /* Handle a "aligned" attribute; arguments as in 1952 /* Handle a "aligned" attribute; arguments as in
1816 struct attribute_spec.handler. */ 1953 struct attribute_spec.handler. */
1817 1954
1818 static tree 1955 static tree
1819 handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args, 1956 handle_aligned_attribute (tree *node, tree name, tree args,
1820 int flags, bool *no_add_attrs) 1957 int flags, bool *no_add_attrs)
1821 { 1958 {
1822 return common_handle_aligned_attribute (node, args, flags, 1959 return common_handle_aligned_attribute (node, name, args, flags,
1823 no_add_attrs, false); 1960 no_add_attrs, false);
1824 } 1961 }
1825 1962
1826 /* Handle a "warn_if_not_aligned" attribute; arguments as in 1963 /* Handle a "warn_if_not_aligned" attribute; arguments as in
1827 struct attribute_spec.handler. */ 1964 struct attribute_spec.handler. */
1828 1965
1829 static tree 1966 static tree
1830 handle_warn_if_not_aligned_attribute (tree *node, tree ARG_UNUSED (name), 1967 handle_warn_if_not_aligned_attribute (tree *node, tree name,
1831 tree args, int flags, 1968 tree args, int flags,
1832 bool *no_add_attrs) 1969 bool *no_add_attrs)
1833 { 1970 {
1834 return common_handle_aligned_attribute (node, args, flags, 1971 return common_handle_aligned_attribute (node, name, args, flags,
1835 no_add_attrs, true); 1972 no_add_attrs, true);
1836 } 1973 }
1837 1974
1838 /* Handle a "weak" attribute; arguments as in 1975 /* Handle a "weak" attribute; arguments as in
1839 struct attribute_spec.handler. */ 1976 struct attribute_spec.handler. */
2161 /* Handle an "tls_model" attribute; arguments as in 2298 /* Handle an "tls_model" attribute; arguments as in
2162 struct attribute_spec.handler. */ 2299 struct attribute_spec.handler. */
2163 2300
2164 static tree 2301 static tree
2165 handle_tls_model_attribute (tree *node, tree name, tree args, 2302 handle_tls_model_attribute (tree *node, tree name, tree args,
2166 int ARG_UNUSED (flags), bool *no_add_attrs) 2303 int ARG_UNUSED (flags),
2304 bool *ARG_UNUSED (no_add_attrs))
2167 { 2305 {
2168 tree id; 2306 tree id;
2169 tree decl = *node; 2307 tree decl = *node;
2170 enum tls_model kind; 2308 enum tls_model kind;
2171
2172 *no_add_attrs = true;
2173 2309
2174 if (!VAR_P (decl) || !DECL_THREAD_LOCAL_P (decl)) 2310 if (!VAR_P (decl) || !DECL_THREAD_LOCAL_P (decl))
2175 { 2311 {
2176 warning (OPT_Wattributes, "%qE attribute ignored", name); 2312 warning (OPT_Wattributes, "%qE attribute ignored", name);
2177 return NULL_TREE; 2313 return NULL_TREE;
2348 && TREE_CODE (TREE_VALUE (args)) == STRING_CST 2484 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
2349 && !TREE_CHAIN (args)); 2485 && !TREE_CHAIN (args));
2350 return NULL_TREE; 2486 return NULL_TREE;
2351 } 2487 }
2352 2488
2353 /* Handle a "bnd_variable_size" attribute; arguments as in
2354 struct attribute_spec.handler. */
2355
2356 static tree
2357 handle_bnd_variable_size_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2358 int ARG_UNUSED (flags), bool *no_add_attrs)
2359 {
2360 if (TREE_CODE (*node) != FIELD_DECL)
2361 {
2362 warning (OPT_Wattributes, "%qE attribute ignored", name);
2363 *no_add_attrs = true;
2364 }
2365
2366 return NULL_TREE;
2367 }
2368
2369 /* Handle a "bnd_legacy" attribute; arguments as in
2370 struct attribute_spec.handler. */
2371
2372 static tree
2373 handle_bnd_legacy (tree *node, tree name, tree ARG_UNUSED (args),
2374 int ARG_UNUSED (flags), bool *no_add_attrs)
2375 {
2376 if (TREE_CODE (*node) != FUNCTION_DECL)
2377 {
2378 warning (OPT_Wattributes, "%qE attribute ignored", name);
2379 *no_add_attrs = true;
2380 }
2381
2382 return NULL_TREE;
2383 }
2384
2385 /* Handle a "bnd_instrument" attribute; arguments as in
2386 struct attribute_spec.handler. */
2387
2388 static tree
2389 handle_bnd_instrument (tree *node, tree name, tree ARG_UNUSED (args),
2390 int ARG_UNUSED (flags), bool *no_add_attrs)
2391 {
2392 if (TREE_CODE (*node) != FUNCTION_DECL)
2393 {
2394 warning (OPT_Wattributes, "%qE attribute ignored", name);
2395 *no_add_attrs = true;
2396 }
2397
2398 return NULL_TREE;
2399 }
2400
2401 /* Handle a "warn_unused" attribute; arguments as in 2489 /* Handle a "warn_unused" attribute; arguments as in
2402 struct attribute_spec.handler. */ 2490 struct attribute_spec.handler. */
2403 2491
2404 static tree 2492 static tree
2405 handle_warn_unused_attribute (tree *node, tree name, 2493 handle_warn_unused_attribute (tree *node, tree name,
2433 static tree 2521 static tree
2434 handle_simd_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs) 2522 handle_simd_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs)
2435 { 2523 {
2436 if (TREE_CODE (*node) == FUNCTION_DECL) 2524 if (TREE_CODE (*node) == FUNCTION_DECL)
2437 { 2525 {
2438 if (lookup_attribute ("cilk simd function", 2526 tree t = get_identifier ("omp declare simd");
2439 DECL_ATTRIBUTES (*node)) != NULL) 2527 tree attr = NULL_TREE;
2440 { 2528 if (args)
2441 error_at (DECL_SOURCE_LOCATION (*node), 2529 {
2442 "%<__simd__%> attribute cannot be used in the same " 2530 tree id = TREE_VALUE (args);
2443 "function marked as a Cilk Plus SIMD-enabled function"); 2531
2444 *no_add_attrs = true; 2532 if (TREE_CODE (id) != STRING_CST)
2445 }
2446 else
2447 {
2448 tree t = get_identifier ("omp declare simd");
2449 tree attr = NULL_TREE;
2450 if (args)
2451 { 2533 {
2452 tree id = TREE_VALUE (args); 2534 error ("attribute %qE argument not a string", name);
2453 2535 *no_add_attrs = true;
2454 if (TREE_CODE (id) != STRING_CST) 2536 return NULL_TREE;
2455 {
2456 error ("attribute %qE argument not a string", name);
2457 *no_add_attrs = true;
2458 return NULL_TREE;
2459 }
2460
2461 if (strcmp (TREE_STRING_POINTER (id), "notinbranch") == 0)
2462 attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
2463 OMP_CLAUSE_NOTINBRANCH);
2464 else
2465 if (strcmp (TREE_STRING_POINTER (id), "inbranch") == 0)
2466 attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
2467 OMP_CLAUSE_INBRANCH);
2468 else
2469 {
2470 error ("only %<inbranch%> and %<notinbranch%> flags are "
2471 "allowed for %<__simd__%> attribute");
2472 *no_add_attrs = true;
2473 return NULL_TREE;
2474 }
2475 } 2537 }
2476 2538
2477 DECL_ATTRIBUTES (*node) = tree_cons (t, 2539 if (strcmp (TREE_STRING_POINTER (id), "notinbranch") == 0)
2478 build_tree_list (NULL_TREE, 2540 attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
2479 attr), 2541 OMP_CLAUSE_NOTINBRANCH);
2480 DECL_ATTRIBUTES (*node)); 2542 else if (strcmp (TREE_STRING_POINTER (id), "inbranch") == 0)
2481 } 2543 attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
2544 OMP_CLAUSE_INBRANCH);
2545 else
2546 {
2547 error ("only %<inbranch%> and %<notinbranch%> flags are "
2548 "allowed for %<__simd__%> attribute");
2549 *no_add_attrs = true;
2550 return NULL_TREE;
2551 }
2552 }
2553
2554 DECL_ATTRIBUTES (*node)
2555 = tree_cons (t, build_tree_list (NULL_TREE, attr),
2556 DECL_ATTRIBUTES (*node));
2482 } 2557 }
2483 else 2558 else
2484 { 2559 {
2485 warning (OPT_Wattributes, "%qE attribute ignored", name); 2560 warning (OPT_Wattributes, "%qE attribute ignored", name);
2486 *no_add_attrs = true; 2561 *no_add_attrs = true;
2551 static tree 2626 static tree
2552 handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args), 2627 handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2553 int ARG_UNUSED (flags), bool *no_add_attrs) 2628 int ARG_UNUSED (flags), bool *no_add_attrs)
2554 { 2629 {
2555 if (TREE_CODE (*node) == FUNCTION_DECL) 2630 if (TREE_CODE (*node) == FUNCTION_DECL)
2556 DECL_PURE_P (*node) = 1; 2631 {
2557 /* ??? TODO: Support types. */ 2632 tree type = TREE_TYPE (*node);
2633 if (VOID_TYPE_P (TREE_TYPE (type)))
2634 warning (OPT_Wattributes, "%qE attribute on function "
2635 "returning %<void%>", name);
2636
2637 DECL_PURE_P (*node) = 1;
2638 /* ??? TODO: Support types. */
2639 }
2558 else 2640 else
2559 { 2641 {
2560 warning (OPT_Wattributes, "%qE attribute ignored", name); 2642 warning (OPT_Wattributes, "%qE attribute ignored", name);
2561 *no_add_attrs = true; 2643 *no_add_attrs = true;
2562 } 2644 }
3062 { 3144 {
3063 tree type = TREE_TYPE (*node); 3145 tree type = TREE_TYPE (*node);
3064 3146
3065 if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE) 3147 if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
3066 { 3148 {
3149 /* Accept the attribute on arrays and pointers to all three
3150 narrow character types. */
3067 tree eltype = TREE_TYPE (type); 3151 tree eltype = TREE_TYPE (type);
3068 if (eltype == char_type_node) 3152 eltype = TYPE_MAIN_VARIANT (eltype);
3153 if (eltype == char_type_node
3154 || eltype == signed_char_type_node
3155 || eltype == unsigned_char_type_node)
3069 return NULL_TREE; 3156 return NULL_TREE;
3070 } 3157 }
3071 3158
3072 warning (OPT_Wattributes, 3159 warning (OPT_Wattributes,
3073 "%qE attribute ignored on objects of type %qT", 3160 "%qE attribute ignored on objects of type %qT",