Mercurial > hg > CbC > CbC_gcc
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", |