/* C-family attributes handling.
   Copyright (C) 1992-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "function.h"
#include "tree.h"
#include "memmodel.h"
#include "c-common.h"
#include "gimple-expr.h"
#include "tm_p.h"
#include "stringpool.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "intl.h"
#include "stor-layout.h"
#include "calls.h"
#include "attribs.h"
#include "varasm.h"
#include "trans-mem.h"
#include "c-objc.h"
#include "common/common-target.h"
#include "langhooks.h"
#include "tree-inline.h"
#include "toplev.h"
#include "tree-iterator.h"
#include "opts.h"
#include "gimplify.h"
#include "tree-pretty-print.h"
#include "gcc-rich-location.h"

static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
static tree handle_common_attribute (tree *, tree, tree, int, bool *);
static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
						  int, bool *);
static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
						 int, bool *);
static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
							 int, bool *);
static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
						    bool *);
static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int,
						   bool *);
static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int,
						 bool *);
static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_stack_protector_function_attribute (tree *, tree,
							tree, int, bool *);
static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
static tree handle_nocf_check_attribute (tree *, tree, tree, int, bool *);
static tree handle_symver_attribute (tree *, tree, tree, int, bool *);
static tree handle_noicf_attribute (tree *, tree, tree, int, bool *);
static tree handle_noipa_attribute (tree *, tree, tree, int, bool *);
static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
static tree handle_always_inline_attribute (tree *, tree, tree, int,
					    bool *);
static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *);
static tree handle_artificial_attribute (tree *, tree, tree, int, bool *);
static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
static tree handle_error_attribute (tree *, tree, tree, int, bool *);
static tree handle_used_attribute (tree *, tree, tree, int, bool *);
static tree handle_externally_visible_attribute (tree *, tree, tree, int,
						 bool *);
static tree handle_no_reorder_attribute (tree *, tree, tree, int,
						 bool *);
static tree handle_const_attribute (tree *, tree, tree, int, bool *);
static tree handle_transparent_union_attribute (tree *, tree, tree,
						int, bool *);
static tree handle_scalar_storage_order_attribute (tree *, tree, tree,
						   int, bool *);
static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
static tree handle_section_attribute (tree *, tree, tree, int, bool *);
static tree handle_special_var_sec_attribute (tree *, tree, tree, int, bool *);
static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree,
						  int, bool *);
static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *);
static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_visibility_attribute (tree *, tree, tree, int,
					 bool *);
static tree handle_tls_model_attribute (tree *, tree, tree, int,
					bool *);
static tree handle_no_instrument_function_attribute (tree *, tree,
						     tree, int, bool *);
static tree handle_no_profile_instrument_function_attribute (tree *, tree,
							     tree, int, bool *);
static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
static tree handle_dealloc_attribute (tree *, tree, tree, int, bool *);
static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
					     bool *);
static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
static tree handle_vector_size_attribute (tree *, tree, tree, int,
					  bool *) ATTRIBUTE_NONNULL(3);
static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *);
static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
						 bool *);
static tree handle_access_attribute (tree *, tree, tree, int, bool *);

static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *);
static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool *);
static tree handle_target_attribute (tree *, tree, tree, int, bool *);
static tree handle_target_clones_attribute (tree *, tree, tree, int, bool *);
static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
static tree ignore_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
static tree handle_zero_call_used_regs_attribute (tree *, tree, tree, int,
						  bool *);
static tree handle_argspec_attribute (tree *, tree, tree, int, bool *);
static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
					       bool *);
static tree handle_omp_declare_variant_attribute (tree *, tree, tree, int,
						  bool *);
static tree handle_simd_attribute (tree *, tree, tree, int, bool *);
static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
						 bool *);
static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *);
static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
						       int, bool *);
static tree handle_copy_attribute (tree *, tree, tree, int, bool *);
static tree handle_nsobject_attribute (tree *, tree, tree, int, bool *);
static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *);
static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool *);
static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int,
						    bool *);
static tree handle_retain_attribute (tree *, tree, tree, int, bool *);

/* Helper to define attribute exclusions.  */
#define ATTR_EXCL(name, function, type, variable)	\
  { name, function, type, variable }

/* Define attributes that are mutually exclusive with one another.  */
static const struct attribute_spec::exclusions attr_aligned_exclusions[] =
{
  /* Attribute name     exclusion applies to:
	                function, type, variable */
  ATTR_EXCL ("aligned", true, false, false),
  ATTR_EXCL ("packed", true, false, false),
  ATTR_EXCL (NULL, false, false, false)
};

extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
{
  ATTR_EXCL ("cold", true, true, true),
  ATTR_EXCL ("hot", true, true, true),
  ATTR_EXCL (NULL, false, false, false)
};

static const struct attribute_spec::exclusions attr_common_exclusions[] =
{
  ATTR_EXCL ("common", true, true, true),
  ATTR_EXCL ("nocommon", true, true, true),
  ATTR_EXCL (NULL, false, false, false),
};

static const struct attribute_spec::exclusions attr_inline_exclusions[] =
{
  ATTR_EXCL ("noinline", true, true, true),
  ATTR_EXCL (NULL, false, false, false),
};

static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
{
  ATTR_EXCL ("always_inline", true, true, true),
  ATTR_EXCL ("gnu_inline", true, true, true),
  ATTR_EXCL (NULL, false, false, false),
};

extern const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
{
  ATTR_EXCL ("alloc_align", true, true, true),
  ATTR_EXCL ("alloc_size", true, true, true),
  ATTR_EXCL ("const", true, true, true),
  ATTR_EXCL ("malloc", true, true, true),
  ATTR_EXCL ("pure", true, true, true),
  ATTR_EXCL ("returns_twice", true, true, true),
  ATTR_EXCL ("warn_unused_result", true, true, true),
  ATTR_EXCL (NULL, false, false, false),
};

static const struct attribute_spec::exclusions
attr_warn_unused_result_exclusions[] =
{
  ATTR_EXCL ("noreturn", true, true, true),
  ATTR_EXCL ("warn_unused_result", true, true, true),
  ATTR_EXCL (NULL, false, false, false),
};

static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
{
  ATTR_EXCL ("noreturn", true, true, true),
  ATTR_EXCL (NULL, false, false, false),
};

/* Exclusions that apply to attribute alloc_align, alloc_size, and malloc.  */
static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
{
  ATTR_EXCL ("const", true, true, true),
  ATTR_EXCL ("noreturn", true, true, true),
  ATTR_EXCL ("pure", true, true, true),
  ATTR_EXCL (NULL, false, false, false),
};

static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
{
  ATTR_EXCL ("const", true, true, true),
  ATTR_EXCL ("alloc_align", true, true, true),
  ATTR_EXCL ("alloc_size", true, true, true),
  ATTR_EXCL ("malloc", true, true, true),
  ATTR_EXCL ("noreturn", true, true, true),
  ATTR_EXCL ("pure", true, true, true),
  ATTR_EXCL (NULL, false, false, false)
};

/* Exclusions that apply to attributes that put declarations in specific
   sections.  */
static const struct attribute_spec::exclusions attr_section_exclusions[] =
{
  ATTR_EXCL ("noinit", true, true, true),
  ATTR_EXCL ("persistent", true, true, true),
  ATTR_EXCL ("section", true, true, true),
  ATTR_EXCL (NULL, false, false, false),
};

static const struct attribute_spec::exclusions attr_stack_protect_exclusions[] =
{
  ATTR_EXCL ("stack_protect", true, false, false),
  ATTR_EXCL ("no_stack_protector", true, false, false),
  ATTR_EXCL (NULL, false, false, false),
};


/* Table of machine-independent attributes common to all C-like languages.

   Current list of processed common attributes: nonnull.  */
const struct attribute_spec c_common_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
       affects_type_identity, handler, exclude } */
  { "signed_bool_precision",  1, 1, false, true, false, true,
			      handle_signed_bool_precision_attribute, NULL },
  { "packed",                 0, 0, false, false, false, false,
			      handle_packed_attribute,
	                      attr_aligned_exclusions },
  { "nocommon",               0, 0, true,  false, false, false,
			      handle_nocommon_attribute,
	                      attr_common_exclusions },
  { "common",                 0, 0, true,  false, false, false,
			      handle_common_attribute,
	                      attr_common_exclusions },
  /* FIXME: logically, noreturn attributes should be listed as
     "false, true, true" and apply to function types.  But implementing this
     would require all the places in the compiler that use TREE_THIS_VOLATILE
     on a decl to identify non-returning functions to be located and fixed
     to check the function type instead.  */
  { "noreturn",               0, 0, true,  false, false, false,
			      handle_noreturn_attribute,
	                      attr_noreturn_exclusions },
  { "volatile",               0, 0, true,  false, false, false,
			      handle_noreturn_attribute, NULL },
  { "stack_protect",          0, 0, true,  false, false, false,
			      handle_stack_protect_attribute,
			      attr_stack_protect_exclusions },
  { "no_stack_protector",     0, 0, true, false, false, false,
			      handle_no_stack_protector_function_attribute,
			      attr_stack_protect_exclusions },
  { "noinline",               0, 0, true,  false, false, false,
			      handle_noinline_attribute,
	                      attr_noinline_exclusions },
  { "noclone",                0, 0, true,  false, false, false,
			      handle_noclone_attribute, NULL },
  { "no_icf",                 0, 0, true,  false, false, false,
			      handle_noicf_attribute, NULL },
  { "noipa",		      0, 0, true,  false, false, false,
			      handle_noipa_attribute, NULL },
  { "leaf",                   0, 0, true,  false, false, false,
			      handle_leaf_attribute, NULL },
  { "always_inline",          0, 0, true,  false, false, false,
			      handle_always_inline_attribute,
	                      attr_inline_exclusions },
  { "gnu_inline",             0, 0, true,  false, false, false,
			      handle_gnu_inline_attribute,
	                      attr_inline_exclusions },
  { "artificial",             0, 0, true,  false, false, false,
			      handle_artificial_attribute, NULL },
  { "flatten",                0, 0, true,  false, false, false,
			      handle_flatten_attribute, NULL },
  { "used",                   0, 0, true,  false, false, false,
			      handle_used_attribute, NULL },
  { "unused",                 0, 0, false, false, false, false,
			      handle_unused_attribute, NULL },
  { "retain",                 0, 0, true,  false, false, false,
			      handle_retain_attribute, NULL },
  { "externally_visible",     0, 0, true,  false, false, false,
			      handle_externally_visible_attribute, NULL },
  { "no_reorder",	      0, 0, true, false, false, false,
	                      handle_no_reorder_attribute, NULL },
  /* The same comments as for noreturn attributes apply to const ones.  */
  { "const",                  0, 0, true,  false, false, false,
			      handle_const_attribute,
	                      attr_const_pure_exclusions },
  { "scalar_storage_order",   1, 1, false, false, false, false,
			      handle_scalar_storage_order_attribute, NULL },
  { "transparent_union",      0, 0, false, false, false, false,
			      handle_transparent_union_attribute, NULL },
  { "constructor",            0, 1, true,  false, false, false,
			      handle_constructor_attribute, NULL },
  { "destructor",             0, 1, true,  false, false, false,
			      handle_destructor_attribute, NULL },
  { "mode",                   1, 1, false,  true, false, false,
			      handle_mode_attribute, NULL },
  { "section",                1, 1, true,  false, false, false,
			      handle_section_attribute, attr_section_exclusions },
  { "aligned",                0, 1, false, false, false, false,
			      handle_aligned_attribute,
	                      attr_aligned_exclusions },
  { "warn_if_not_aligned",    0, 1, false, false, false, false,
			      handle_warn_if_not_aligned_attribute, NULL },
  { "weak",                   0, 0, true,  false, false, false,
			      handle_weak_attribute, NULL },
  { "noplt",                   0, 0, true,  false, false, false,
			      handle_noplt_attribute, NULL },
  { "ifunc",                  1, 1, true,  false, false, false,
			      handle_ifunc_attribute, NULL },
  { "alias",                  1, 1, true,  false, false, false,
			      handle_alias_attribute, NULL },
  { "weakref",                0, 1, true,  false, false, false,
			      handle_weakref_attribute, NULL },
  { "no_instrument_function", 0, 0, true,  false, false, false,
			      handle_no_instrument_function_attribute,
			      NULL },
  { "no_profile_instrument_function",  0, 0, true, false, false, false,
			      handle_no_profile_instrument_function_attribute,
			      NULL },
  { "malloc",                 0, 2, true,  false, false, false,
			      handle_malloc_attribute, attr_alloc_exclusions },
  { "returns_twice",          0, 0, true,  false, false, false,
			      handle_returns_twice_attribute,
	                      attr_returns_twice_exclusions },
  { "no_stack_limit",         0, 0, true,  false, false, false,
			      handle_no_limit_stack_attribute, NULL },
  { "pure",                   0, 0, true,  false, false, false,
			      handle_pure_attribute,
	                      attr_const_pure_exclusions },
  { "transaction_callable",   0, 0, false, true,  false, false,
			      handle_tm_attribute, NULL },
  { "transaction_unsafe",     0, 0, false, true,  false, true,
			      handle_tm_attribute, NULL },
  { "transaction_safe",       0, 0, false, true,  false, true,
			      handle_tm_attribute, NULL },
  { "transaction_safe_dynamic", 0, 0, true, false,  false, false,
			      handle_tm_attribute, NULL },
  { "transaction_may_cancel_outer", 0, 0, false, true, false, false,
			      handle_tm_attribute, NULL },
  /* ??? These two attributes didn't make the transition from the
     Intel language document to the multi-vendor language document.  */
  { "transaction_pure",       0, 0, false, true,  false, false,
			      handle_tm_attribute, NULL },
  { "transaction_wrap",       1, 1, true,  false,  false, false,
			     handle_tm_wrap_attribute, NULL },
  /* For internal use (marking of builtins) only.  The name contains space
     to prevent its usage in source code.  */
  { "no vops",                0, 0, true,  false, false, false,
			      handle_novops_attribute, NULL },
  { "deprecated",             0, 1, false, false, false, false,
			      handle_deprecated_attribute, NULL },
  { "vector_size",	      1, 1, false, true, false, true,
			      handle_vector_size_attribute, NULL },
  { "visibility",	      1, 1, false, false, false, false,
			      handle_visibility_attribute, NULL },
  { "tls_model",	      1, 1, true,  false, false, false,
			      handle_tls_model_attribute, NULL },
  { "nonnull",                0, -1, false, true, true, false,
			      handle_nonnull_attribute, NULL },
  { "nonstring",              0, 0, true, false, false, false,
			      handle_nonstring_attribute, NULL },
  { "nothrow",                0, 0, true,  false, false, false,
			      handle_nothrow_attribute, NULL },
  { "may_alias",	      0, 0, false, true, false, false, NULL, NULL },
  { "cleanup",		      1, 1, true, false, false, false,
			      handle_cleanup_attribute, NULL },
  { "warn_unused_result",     0, 0, false, true, true, false,
			      handle_warn_unused_result_attribute,
	                      attr_warn_unused_result_exclusions },
  { "sentinel",               0, 1, false, true, true, false,
			      handle_sentinel_attribute, NULL },
  /* For internal use (marking of builtins) only.  The name contains space
     to prevent its usage in source code.  */
  { "type generic",           0, 0, false, true, true, false,
			      handle_type_generic_attribute, NULL },
  { "alloc_size",	      1, 2, false, true, true, false,
			      handle_alloc_size_attribute,
	                      attr_alloc_exclusions },
  { "cold",                   0, 0, true,  false, false, false,
			      handle_cold_attribute,
	                      attr_cold_hot_exclusions },
  { "hot",                    0, 0, true,  false, false, false,
			      handle_hot_attribute,
	                      attr_cold_hot_exclusions },
  { "no_address_safety_analysis",
			      0, 0, true, false, false, false,
			      handle_no_address_safety_analysis_attribute,
			      NULL },
  { "no_sanitize",	      1, -1, true, false, false, false,
			      handle_no_sanitize_attribute, NULL },
  { "no_sanitize_address",    0, 0, true, false, false, false,
			      handle_no_sanitize_address_attribute, NULL },
  { "no_sanitize_thread",     0, 0, true, false, false, false,
			      handle_no_sanitize_thread_attribute, NULL },
  { "no_sanitize_undefined",  0, 0, true, false, false, false,
			      handle_no_sanitize_undefined_attribute, NULL },
  { "no_sanitize_coverage",   0, 0, true, false, false, false,
			      handle_no_sanitize_coverage_attribute, NULL },
  { "asan odr indicator",     0, 0, true, false, false, false,
			      handle_asan_odr_indicator_attribute, NULL },
  { "warning",		      1, 1, true,  false, false, false,
			      handle_error_attribute, NULL },
  { "error",		      1, 1, true,  false, false, false,
			      handle_error_attribute, NULL },
  { "target",                 1, -1, true, false, false, false,
			      handle_target_attribute, NULL },
  { "target_clones",          1, -1, true, false, false, false,
			      handle_target_clones_attribute, NULL },
  { "optimize",               1, -1, true, false, false, false,
			      handle_optimize_attribute, NULL },
  /* For internal use only.  The leading '*' both prevents its usage in
     source code and signals that it may be overridden by machine tables.  */
  { "*tm regparm",            0, 0, false, true, true, false,
			      ignore_attribute, NULL },
  { "no_split_stack",	      0, 0, true,  false, false, false,
			      handle_no_split_stack_attribute, NULL },
  { "zero_call_used_regs",    1, 1, true, false, false, false,
			      handle_zero_call_used_regs_attribute, NULL },
  /* For internal use only (marking of function arguments).
     The name contains a space to prevent its usage in source code.  */
  { "arg spec",		      1, -1, true, false, false, false,
			      handle_argspec_attribute, NULL },
  /* For internal use (marking of builtins and runtime functions) only.
     The name contains space to prevent its usage in source code.  */
  { "fn spec",		      1, 1, false, true, true, false,
			      handle_fnspec_attribute, NULL },
  { "warn_unused",            0, 0, false, false, false, false,
			      handle_warn_unused_attribute, NULL },
  { "returns_nonnull",        0, 0, false, true, true, false,
			      handle_returns_nonnull_attribute, NULL },
  { "omp declare simd",       0, -1, true,  false, false, false,
			      handle_omp_declare_simd_attribute, NULL },
  { "omp declare variant base", 0, -1, true,  false, false, false,
			      handle_omp_declare_variant_attribute, NULL },
  { "omp declare variant variant", 0, -1, true,  false, false, false,
			      handle_omp_declare_variant_attribute, NULL },
  { "simd",		      0, 1, true,  false, false, false,
			      handle_simd_attribute, NULL },
  { "omp declare target",     0, -1, true, false, false, false,
			      handle_omp_declare_target_attribute, NULL },
  { "omp declare target link", 0, 0, true, false, false, false,
			      handle_omp_declare_target_attribute, NULL },
  { "omp declare target implicit", 0, 0, true, false, false, false,
			      handle_omp_declare_target_attribute, NULL },
  { "omp declare target host", 0, 0, true, false, false, false,
			      handle_omp_declare_target_attribute, NULL },
  { "omp declare target nohost", 0, 0, true, false, false, false,
			      handle_omp_declare_target_attribute, NULL },
  { "omp declare target block", 0, 0, true, false, false, false,
			      handle_omp_declare_target_attribute, NULL },
  { "alloc_align",	      1, 1, false, true, true, false,
			      handle_alloc_align_attribute,
	                      attr_alloc_exclusions },
  { "assume_aligned",	      1, 2, false, true, true, false,
			      handle_assume_aligned_attribute, NULL },
  { "designated_init",        0, 0, false, true, false, false,
			      handle_designated_init_attribute, NULL },
  { "fallthrough",	      0, 0, false, false, false, false,
			      handle_fallthrough_attribute, NULL },
  { "patchable_function_entry",	1, 2, true, false, false, false,
			      handle_patchable_function_entry_attribute,
			      NULL },
  { "nocf_check",	      0, 0, false, true, true, true,
			      handle_nocf_check_attribute, NULL },
  { "symver",		      1, -1, true, false, false, false,
			      handle_symver_attribute, NULL},
  { "copy",                   1, 1, false, false, false, false,
			      handle_copy_attribute, NULL },
  { "noinit",		      0, 0, true,  false, false, false,
			      handle_special_var_sec_attribute, attr_section_exclusions },
  { "persistent",	      0, 0, true,  false, false, false,
			      handle_special_var_sec_attribute, attr_section_exclusions },
  { "access",		      1, 3, false, true, true, false,
			      handle_access_attribute, NULL },
  /* Attributes used by Objective-C.  */
  { "NSObject",		      0, 0, true, false, false, false,
			      handle_nsobject_attribute, NULL },
  { "objc_root_class",	      0, 0, true, false, false, false,
			      handle_objc_root_class_attribute, NULL },
  { "objc_nullability",	      1, 1, true, false, false, false,
			      handle_objc_nullability_attribute, NULL },
  { "*dealloc",                1, 2, true, false, false, false,
			      handle_dealloc_attribute, NULL },
  { NULL,                     0, 0, false, false, false, false, NULL, NULL }
};

/* Give the specifications for the format attributes, used by C and all
   descendants.

   Current list of processed format attributes: format, format_arg.  */
const struct attribute_spec c_common_format_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
       affects_type_identity, handler, exclude } */
  { "format",                 3, 3, false, true,  true, false,
			      handle_format_attribute, NULL },
  { "format_arg",             1, 1, false, true,  true, false,
			      handle_format_arg_attribute, NULL },
  { NULL,                     0, 0, false, false, false, false, NULL, NULL }
};

/* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain
   identifier as an argument, so the front end shouldn't look it up.  */

bool
attribute_takes_identifier_p (const_tree attr_id)
{
  const struct attribute_spec *spec = lookup_attribute_spec (attr_id);
  if (spec == NULL)
    /* Unknown attribute that we'll end up ignoring, return true so we
       don't complain about an identifier argument.  */
    return true;
  else if (!strcmp ("mode", spec->name)
	   || !strcmp ("format", spec->name)
	   || !strcmp ("cleanup", spec->name)
	   || !strcmp ("access", spec->name))
    return true;
  else
    return targetm.attribute_takes_identifier_p (attr_id);
}

/* Verify that argument value POS at position ARGNO to attribute NAME
   applied to function TYPE refers to a function parameter at position
   POS and the expected type CODE.  Treat CODE == INTEGER_TYPE as
   matching all C integral types except bool.  If successful, return
   POS after default conversions, if any.  Otherwise, issue appropriate
   warnings and return null.  A non-zero 1-based ARGNO should be passed
   in by callers only for attributes with more than one argument.  */

tree
positional_argument (const_tree fntype, const_tree atname, tree pos,
		     tree_code code, int argno /* = 0 */,
		     int flags /* = posargflags () */)
{
  if (pos && TREE_CODE (pos) != IDENTIFIER_NODE
      && TREE_CODE (pos) != FUNCTION_DECL)
    pos = default_conversion (pos);

  tree postype = TREE_TYPE (pos);
  if (pos == error_mark_node || !postype)
    {
      /* Only mention the positional argument number when it's non-zero.  */
      if (argno < 1)
	warning (OPT_Wattributes,
		 "%qE attribute argument is invalid", atname);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument %i is invalid", atname, argno);

      return NULL_TREE;
    }

  if (!INTEGRAL_TYPE_P (postype))
    {
      /* Handle this case specially to avoid mentioning the value
	 of pointer constants in diagnostics.  Only mention
	 the positional argument number when it's non-zero.  */
      if (argno < 1)
	warning (OPT_Wattributes,
		 "%qE attribute argument has type %qT",
		 atname, postype);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument %i has type %qT",
		 atname, argno, postype);

      return NULL_TREE;
    }

  if (TREE_CODE (pos) != INTEGER_CST)
    {
      /* Only mention the argument number when it's non-zero.  */
      if (argno < 1)
	warning (OPT_Wattributes,
		 "%qE attribute argument value %qE is not an integer "
		 "constant",
		 atname, pos);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument %i value %qE is not an integer "
		 "constant",
		 atname, argno, pos);

      return NULL_TREE;
    }

  /* Argument positions are 1-based.  */
  if (integer_zerop (pos))
    {
      if (flags & POSARG_ZERO)
	/* Zero is explicitly allowed.  */
	return pos;

      if (argno < 1)
	warning (OPT_Wattributes,
		 "%qE attribute argument value %qE does not refer to "
		 "a function parameter",
		 atname, pos);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument %i value %qE does not refer to "
		 "a function parameter",
		 atname, argno, pos);

      return NULL_TREE;
    }

  if (!prototype_p (fntype))
    return pos;

  /* Verify that the argument position does not exceed the number
     of formal arguments to the function.  When POSARG_ELLIPSIS
     is set, ARGNO may be beyond the last argument of a vararg
     function.  */
  unsigned nargs = type_num_arguments (fntype);
  if (!nargs
      || !tree_fits_uhwi_p (pos)
      || ((flags & POSARG_ELLIPSIS) == 0
	  && !IN_RANGE (tree_to_uhwi (pos), 1, nargs)))
    {

      if (argno < 1)
	warning (OPT_Wattributes,
		 "%qE attribute argument value %qE exceeds the number "
		 "of function parameters %u",
		 atname, pos, nargs);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument %i value %qE exceeds the number "
		 "of function parameters %u",
		 atname, argno, pos, nargs);
      return NULL_TREE;
    }

  /* Verify that the type of the referenced formal argument matches
     the expected type.  */
  unsigned HOST_WIDE_INT ipos = tree_to_uhwi (pos);

  /* Zero was handled above.  */
  gcc_assert (ipos != 0);

  if (tree argtype = type_argument_type (fntype, ipos))
    {
      if (argtype == error_mark_node)
	return NULL_TREE;

      if (flags & POSARG_ELLIPSIS)
	{
	  if (argno < 1)
	    error ("%qE attribute argument value %qE does not refer to "
		   "a variable argument list",
		   atname, pos);
	  else
	    error ("%qE attribute argument %i value %qE does not refer to "
		   "a variable argument list",
		   atname, argno, pos);
	  return NULL_TREE;
	}

      /* Where the expected code is STRING_CST accept any pointer
	 expected by attribute format (this includes possibly qualified
	 char pointers and, for targets like Darwin, also pointers to
	 struct CFString).  */
      bool type_match;
      if (code == STRING_CST)
	type_match = valid_format_string_type_p (argtype);
      else if (code == INTEGER_TYPE)
	/* For integers, accept enums, wide characters and other types
	   that match INTEGRAL_TYPE_P except for bool.  */
	type_match = (INTEGRAL_TYPE_P (argtype)
		      && TREE_CODE (argtype) != BOOLEAN_TYPE);
      else
	type_match = TREE_CODE (argtype) == code;

      if (!type_match)
	{
	  if (code == STRING_CST)
	    {
	      /* Reject invalid format strings with an error.  */
	      if (argno < 1)
		error ("%qE attribute argument value %qE refers to "
		       "parameter type %qT",
		       atname, pos, argtype);
	      else
		error ("%qE attribute argument %i value %qE refers to "
		       "parameter type %qT",
		       atname, argno, pos, argtype);

	      return NULL_TREE;
	    }

	  if (argno < 1)
	    warning (OPT_Wattributes,
		     "%qE attribute argument value %qE refers to "
		     "parameter type %qT",
		     atname, pos, argtype);
	  else
	    warning (OPT_Wattributes,
		   "%qE attribute argument %i value %qE refers to "
		     "parameter type %qT",
		     atname, argno, pos, argtype);
	  return NULL_TREE;
	}
    }
  else if (!(flags & POSARG_ELLIPSIS))
    {
      if (argno < 1)
	warning (OPT_Wattributes,
		 "%qE attribute argument value %qE refers to "
		 "a variadic function parameter of unknown type",
		 atname, pos);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument %i value %qE refers to "
		 "a variadic function parameter of unknown type",
		 atname, argno, pos);
      return NULL_TREE;
    }

  return pos;
}

/* Return the first of DECL or TYPE attributes installed in NODE if it's
   a DECL, or TYPE attributes if it's a TYPE, or null otherwise.  */

static tree
decl_or_type_attrs (tree node)
{
  if (DECL_P (node))
    {
      if (tree attrs = DECL_ATTRIBUTES (node))
	return attrs;

      tree type = TREE_TYPE (node);
      return TYPE_ATTRIBUTES (type);
    }

  if (TYPE_P (node))
    return TYPE_ATTRIBUTES (node);

  return NULL_TREE;
}

/* Given a pair of NODEs for arbitrary DECLs or TYPEs, validate one or
   two integral or string attribute arguments NEWARGS to be applied to
   NODE[0] for the absence of conflicts with the same attribute arguments
   already applied to NODE[1]. Issue a warning for conflicts and return
   false.  Otherwise, when no conflicts are found, return true.  */

static bool
validate_attr_args (tree node[2], tree name, tree newargs[2])
{
  /* First validate the arguments against those already applied to
     the same declaration (or type).  */
  tree self[2] = { node[0], node[0] };
  if (node[0] != node[1] && !validate_attr_args (self, name, newargs))
    return false;

  if (!node[1])
    return true;

  /* Extract the same attribute from the previous declaration or type.  */
  tree prevattr = decl_or_type_attrs (node[1]);
  const char* const namestr = IDENTIFIER_POINTER (name);
  prevattr = lookup_attribute (namestr, prevattr);
  if (!prevattr)
    return true;

  /* Extract one or both attribute arguments.  */
  tree prevargs[2];
  prevargs[0] = TREE_VALUE (TREE_VALUE (prevattr));
  prevargs[1] = TREE_CHAIN (TREE_VALUE (prevattr));
  if (prevargs[1])
    prevargs[1] = TREE_VALUE (prevargs[1]);

  /* Both arguments must be equal or, for the second pair, neither must
     be provided to succeed.  */
  bool arg1eq, arg2eq;
  if (TREE_CODE (newargs[0]) == INTEGER_CST)
    {
      arg1eq = tree_int_cst_equal (newargs[0], prevargs[0]);
      if (newargs[1] && prevargs[1])
	arg2eq = tree_int_cst_equal (newargs[1], prevargs[1]);
      else
	arg2eq = newargs[1] == prevargs[1];
    }
  else if (TREE_CODE (newargs[0]) == STRING_CST)
    {
      const char *s0 = TREE_STRING_POINTER (newargs[0]);
      const char *s1 = TREE_STRING_POINTER (prevargs[0]);
      arg1eq = strcmp (s0, s1) == 0;
      if (newargs[1] && prevargs[1])
	{
	  s0 = TREE_STRING_POINTER (newargs[1]);
	  s1 = TREE_STRING_POINTER (prevargs[1]);
	  arg2eq = strcmp (s0, s1) == 0;
	}
      else
	arg2eq = newargs[1] == prevargs[1];
    }
  else
    gcc_unreachable ();

  if (arg1eq && arg2eq)
    return true;

  /* If the two locations are different print a note pointing to
     the previous one.  */
  const location_t curloc = input_location;
  const location_t prevloc =
    DECL_P (node[1]) ? DECL_SOURCE_LOCATION (node[1]) : curloc;

  /* Format the attribute specification for convenience.  */
  char newspec[80], prevspec[80];
  if (newargs[1])
    snprintf (newspec, sizeof newspec, "%s (%s, %s)", namestr,
	      print_generic_expr_to_str (newargs[0]),
	      print_generic_expr_to_str (newargs[1]));
  else
    snprintf (newspec, sizeof newspec, "%s (%s)", namestr,
	      print_generic_expr_to_str (newargs[0]));

  if (prevargs[1])
    snprintf (prevspec, sizeof prevspec, "%s (%s, %s)", namestr,
	      print_generic_expr_to_str (prevargs[0]),
	      print_generic_expr_to_str (prevargs[1]));
  else
    snprintf (prevspec, sizeof prevspec, "%s (%s)", namestr,
	      print_generic_expr_to_str (prevargs[0]));

  if (warning_at (curloc, OPT_Wattributes,
		  "ignoring attribute %qs because it conflicts "
		  "with previous %qs",
		  newspec, prevspec)
      && curloc != prevloc)
    inform (prevloc, "previous declaration here");

  return false;
}

/* Convenience wrapper for validate_attr_args to validate a single
   attribute argument.  Used by handlers for attributes that take
   just a single argument.  */

static bool
validate_attr_arg (tree node[2], tree name, tree newarg)
{
  tree argarray[2] = { newarg, NULL_TREE };
  return validate_attr_args (node, name, argarray);
}

/* Attribute handlers common to C front ends.  */

/* Handle a "signed_bool_precision" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_signed_bool_precision_attribute (tree *node, tree name, tree args,
					int, bool *no_add_attrs)
{
  *no_add_attrs = true;
  if (!flag_gimple)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      return NULL_TREE;
    }

  if (!TYPE_P (*node) || TREE_CODE (*node) != BOOLEAN_TYPE)
    {
      warning (OPT_Wattributes, "%qE attribute only supported on "
	       "boolean types", name);
      return NULL_TREE;
    }

  unsigned HOST_WIDE_INT prec = HOST_WIDE_INT_M1U;
  if (tree_fits_uhwi_p (TREE_VALUE (args)))
    prec = tree_to_uhwi (TREE_VALUE (args));
  if (prec > MAX_FIXED_MODE_SIZE)
    {
      warning (OPT_Wattributes, "%qE attribute with unsupported boolean "
	       "precision", name);
      return NULL_TREE;
    }

  tree new_type = build_nonstandard_boolean_type (prec);
  *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);

  return NULL_TREE;
}

/* Handle a "packed" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			 int flags, bool *no_add_attrs)
{
  if (TYPE_P (*node))
    {
      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
	{
	  warning (OPT_Wattributes,
		   "%qE attribute ignored for type %qT", name, *node);
	  *no_add_attrs = true;
	}
      else
	TYPE_PACKED (*node) = 1;
    }
  else if (TREE_CODE (*node) == FIELD_DECL)
    {
      if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
	  /* Still pack bitfields.  */
	  && ! DECL_C_BIT_FIELD (*node))
	warning (OPT_Wattributes,
		 "%qE attribute ignored for field of type %qT",
		 name, TREE_TYPE (*node));
      else
	DECL_PACKED (*node) = 1;
    }
  /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
     used for DECL_REGISTER.  It wouldn't mean anything anyway.
     We can't set DECL_PACKED on the type of a TYPE_DECL, because
     that changes what the typedef is typing.  */
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "nocommon" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_nocommon_attribute (tree *node, tree name,
			   tree ARG_UNUSED (args),
			   int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (VAR_P (*node))
    DECL_COMMON (*node) = 0;
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "common" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			 int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (VAR_P (*node))
    DECL_COMMON (*node) = 1;
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "noreturn" attribute; arguments as in
   struct attribute_spec.handler.  */

tree
handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			   int ARG_UNUSED (flags), bool *no_add_attrs)
{
  tree type = TREE_TYPE (*node);

  /* See FIXME comment in c_common_attribute_table.  */
  if (TREE_CODE (*node) == FUNCTION_DECL
      || objc_method_decl (TREE_CODE (*node)))
    TREE_THIS_VOLATILE (*node) = 1;
  else if (TREE_CODE (type) == POINTER_TYPE
	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
    TREE_TYPE (*node)
      = (build_qualified_type
	 (build_pointer_type
	  (build_type_variant (TREE_TYPE (type),
			       TYPE_READONLY (TREE_TYPE (type)), 1)),
	  TYPE_QUALS (type)));
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "hot" and attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
		      int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL
      || TREE_CODE (*node) == LABEL_DECL)
    {
      /* Attribute hot processing is done later with lookup_attribute.  */
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "cold" and attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
		       int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL
      || TREE_CODE (*node) == LABEL_DECL)
    {
      /* Attribute cold processing is done later with lookup_attribute.  */
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Add FLAGS for a function NODE to no_sanitize_flags in DECL_ATTRIBUTES.  */

void
add_no_sanitize_value (tree node, unsigned int flags)
{
  tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (node));
  if (attr)
    {
      unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr));
      flags |= old_value;

      if (flags == old_value)
	return;

      TREE_VALUE (attr) = build_int_cst (unsigned_type_node, flags);
    }
  else
    DECL_ATTRIBUTES (node)
      = tree_cons (get_identifier ("no_sanitize"),
		   build_int_cst (unsigned_type_node, flags),
		   DECL_ATTRIBUTES (node));
}

/* Handle a "no_sanitize" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
			      bool *no_add_attrs)
{
  unsigned int flags = 0;
  *no_add_attrs = true;
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      return NULL_TREE;
    }

  for (; args; args = TREE_CHAIN (args))
    {
      tree id = TREE_VALUE (args);
      if (TREE_CODE (id) != STRING_CST)
	{
	  error ("%qE argument not a string", name);
	  return NULL_TREE;
	}

      char *string = ASTRDUP (TREE_STRING_POINTER (id));
      flags |= parse_no_sanitize_attribute (string);
    }

  add_no_sanitize_value (*node, flags);

  return NULL_TREE;
}

/* Handle a "no_sanitize_address" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_sanitize_address_attribute (tree *node, tree name, tree, int,
				      bool *no_add_attrs)
{
  *no_add_attrs = true;
  if (TREE_CODE (*node) != FUNCTION_DECL)
    warning (OPT_Wattributes, "%qE attribute ignored", name);
  else
    add_no_sanitize_value (*node, SANITIZE_ADDRESS);

  return NULL_TREE;
}

/* Handle a "no_sanitize_thread" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_sanitize_thread_attribute (tree *node, tree name, tree, int,
				      bool *no_add_attrs)
{
  *no_add_attrs = true;
  if (TREE_CODE (*node) != FUNCTION_DECL)
    warning (OPT_Wattributes, "%qE attribute ignored", name);
  else
    add_no_sanitize_value (*node, SANITIZE_THREAD);

  return NULL_TREE;
}


/* Handle a "no_address_safety_analysis" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int,
					     bool *no_add_attrs)
{
  *no_add_attrs = true;
  if (TREE_CODE (*node) != FUNCTION_DECL)
    warning (OPT_Wattributes, "%qE attribute ignored", name);
  else
    add_no_sanitize_value (*node, SANITIZE_ADDRESS);

  return NULL_TREE;
}

/* Handle a "no_sanitize_undefined" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
				      bool *no_add_attrs)
{
  *no_add_attrs = true;
  if (TREE_CODE (*node) != FUNCTION_DECL)
    warning (OPT_Wattributes, "%qE attribute ignored", name);
  else
    add_no_sanitize_value (*node,
			   SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);

  return NULL_TREE;
}

/* Handle a "no_sanitize_coverage" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int,
				       bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle an "asan odr indicator" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *)
{
  return NULL_TREE;
}

/* Handle a "stack_protect" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_stack_protect_attribute (tree *node, tree name, tree, int,
				bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "no_stack_protector" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_stack_protector_function_attribute (tree *node, tree name, tree,
					      int, bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "noipa" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_noipa_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "noinline" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_noinline_attribute (tree *node, tree name,
			   tree ARG_UNUSED (args),
			   int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL)
    {
      if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
	{
	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
		   "with attribute %qs", name, "always_inline");
	  *no_add_attrs = true;
	}
      else
	DECL_UNINLINABLE (*node) = 1;
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "noclone" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_noclone_attribute (tree *node, tree name,
			  tree ARG_UNUSED (args),
			  int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "nocf_check" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_nocf_check_attribute (tree *node, tree name,
			  tree ARG_UNUSED (args),
			  int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_TYPE
      && TREE_CODE (*node) != METHOD_TYPE)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }
  else if (!(flag_cf_protection & CF_BRANCH))
    {
      warning (OPT_Wattributes, "%qE attribute ignored. Use "
				"%<-fcf-protection%> option to enable it",
				name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "no_icf" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_noicf_attribute (tree *node, tree name,
			tree ARG_UNUSED (args),
			int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}


/* Handle a "always_inline" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_always_inline_attribute (tree *node, tree name,
				tree ARG_UNUSED (args),
				int ARG_UNUSED (flags),
				bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL)
    {
      if (lookup_attribute ("noinline", DECL_ATTRIBUTES (*node)))
	{
	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
		   "with %qs attribute", name, "noinline");
	  *no_add_attrs = true;
	}
      else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)))
	{
	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
		   "with %qs attribute", name, "target_clones");
	  *no_add_attrs = true;
	}
      else
	/* Set the attribute and mark it for disregarding inline
	   limits.  */
	DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "gnu_inline" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_gnu_inline_attribute (tree *node, tree name,
			     tree ARG_UNUSED (args),
			     int ARG_UNUSED (flags),
			     bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
    {
      /* Do nothing else, just set the attribute.  We'll get at
	 it later with lookup_attribute.  */
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "leaf" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_leaf_attribute (tree *node, tree name,
		       tree ARG_UNUSED (args),
		       int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }
  if (!TREE_PUBLIC (*node))
    {
      warning (OPT_Wattributes, "%qE attribute has no effect on unit local "
	       "functions", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle an "artificial" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_artificial_attribute (tree *node, tree name,
			     tree ARG_UNUSED (args),
			     int ARG_UNUSED (flags),
			     bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
    {
      /* Do nothing else, just set the attribute.  We'll get at
	 it later with lookup_attribute.  */
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "flatten" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_flatten_attribute (tree *node, tree name,
			  tree args ATTRIBUTE_UNUSED,
			  int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL)
    /* Do nothing else, just set the attribute.  We'll get at
       it later with lookup_attribute.  */
    ;
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "warning" or "error" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_error_attribute (tree *node, tree name, tree args,
			int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL
      && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
    /* Do nothing else, just set the attribute.  We'll get at
       it later with lookup_attribute.  */
    ;
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "used" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
		       int ARG_UNUSED (flags), bool *no_add_attrs)
{
  tree node = *pnode;

  if (TREE_CODE (node) == FUNCTION_DECL
      || (VAR_P (node) && TREE_STATIC (node))
      || (TREE_CODE (node) == TYPE_DECL))
    {
      TREE_USED (node) = 1;
      DECL_PRESERVE_P (node) = 1;
      if (VAR_P (node))
	DECL_READ_P (node) = 1;
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "unused" attribute; arguments as in
   struct attribute_spec.handler.  */

tree
handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			 int flags, bool *no_add_attrs)
{
  if (DECL_P (*node))
    {
      tree decl = *node;

      if (TREE_CODE (decl) == PARM_DECL
	  || VAR_OR_FUNCTION_DECL_P (decl)
	  || TREE_CODE (decl) == LABEL_DECL
	  || TREE_CODE (decl) == CONST_DECL
	  || TREE_CODE (decl) == FIELD_DECL
	  || TREE_CODE (decl) == TYPE_DECL)
	{
	  TREE_USED (decl) = 1;
	  if (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
	    DECL_READ_P (decl) = 1;
	}
      else
	{
	  warning (OPT_Wattributes, "%qE attribute ignored", name);
	  *no_add_attrs = true;
	}
    }
  else
    {
      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
	*node = build_variant_type_copy (*node);
      TREE_USED (*node) = 1;
    }

  return NULL_TREE;
}

/* Handle a "retain" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_retain_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
			 int ARG_UNUSED (flags), bool *no_add_attrs)
{
  tree node = *pnode;

  if (SUPPORTS_SHF_GNU_RETAIN
      && (TREE_CODE (node) == FUNCTION_DECL
	  || (VAR_P (node) && TREE_STATIC (node))))
    ;
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "externally_visible" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_externally_visible_attribute (tree *pnode, tree name,
				     tree ARG_UNUSED (args),
				     int ARG_UNUSED (flags),
				     bool *no_add_attrs)
{
  tree node = *pnode;

  if (VAR_OR_FUNCTION_DECL_P (node))
    {
      if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL
	   && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node))
	{
	  warning (OPT_Wattributes,
		   "%qE attribute have effect only on public objects", name);
	  *no_add_attrs = true;
	}
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle the "no_reorder" attribute.  Arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_reorder_attribute (tree *pnode,
			     tree name,
			     tree,
			     int,
			     bool *no_add_attrs)
{
  tree node = *pnode;

  if (!VAR_OR_FUNCTION_DECL_P (node)
	&& !(TREE_STATIC (node) || DECL_EXTERNAL (node)))
    {
      warning (OPT_Wattributes,
		"%qE attribute only affects top level objects",
		name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "const" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			int flags, bool *no_add_attrs)
{
  tree type = TREE_TYPE (*node);

  /* See FIXME comment on noreturn in c_common_attribute_table.  */
  if (TREE_CODE (*node) == FUNCTION_DECL)
    TREE_READONLY (*node) = 1;
  else if (TREE_CODE (type) == POINTER_TYPE
	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
    TREE_TYPE (*node)
      = (build_qualified_type
	 (build_pointer_type
	  (build_type_variant (TREE_TYPE (type), 1,
			       TREE_THIS_VOLATILE (TREE_TYPE (type)))),
	  TYPE_QUALS (type)));
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  /* void __builtin_unreachable(void) is const.  Accept other such
     built-ins but warn on user-defined functions that return void.  */
  if (!(flags & ATTR_FLAG_BUILT_IN)
      && TREE_CODE (*node) == FUNCTION_DECL
      && VOID_TYPE_P (TREE_TYPE (type)))
    warning (OPT_Wattributes, "%qE attribute on function "
	     "returning %<void%>", name);

  return NULL_TREE;
}

/* Handle a "scalar_storage_order" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
				       int flags, bool *no_add_attrs)
{
  tree id = TREE_VALUE (args);
  tree type;

  if (TREE_CODE (*node) == TYPE_DECL
      && ! (flags & ATTR_FLAG_CXX11))
    node = &TREE_TYPE (*node);
  type = *node;

  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
    {
      error ("%qE attribute is not supported because endianness is not uniform",
	     name);
      return NULL_TREE;
    }

  if (RECORD_OR_UNION_TYPE_P (type) && !c_dialect_cxx ())
    {
      bool reverse = false;

      if (TREE_CODE (id) == STRING_CST
	  && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0)
	reverse = !BYTES_BIG_ENDIAN;
      else if (TREE_CODE (id) == STRING_CST
	       && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0)
	reverse = BYTES_BIG_ENDIAN;
      else
	{
	  error ("attribute %qE argument must be one of %qs or %qs",
		 name, "big-endian", "little-endian");
	  return NULL_TREE;
	}

      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
	{
	  if (reverse)
	    /* A type variant isn't good enough, since we don't want a cast
	       to such a type to be removed as a no-op.  */
	    *node = type = build_duplicate_type (type);
	}

      TYPE_REVERSE_STORAGE_ORDER (type) = reverse;
      return NULL_TREE;
    }

  warning (OPT_Wattributes, "%qE attribute ignored", name);
  *no_add_attrs = true;
  return NULL_TREE;
}

/* Handle a "transparent_union" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_transparent_union_attribute (tree *node, tree name,
				    tree ARG_UNUSED (args), int flags,
				    bool *no_add_attrs)
{
  tree type;

  *no_add_attrs = true;

  if (TREE_CODE (*node) == TYPE_DECL
      && ! (flags & ATTR_FLAG_CXX11))
    node = &TREE_TYPE (*node);
  type = *node;

  if (TREE_CODE (type) == UNION_TYPE)
    {
      /* Make sure that the first field will work for a transparent union.
	 If the type isn't complete yet, leave the check to the code in
	 finish_struct.  */
      if (TYPE_SIZE (type))
	{
	  tree first = first_field (type);
	  if (first == NULL_TREE
	      || DECL_ARTIFICIAL (first)
	      || TYPE_MODE (type) != DECL_MODE (first))
	    goto ignored;
	}

      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
	{
	  /* If the type isn't complete yet, setting the flag
	     on a variant wouldn't ever be checked.  */
	  if (!TYPE_SIZE (type))
	    goto ignored;

	  /* build_duplicate_type doesn't work for C++.  */
	  if (c_dialect_cxx ())
	    goto ignored;

	  /* A type variant isn't good enough, since we don't want a cast
	     to such a type to be removed as a no-op.  */
	  *node = type = build_duplicate_type (type);
	}

      for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
	TYPE_TRANSPARENT_AGGR (t) = 1;
      return NULL_TREE;
    }

 ignored:
  warning (OPT_Wattributes, "%qE attribute ignored", name);
  return NULL_TREE;
}

/* Subroutine of handle_{con,de}structor_attribute.  Evaluate ARGS to
   get the requested priority for a constructor or destructor,
   possibly issuing diagnostics for invalid or reserved
   priorities.  */

static priority_type
get_priority (tree args, bool is_destructor)
{
  HOST_WIDE_INT pri;
  tree arg;

  if (!args)
    return DEFAULT_INIT_PRIORITY;

  if (!SUPPORTS_INIT_PRIORITY)
    {
      if (is_destructor)
	error ("destructor priorities are not supported");
      else
	error ("constructor priorities are not supported");
      return DEFAULT_INIT_PRIORITY;
    }

  arg = TREE_VALUE (args);
  if (TREE_CODE (arg) == IDENTIFIER_NODE)
    goto invalid;
  if (arg == error_mark_node)
    return DEFAULT_INIT_PRIORITY;
  arg = default_conversion (arg);
  if (!tree_fits_shwi_p (arg)
      || !INTEGRAL_TYPE_P (TREE_TYPE (arg)))
    goto invalid;

  pri = tree_to_shwi (arg);
  if (pri < 0 || pri > MAX_INIT_PRIORITY)
    goto invalid;

  if (pri <= MAX_RESERVED_INIT_PRIORITY)
    {
      if (is_destructor)
	warning (OPT_Wprio_ctor_dtor,
		 "destructor priorities from 0 to %d are reserved "
		 "for the implementation",
		 MAX_RESERVED_INIT_PRIORITY);
      else
	warning (OPT_Wprio_ctor_dtor,
		 "constructor priorities from 0 to %d are reserved "
		 "for the implementation",
		 MAX_RESERVED_INIT_PRIORITY);
    }
  return pri;

 invalid:
  if (is_destructor)
    error ("destructor priorities must be integers from 0 to %d inclusive",
	   MAX_INIT_PRIORITY);
  else
    error ("constructor priorities must be integers from 0 to %d inclusive",
	   MAX_INIT_PRIORITY);
  return DEFAULT_INIT_PRIORITY;
}

/* Handle a "constructor" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_constructor_attribute (tree *node, tree name, tree args,
			      int ARG_UNUSED (flags),
			      bool *no_add_attrs)
{
  tree decl = *node;
  tree type = TREE_TYPE (decl);

  if (TREE_CODE (decl) == FUNCTION_DECL
      && TREE_CODE (type) == FUNCTION_TYPE
      && decl_function_context (decl) == 0)
    {
      priority_type priority;
      DECL_STATIC_CONSTRUCTOR (decl) = 1;
      priority = get_priority (args, /*is_destructor=*/false);
      SET_DECL_INIT_PRIORITY (decl, priority);
      TREE_USED (decl) = 1;
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "destructor" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_destructor_attribute (tree *node, tree name, tree args,
			     int ARG_UNUSED (flags),
			     bool *no_add_attrs)
{
  tree decl = *node;
  tree type = TREE_TYPE (decl);

  if (TREE_CODE (decl) == FUNCTION_DECL
      && TREE_CODE (type) == FUNCTION_TYPE
      && decl_function_context (decl) == 0)
    {
      priority_type priority;
      DECL_STATIC_DESTRUCTOR (decl) = 1;
      priority = get_priority (args, /*is_destructor=*/true);
      SET_DECL_FINI_PRIORITY (decl, priority);
      TREE_USED (decl) = 1;
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Nonzero if the mode is a valid vector mode for this architecture.
   This returns nonzero even if there is no hardware support for the
   vector mode, but we can emulate with narrower modes.  */

static bool
vector_mode_valid_p (machine_mode mode)
{
  enum mode_class mclass = GET_MODE_CLASS (mode);

  /* Doh!  What's going on?  */
  if (mclass != MODE_VECTOR_INT
      && mclass != MODE_VECTOR_FLOAT
      && mclass != MODE_VECTOR_FRACT
      && mclass != MODE_VECTOR_UFRACT
      && mclass != MODE_VECTOR_ACCUM
      && mclass != MODE_VECTOR_UACCUM)
    return false;

  /* Hardware support.  Woo hoo!  */
  if (targetm.vector_mode_supported_p (mode))
    return true;

  /* We should probably return 1 if requesting V4DI and we have no DI,
     but we have V2DI, but this is probably very unlikely.  */

  /* If we have support for the inner mode, we can safely emulate it.
     We may not have V2DI, but me can emulate with a pair of DIs.  */
  return targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
}


/* Handle a "mode" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_mode_attribute (tree *node, tree name, tree args,
		       int ARG_UNUSED (flags), bool *no_add_attrs)
{
  tree type = *node;
  tree ident = TREE_VALUE (args);

  *no_add_attrs = true;

  if (TREE_CODE (ident) != IDENTIFIER_NODE)
    warning (OPT_Wattributes, "%qE attribute ignored", name);
  else
    {
      int j;
      const char *p = IDENTIFIER_POINTER (ident);
      int len = strlen (p);
      machine_mode mode = VOIDmode;
      tree typefm;
      bool valid_mode;

      if (len > 4 && p[0] == '_' && p[1] == '_'
	  && p[len - 1] == '_' && p[len - 2] == '_')
	{
	  char *newp = (char *) alloca (len - 1);

	  strcpy (newp, &p[2]);
	  newp[len - 4] = '\0';
	  p = newp;
	}

      /* Change this type to have a type with the specified mode.
	 First check for the special modes.  */
      if (!strcmp (p, "byte"))
	mode = byte_mode;
      else if (!strcmp (p, "word"))
	mode = word_mode;
      else if (!strcmp (p, "pointer"))
	mode = ptr_mode;
      else if (!strcmp (p, "libgcc_cmp_return"))
	mode = targetm.libgcc_cmp_return_mode ();
      else if (!strcmp (p, "libgcc_shift_count"))
	mode = targetm.libgcc_shift_count_mode ();
      else if (!strcmp (p, "unwind_word"))
	mode = targetm.unwind_word_mode ();
      else
	for (j = 0; j < NUM_MACHINE_MODES; j++)
	  if (!strcmp (p, GET_MODE_NAME (j)))
	    {
	      mode = (machine_mode) j;
	      break;
	    }

      if (mode == VOIDmode)
	{
	  error ("unknown machine mode %qE", ident);
	  return NULL_TREE;
	}

      /* Allow the target a chance to translate MODE into something supported.
	 See PR86324.  */
      mode = targetm.translate_mode_attribute (mode);

      valid_mode = false;
      switch (GET_MODE_CLASS (mode))
	{
	case MODE_INT:
	case MODE_PARTIAL_INT:
	case MODE_FLOAT:
	case MODE_DECIMAL_FLOAT:
	case MODE_FRACT:
	case MODE_UFRACT:
	case MODE_ACCUM:
	case MODE_UACCUM:
	  valid_mode
	    = targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode));
	  break;

	case MODE_COMPLEX_INT:
	case MODE_COMPLEX_FLOAT:
	  valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
	  break;

	case MODE_VECTOR_INT:
	case MODE_VECTOR_FLOAT:
	case MODE_VECTOR_FRACT:
	case MODE_VECTOR_UFRACT:
	case MODE_VECTOR_ACCUM:
	case MODE_VECTOR_UACCUM:
	  warning (OPT_Wattributes, "specifying vector types with "
		   "%<__attribute__ ((mode))%> is deprecated");
	  inform (input_location,
		  "use %<__attribute__ ((vector_size))%> instead");
	  valid_mode = vector_mode_valid_p (mode);
	  break;

	default:
	  break;
	}
      if (!valid_mode)
	{
	  error ("unable to emulate %qs", p);
	  return NULL_TREE;
	}

      if (POINTER_TYPE_P (type))
	{
	  scalar_int_mode addr_mode;
	  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
	  tree (*fn)(tree, machine_mode, bool);

	  if (!is_a <scalar_int_mode> (mode, &addr_mode)
	      || !targetm.addr_space.valid_pointer_mode (addr_mode, as))
	    {
	      error ("invalid pointer mode %qs", p);
	      return NULL_TREE;
	    }

	  if (TREE_CODE (type) == POINTER_TYPE)
	    fn = build_pointer_type_for_mode;
	  else
	    fn = build_reference_type_for_mode;
	  typefm = fn (TREE_TYPE (type), addr_mode, false);
	}
      else
	{
	  /* For fixed-point modes, we need to test if the signness of type
	     and the machine mode are consistent.  */
	  if (ALL_FIXED_POINT_MODE_P (mode)
	      && TYPE_UNSIGNED (type) != UNSIGNED_FIXED_POINT_MODE_P (mode))
	    {
	      error ("signedness of type and machine mode %qs don%'t match", p);
	      return NULL_TREE;
	    }
	  /* For fixed-point modes, we need to pass saturating info.  */
	  typefm = lang_hooks.types.type_for_mode (mode,
			ALL_FIXED_POINT_MODE_P (mode) ? TYPE_SATURATING (type)
						      : TYPE_UNSIGNED (type));
	}

      if (typefm == NULL_TREE)
	{
	  error ("no data type for mode %qs", p);
	  return NULL_TREE;
	}
      else if (TREE_CODE (type) == ENUMERAL_TYPE)
	{
	  /* For enumeral types, copy the precision from the integer
	     type returned above.  If not an INTEGER_TYPE, we can't use
	     this mode for this type.  */
	  if (TREE_CODE (typefm) != INTEGER_TYPE)
	    {
	      error ("cannot use mode %qs for enumerated types", p);
	      return NULL_TREE;
	    }

	  if (flags & ATTR_FLAG_TYPE_IN_PLACE)
	    {
	      TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
	      typefm = type;
	    }
	  else
	    {
	      /* We cannot build a type variant, as there's code that assumes
		 that TYPE_MAIN_VARIANT has the same mode.  This includes the
		 debug generators.  Instead, create a subrange type.  This
		 results in all of the enumeral values being emitted only once
		 in the original, and the subtype gets them by reference.  */
	      if (TYPE_UNSIGNED (type))
		typefm = make_unsigned_type (TYPE_PRECISION (typefm));
	      else
		typefm = make_signed_type (TYPE_PRECISION (typefm));
	      TREE_TYPE (typefm) = type;
	    }
	  *no_add_attrs = false;
	}
      else if (VECTOR_MODE_P (mode)
	       ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
	       : TREE_CODE (type) != TREE_CODE (typefm))
	{
	  error ("mode %qs applied to inappropriate type", p);
	  return NULL_TREE;
	}

      *node = build_qualified_type (typefm, TYPE_QUALS (type));
    }

  return NULL_TREE;
}

/* Handle a "section" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_section_attribute (tree *node, tree name, tree args,
			  int flags, bool *no_add_attrs)
{
  tree decl = *node;
  tree res = NULL_TREE;
  tree argval = TREE_VALUE (args);
  const char* new_section_name;

  if (!targetm_common.have_named_sections)
    {
      error_at (DECL_SOURCE_LOCATION (*node),
		"section attributes are not supported for this target");
      goto fail;
    }

  if (!VAR_OR_FUNCTION_DECL_P (decl))
    {
      error ("section attribute not allowed for %q+D", *node);
      goto fail;
    }

  if (TREE_CODE (argval) != STRING_CST)
    {
      error ("section attribute argument not a string constant");
      goto fail;
    }

  if (VAR_P (decl)
      && current_function_decl != NULL_TREE
      && !TREE_STATIC (decl))
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"section attribute cannot be specified for local variables");
      goto fail;
    }

  new_section_name = TREE_STRING_POINTER (argval);

  /* The decl may have already been given a section attribute
     from a previous declaration.  Ensure they match.  */
  if (const char* const old_section_name = DECL_SECTION_NAME (decl))
    if (strcmp (old_section_name, new_section_name) != 0)
      {
	error ("section of %q+D conflicts with previous declaration",
	       *node);
	goto fail;
      }

  if (VAR_P (decl)
      && !targetm.have_tls && targetm.emutls.tmpl_section
      && DECL_THREAD_LOCAL_P (decl))
    {
      error ("section of %q+D cannot be overridden", *node);
      goto fail;
    }

  if (!validate_attr_arg (node, name, argval))
    goto fail;

  res = targetm.handle_generic_attribute (node, name, args, flags,
					  no_add_attrs);

  /* If the back end confirms the attribute can be added then continue onto
     final processing.  */
  if (!(*no_add_attrs))
    {
      set_decl_section_name (decl, new_section_name);
      return res;
    }

fail:
  *no_add_attrs = true;
  return res;
}

/* Common codes shared by handle_warn_if_not_aligned_attribute and
   handle_aligned_attribute.  */

static tree
common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
				 bool *no_add_attrs,
				 bool warn_if_not_aligned_p)
{
  tree decl = NULL_TREE;
  tree *type = NULL;
  bool is_type = false;
  tree align_expr;

  /* The last (already pushed) declaration with all validated attributes
     merged in or the current about-to-be-pushed one if one hasn't been
     yet.  */
  tree last_decl = node[1] ? node[1] : *node;

  if (args)
    {
      align_expr = TREE_VALUE (args);
      if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE
	  && TREE_CODE (align_expr) != FUNCTION_DECL)
	align_expr = default_conversion (align_expr);
    }
  else
    align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);

  if (DECL_P (*node))
    {
      decl = *node;
      type = &TREE_TYPE (decl);
      is_type = TREE_CODE (*node) == TYPE_DECL;
    }
  else if (TYPE_P (*node))
    type = node, is_type = true;

  /* True to consider invalid alignments greater than MAX_OFILE_ALIGNMENT.  */
  bool objfile = (TREE_CODE (*node) == FUNCTION_DECL
		  || (VAR_P (*node) && TREE_STATIC (*node)));
  /* Log2 of specified alignment.  */
  int pow2align = check_user_alignment (align_expr, objfile,
					/* warn_zero = */ true);
  if (pow2align == -1)
    {
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* The alignment in bits corresponding to the specified alignment.  */
  unsigned bitalign = (1U << pow2align) * BITS_PER_UNIT;

  /* The alignment of the current declaration and that of the last
     pushed declaration, determined on demand below.  */
  unsigned curalign = 0;
  unsigned lastalign = 0;

  /* True when SET_DECL_ALIGN() should be called for the decl when
     *NO_ADD_ATTRS is false.  */
  bool set_align = true;
  if (is_type)
    {
      if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
	/* OK, modify the type in place.  */;
      /* If we have a TYPE_DECL, then copy the type, so that we
	 don't accidentally modify a builtin type.  See pushdecl.  */
      else if (decl && TREE_TYPE (decl) != error_mark_node
	       && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
	{
	  tree tt = TREE_TYPE (decl);
	  *type = build_variant_type_copy (*type);
	  DECL_ORIGINAL_TYPE (decl) = tt;
	  TYPE_NAME (*type) = decl;
	  TREE_USED (*type) = TREE_USED (decl);
	  TREE_TYPE (decl) = *type;
	}
      else
	*type = build_variant_type_copy (*type);

      if (warn_if_not_aligned_p)
	{
	  SET_TYPE_WARN_IF_NOT_ALIGN (*type, bitalign);
	  warn_if_not_aligned_p = false;
	}
      else
	{
	  SET_TYPE_ALIGN (*type, bitalign);
	  TYPE_USER_ALIGN (*type) = 1;
	}
    }
  else if (! VAR_OR_FUNCTION_DECL_P (decl)
	   && TREE_CODE (decl) != FIELD_DECL)
    {
      error ("alignment may not be specified for %q+D", decl);
      *no_add_attrs = true;
    }
  else if (TREE_CODE (decl) == FUNCTION_DECL
	   && (((curalign = DECL_ALIGN (decl)) > bitalign)
	       | ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
    {
      /* Either a prior attribute on the same declaration or one
	 on a prior declaration of the same function specifies
	 stricter alignment than this attribute.  */
      bool note = (lastalign > curalign
		   || (lastalign == curalign
		       && (DECL_USER_ALIGN (last_decl)
			   > DECL_USER_ALIGN (decl))));
      if (note)
	curalign = lastalign;

      curalign /= BITS_PER_UNIT;
      unsigned newalign = bitalign / BITS_PER_UNIT;

      auto_diagnostic_group d;
      if ((DECL_USER_ALIGN (decl)
	   || DECL_USER_ALIGN (last_decl)))
	{
	  if (warning (OPT_Wattributes,
		       "ignoring attribute %<%E (%u)%> because it conflicts "
		       "with attribute %<%E (%u)%>",
		       name, newalign, name, curalign)
	      && note)
	    inform (DECL_SOURCE_LOCATION (last_decl),
		    "previous declaration here");
	  /* Only reject attempts to relax/override an alignment
	     explicitly specified previously and accept declarations
	     that appear to relax the implicit function alignment for
	     the target.  Both increasing and increasing the alignment
	     set by -falign-functions setting is permitted.  */
	  *no_add_attrs = true;
	}
      else if (!warn_if_not_aligned_p)
	{
	  /* Do not fail for attribute warn_if_not_aligned.  Otherwise,
	     silently avoid applying the alignment to the declaration
	     because it's implicitly satisfied by the target.  Apply
	     the attribute nevertheless so it can be retrieved by
	     __builtin_has_attribute.  */
	  set_align = false;
	}
    }
  else if (DECL_USER_ALIGN (decl)
	   && DECL_ALIGN (decl) > bitalign)
    /* C++-11 [dcl.align/4]:

	   When multiple alignment-specifiers are specified for an
	   entity, the alignment requirement shall be set to the
	   strictest specified alignment.

      This formally comes from the c++11 specification but we are
      doing it for the GNU attribute syntax as well.  */
    *no_add_attrs = true;
  else if (warn_if_not_aligned_p
	   && TREE_CODE (decl) == FIELD_DECL
	   && !DECL_C_BIT_FIELD (decl))
    {
      SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign);
      warn_if_not_aligned_p = false;
      set_align = false;
    }

  if (warn_if_not_aligned_p)
    {
      error ("%<warn_if_not_aligned%> may not be specified for %q+D",
	     decl);
      *no_add_attrs = true;
    }
  else if (!is_type && !*no_add_attrs && set_align)
    {
      SET_DECL_ALIGN (decl, bitalign);
      DECL_USER_ALIGN (decl) = 1;
    }

  return NULL_TREE;
}

/* Handle a "aligned" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_aligned_attribute (tree *node, tree name, tree args,
			  int flags, bool *no_add_attrs)
{
  return common_handle_aligned_attribute (node, name, args, flags,
					 no_add_attrs, false);
}

/* Handle a "warn_if_not_aligned" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_warn_if_not_aligned_attribute (tree *node, tree name,
				      tree args, int flags,
				      bool *no_add_attrs)
{
  return common_handle_aligned_attribute (node, name, args, flags,
					  no_add_attrs, true);
}

/* Handle a "weak" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_weak_attribute (tree *node, tree name,
		       tree ARG_UNUSED (args),
		       int ARG_UNUSED (flags),
		       bool * ARG_UNUSED (no_add_attrs))
{
  if (TREE_CODE (*node) == FUNCTION_DECL
      && DECL_DECLARED_INLINE_P (*node))
    {
      warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
      *no_add_attrs = true;
    }
  else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
    {
      error ("indirect function %q+D cannot be declared weak", *node);
      *no_add_attrs = true;
      return NULL_TREE;
    }
  else if (VAR_OR_FUNCTION_DECL_P (*node))
    declare_weak (*node);
  else
    warning (OPT_Wattributes, "%qE attribute ignored", name);

  return NULL_TREE;
}

/* Handle a "noinit" or "persistent" attribute; arguments as in
   struct attribute_spec.handler.
   This generic handler is used for "special variable sections" that allow the
   section name to be set using a dedicated attribute.  Additional validation
   is performed for the specific properties of the section corresponding to the
   attribute.
   The ".noinit" section *is not* loaded by the program loader, and is not
   initialized by the runtime startup code.
   The ".persistent" section *is* loaded by the program loader, but is not
   initialized by the runtime startup code.  */
static tree
handle_special_var_sec_attribute (tree *node, tree name, tree args,
				  int flags, bool *no_add_attrs)
{
  tree decl = *node;
  tree res = NULL_TREE;

  /* First perform generic validation common to "noinit" and "persistent"
     attributes.  */
  if (!targetm_common.have_named_sections)
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"section attributes are not supported for this target");
      goto fail;
    }

  if (!VAR_P (decl))
    {
      warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
		  "ignoring %qE attribute not set on a variable",
		  name);
      goto fail;
    }

  if (VAR_P (decl)
      && current_function_decl != NULL_TREE
      && !TREE_STATIC (decl))
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"%qE attribute cannot be specified for local variables",
		name);
      goto fail;
    }

  if (VAR_P (decl)
      && !targetm.have_tls && targetm.emutls.tmpl_section
      && DECL_THREAD_LOCAL_P (decl))
    {
      error ("section of %q+D cannot be overridden", decl);
      goto fail;
    }

  if (!targetm.have_switchable_bss_sections)
    {
      error ("%qE attribute is specific to ELF targets", name);
      goto fail;
    }

  if (TREE_READONLY (decl))
    {
      warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
		  "ignoring %qE attribute set on const variable",
		  name);
      goto fail;
    }

  /* Now validate noinit/persistent individually.  */
  if (strcmp (IDENTIFIER_POINTER (name), "noinit") == 0)
    {
      if (DECL_INITIAL (decl))
	{
	  warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
		      "ignoring %qE attribute set on initialized variable",
		      name);
	  goto fail;
	}
      /* If this var is thought to be common, then change this.  "noinit"
	 variables must be placed in an explicit ".noinit" section.  */
      DECL_COMMON (decl) = 0;
    }
  else if (strcmp (IDENTIFIER_POINTER (name), "persistent") == 0)
    {
      if (DECL_COMMON (decl) || DECL_INITIAL (decl) == NULL_TREE)
	{
	  warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
		      "ignoring %qE attribute set on uninitialized variable",
		      name);
	  goto fail;
	}
    }
  else
    gcc_unreachable ();

  res = targetm.handle_generic_attribute (node, name, args, flags,
					  no_add_attrs);

  /* If the back end confirms the attribute can be added then continue onto
     final processing.  */
  if (!(*no_add_attrs))
    return res;

fail:
  *no_add_attrs = true;
  return res;
}

/* Handle a "noplt" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_noplt_attribute (tree *node, tree name,
		       tree ARG_UNUSED (args),
		       int ARG_UNUSED (flags),
		       bool * ARG_UNUSED (no_add_attrs))
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes,
	       "%qE attribute is only applicable on functions", name);
      *no_add_attrs = true;
      return NULL_TREE;
    }
  return NULL_TREE;
}

/* Handle a "symver" attribute.  */

static tree
handle_symver_attribute (tree *node, tree ARG_UNUSED (name), tree args,
			 int ARG_UNUSED (flags), bool *no_add_attrs)
{
  tree symver;
  const char *symver_str;

  if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
    {
      warning (OPT_Wattributes,
	       "%<symver%> attribute only applies to functions and variables");
      *no_add_attrs = true;
      return NULL_TREE;
    }

  if (!decl_in_symtab_p (*node))
    {
      warning (OPT_Wattributes,
	       "%<symver%> attribute is only applicable to symbols");
      *no_add_attrs = true;
      return NULL_TREE;
    }

  for (; args; args = TREE_CHAIN (args))
    {
      symver = TREE_VALUE (args);
      if (TREE_CODE (symver) != STRING_CST)
	{
	  error ("%<symver%> attribute argument not a string constant");
	  *no_add_attrs = true;
	  return NULL_TREE;
	}

      symver_str = TREE_STRING_POINTER (symver);

      int ats = 0;
      for (int n = 0; (int)n < TREE_STRING_LENGTH (symver); n++)
	if (symver_str[n] == '@')
	  ats++;

      if (ats != 1 && ats != 2)
	{
	  error ("symver attribute argument must have format %<name@nodename%>");
	  error ("%<symver%> attribute argument %qs must contain one or two "
		 "%<@%>", symver_str);
	  *no_add_attrs = true;
	  return NULL_TREE;
	}
    }

  return NULL_TREE;
}


/* Handle an "alias" or "ifunc" attribute; arguments as in
   struct attribute_spec.handler, except that IS_ALIAS tells us
   whether this is an alias as opposed to ifunc attribute.  */

static tree
handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args,
			      bool *no_add_attrs)
{
  tree decl = *node;

  if (TREE_CODE (decl) != FUNCTION_DECL
      && (!is_alias || !VAR_P (decl)))
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }
  else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
      || (TREE_CODE (decl) != FUNCTION_DECL
	  && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
      /* A static variable declaration is always a tentative definition,
	 but the alias is a non-tentative definition which overrides.  */
      || (TREE_CODE (decl) != FUNCTION_DECL
	  && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
    {
      error ("%q+D defined both normally and as %qE attribute", decl, name);
      *no_add_attrs = true;
      return NULL_TREE;
    }
  else if (!is_alias
	   && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
	       || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))))
    {
      error ("weak %q+D cannot be defined %qE", decl, name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* Note that the very first time we process a nested declaration,
     decl_function_context will not be set.  Indeed, *would* never
     be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that
     we do below.  After such frobbery, pushdecl would set the context.
     In any case, this is never what we want.  */
  else if (decl_function_context (decl) == 0 && current_function_decl == NULL)
    {
      tree id;

      id = TREE_VALUE (args);
      if (TREE_CODE (id) != STRING_CST)
	{
	  error ("attribute %qE argument not a string", name);
	  *no_add_attrs = true;
	  return NULL_TREE;
	}
      id = get_identifier (TREE_STRING_POINTER (id));
      /* This counts as a use of the object pointed to.  */
      TREE_USED (id) = 1;

      if (TREE_CODE (decl) == FUNCTION_DECL)
	DECL_INITIAL (decl) = error_mark_node;
      else
	TREE_STATIC (decl) = 1;

      if (!is_alias)
	{
	  /* ifuncs are also aliases, so set that attribute too.  */
	  DECL_ATTRIBUTES (decl)
	    = tree_cons (get_identifier ("alias"), args,
			 DECL_ATTRIBUTES (decl));
	  DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"),
					      NULL, DECL_ATTRIBUTES (decl));
	}
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  if (decl_in_symtab_p (*node))
    {
      struct symtab_node *n = symtab_node::get (decl);
      if (n && n->refuse_visibility_changes)
	error ("%+qD declared %qs after being used",
	       decl, is_alias ? "alias" : "ifunc");
    }


  return NULL_TREE;
}

/* Handle an "alias" or "ifunc" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_ifunc_attribute (tree *node, tree name, tree args,
			int ARG_UNUSED (flags), bool *no_add_attrs)
{
  return handle_alias_ifunc_attribute (false, node, name, args, no_add_attrs);
}

/* Handle an "alias" or "ifunc" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_alias_attribute (tree *node, tree name, tree args,
			int ARG_UNUSED (flags), bool *no_add_attrs)
{
  return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs);
}

/* Handle the "copy" attribute NAME by copying the set of attributes
   from the symbol referenced by ARGS to the declaration of *NODE.  */

static tree
handle_copy_attribute (tree *node, tree name, tree args,
		       int flags, bool *no_add_attrs)
{
  /* Do not apply the copy attribute itself.  It serves no purpose
     other than to copy other attributes.  */
  *no_add_attrs = true;

  tree decl = *node;

  tree ref = TREE_VALUE (args);
  if (ref == error_mark_node)
    return NULL_TREE;

  if (TREE_CODE (ref) == STRING_CST)
    {
      /* Explicitly handle this case since using a string literal
	 as an argument is a likely mistake.  */
      error_at (DECL_SOURCE_LOCATION (decl),
		"%qE attribute argument cannot be a string",
		name);
      return NULL_TREE;
    }

  if (CONSTANT_CLASS_P (ref)
      && (INTEGRAL_TYPE_P (TREE_TYPE (ref))
	  || FLOAT_TYPE_P (TREE_TYPE (ref))))
    {
      /* Similar to the string case, since some function attributes
	 accept literal numbers as arguments (e.g., alloc_size or
	 nonnull) using one here is a likely mistake.  */
      error_at (DECL_SOURCE_LOCATION (decl),
		"%qE attribute argument cannot be a constant arithmetic "
		"expression",
		name);
      return NULL_TREE;
    }

  if (ref == node[1])
    {
      /* Another possible mistake (but indirect self-references aren't
	 and diagnosed and shouldn't be).  */
      if (warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
		      "%qE attribute ignored on a redeclaration "
		      "of the referenced symbol",
		      name))
	inform (DECL_SOURCE_LOCATION (node[1]),
		"previous declaration here");
      return NULL_TREE;
    }

  /* Consider address-of expressions in the attribute argument
     as requests to copy from the referenced entity.  */
  if (TREE_CODE (ref) == ADDR_EXPR)
    ref = TREE_OPERAND (ref, 0);

  do
    {
      /* Drill down into references to find the referenced decl.  */
      tree_code refcode = TREE_CODE (ref);
      if (refcode == ARRAY_REF
	  || refcode == INDIRECT_REF)
	ref = TREE_OPERAND (ref, 0);
      else if (refcode == COMPONENT_REF)
	ref = TREE_OPERAND (ref, 1);
      else
	break;
    } while (!DECL_P (ref));

  /* For object pointer expressions, consider those to be requests
     to copy from their type, such as in:
       struct __attribute__ (copy ((struct T *)0)) U { ... };
     which copies type attributes from struct T to the declaration
     of struct U.  */
  if ((CONSTANT_CLASS_P (ref) || EXPR_P (ref))
      && POINTER_TYPE_P (TREE_TYPE (ref))
      && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (ref)))
    ref = TREE_TYPE (ref);

  tree reftype = TYPE_P (ref) ? ref : TREE_TYPE (ref);

  if (DECL_P (decl))
    {
      if ((VAR_P (decl)
	   && (TREE_CODE (ref) == FUNCTION_DECL
	       || (EXPR_P (ref)
		   && POINTER_TYPE_P (reftype)
		   && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))
	  || (TREE_CODE (decl) == FUNCTION_DECL
	      && (VAR_P (ref)
		  || (EXPR_P (ref)
		      && !FUNC_OR_METHOD_TYPE_P (reftype)
		      && (!POINTER_TYPE_P (reftype)
			  || !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))))
	{
	  /* It makes no sense to try to copy function attributes
	     to a variable, or variable attributes to a function.  */
	  if (warning (OPT_Wattributes,
		       "%qE attribute ignored on a declaration of "
		       "a different kind than referenced symbol",
		       name)
	      && DECL_P (ref))
	    inform (DECL_SOURCE_LOCATION (ref),
		    "symbol %qD referenced by %qD declared here", ref, decl);
	  return NULL_TREE;
	}

      tree attrs = NULL_TREE;
      if (DECL_P (ref))
	attrs = DECL_ATTRIBUTES (ref);
      else if (TYPE_P (ref))
	attrs = TYPE_ATTRIBUTES (ref);

      /* Copy decl attributes from REF to DECL.  */
      for (tree at = attrs; at; at = TREE_CHAIN (at))
	{
	  /* Avoid copying attributes that affect a symbol linkage,
	     inlining, or visibility since those in all likelihood
	     only apply to the target.
	     FIXME: make it possible to specify which attributes to
	     copy or not to copy in the copy attribute itself.  */
	  tree atname = get_attribute_name (at);
	  if (is_attribute_p ("alias", atname)
	      || is_attribute_p ("always_inline", atname)
	      || is_attribute_p ("gnu_inline", atname)
	      || is_attribute_p ("ifunc", atname)
	      || is_attribute_p ("noinline", atname)
	      || is_attribute_p ("visibility", atname)
	      || is_attribute_p ("weak", atname)
	      || is_attribute_p ("weakref", atname)
	      || is_attribute_p ("target_clones", atname))
	    continue;

	  /* Attribute leaf only applies to extern functions.
	     Avoid copying it to static ones.  */
	  if (!TREE_PUBLIC (decl)
	      && is_attribute_p ("leaf", atname))
	    continue;

	  tree atargs = TREE_VALUE (at);
	  /* Create a copy of just the one attribute ar AT, including
	     its argumentsm and add it to DECL.  */
	  tree attr = tree_cons (atname, copy_list (atargs), NULL_TREE);
	  decl_attributes (node, attr, flags,  EXPR_P (ref) ? NULL_TREE : ref);
	}

      /* Proceed to copy type attributes below.  */
    }
  else if (!TYPE_P (decl))
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"%qE attribute must apply to a declaration",
		name);
      return NULL_TREE;
    }

  /* A function declared with attribute nothrow has the attribute
     attached to it, but a C++ throw() function does not.  */
  if (TREE_NOTHROW (ref))
    TREE_NOTHROW (decl) = true;

  /* Similarly, a function declared with attribute noreturn has it
     attached on to it, but a C11 _Noreturn function does not.  */
  if (DECL_P (ref)
      && TREE_THIS_VOLATILE (ref)
      && FUNC_OR_METHOD_TYPE_P (reftype))
    TREE_THIS_VOLATILE (decl) = true;

  if (POINTER_TYPE_P (reftype))
    reftype = TREE_TYPE (reftype);

  if (!TYPE_P (reftype))
    return NULL_TREE;

  tree attrs = TYPE_ATTRIBUTES (reftype);

  /* Copy type attributes from REF to DECL.  Pass in REF if it's a DECL
     or a type but not if it's an expression.  Set ATTR_FLAG_INTERNAL
     since the attributes' arguments may be in their internal form.  */
  for (tree at = attrs; at; at = TREE_CHAIN (at))
    decl_attributes (node, at, flags | ATTR_FLAG_INTERNAL,
		     EXPR_P (ref) ? NULL_TREE : ref);

  return NULL_TREE;
}

/* Handle a "weakref" attribute; arguments as in struct
   attribute_spec.handler.  */

static tree
handle_weakref_attribute (tree *node, tree name, tree args,
			  int flags, bool *no_add_attrs)
{
  tree attr = NULL_TREE;

  /* We must ignore the attribute when it is associated with
     local-scoped decls, since attribute alias is ignored and many
     such symbols do not even have a DECL_WEAK field.  */
  if (decl_function_context (*node)
      || current_function_decl
      || !VAR_OR_FUNCTION_DECL_P (*node))
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
    {
      error ("indirect function %q+D cannot be declared %qE",
	     *node, name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* The idea here is that `weakref("name")' mutates into `weakref,
     alias("name")', and weakref without arguments, in turn,
     implicitly adds weak.  */

  if (args)
    {
      attr = tree_cons (get_identifier ("alias"), args, attr);
      attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);

      *no_add_attrs = true;

      decl_attributes (node, attr, flags);
    }
  else
    {
      if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
	error_at (DECL_SOURCE_LOCATION (*node),
		  "%qE attribute must appear before %qs attribute",
		  name, "alias");

      /* Can't call declare_weak because it wants this to be TREE_PUBLIC,
	 and that isn't supported; and because it wants to add it to
	 the list of weak decls, which isn't helpful.  */
      DECL_WEAK (*node) = 1;
    }

  if (decl_in_symtab_p (*node))
    {
      struct symtab_node *n = symtab_node::get (*node);
      if (n && n->refuse_visibility_changes)
	error ("%+qD declared %qE after being used", *node, name);
    }

  return NULL_TREE;
}

/* Handle an "visibility" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_visibility_attribute (tree *node, tree name, tree args,
			     int ARG_UNUSED (flags),
			     bool *ARG_UNUSED (no_add_attrs))
{
  tree decl = *node;
  tree id = TREE_VALUE (args);
  enum symbol_visibility vis;

  if (TYPE_P (*node))
    {
      if (TREE_CODE (*node) == ENUMERAL_TYPE)
	/* OK */;
      else if (!RECORD_OR_UNION_TYPE_P (*node))
	{
	  warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
		   name);
	  return NULL_TREE;
	}
      else if (TYPE_FIELDS (*node))
	{
	  error ("%qE attribute ignored because %qT is already defined",
		 name, *node);
	  return NULL_TREE;
	}
    }
  else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      return NULL_TREE;
    }

  if (TREE_CODE (id) != STRING_CST)
    {
      error ("visibility argument not a string");
      return NULL_TREE;
    }

  /*  If this is a type, set the visibility on the type decl.  */
  if (TYPE_P (decl))
    {
      decl = TYPE_NAME (decl);
      if (!decl)
	return NULL_TREE;
      if (TREE_CODE (decl) == IDENTIFIER_NODE)
	{
	   warning (OPT_Wattributes, "%qE attribute ignored on types",
		    name);
	   return NULL_TREE;
	}
    }

  if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
    vis = VISIBILITY_DEFAULT;
  else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
    vis = VISIBILITY_INTERNAL;
  else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
    vis = VISIBILITY_HIDDEN;
  else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
    vis = VISIBILITY_PROTECTED;
  else
    {
      error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs",
	     name, "default", "hidden", "protected", "internal");
      vis = VISIBILITY_DEFAULT;
    }

  if (DECL_VISIBILITY_SPECIFIED (decl)
      && vis != DECL_VISIBILITY (decl))
    {
      tree attributes = (TYPE_P (*node)
			 ? TYPE_ATTRIBUTES (*node)
			 : DECL_ATTRIBUTES (decl));
      if (lookup_attribute ("visibility", attributes))
	error ("%qD redeclared with different visibility", decl);
      else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
	       && lookup_attribute ("dllimport", attributes))
	error ("%qD was declared %qs which implies default visibility",
	       decl, "dllimport");
      else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
	       && lookup_attribute ("dllexport", attributes))
	error ("%qD was declared %qs which implies default visibility",
	       decl, "dllexport");
    }

  DECL_VISIBILITY (decl) = vis;
  DECL_VISIBILITY_SPECIFIED (decl) = 1;

  /* Go ahead and attach the attribute to the node as well.  This is needed
     so we can determine whether we have VISIBILITY_DEFAULT because the
     visibility was not specified, or because it was explicitly overridden
     from the containing scope.  */

  return NULL_TREE;
}

/* Handle an "tls_model" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_tls_model_attribute (tree *node, tree name, tree args,
			    int ARG_UNUSED (flags),
			    bool *ARG_UNUSED (no_add_attrs))
{
  tree id;
  tree decl = *node;
  enum tls_model kind;

  if (!VAR_P (decl))
    {
      warning (OPT_Wattributes, "%qE attribute ignored because %qD "
	       "is not a variable",
	       name, decl);
      return NULL_TREE;
    }

  if (!DECL_THREAD_LOCAL_P (decl))
    {
      warning (OPT_Wattributes, "%qE attribute ignored because %qD does "
	       "not have thread storage duration", name, decl);
      return NULL_TREE;
    }

  kind = DECL_TLS_MODEL (decl);
  id = TREE_VALUE (args);
  if (TREE_CODE (id) != STRING_CST)
    {
      error ("%qE argument not a string", name);
      return NULL_TREE;
    }

  if (!strcmp (TREE_STRING_POINTER (id), "local-exec"))
    kind = TLS_MODEL_LOCAL_EXEC;
  else if (!strcmp (TREE_STRING_POINTER (id), "initial-exec"))
    kind = TLS_MODEL_INITIAL_EXEC;
  else if (!strcmp (TREE_STRING_POINTER (id), "local-dynamic"))
    kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
  else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
    kind = TLS_MODEL_GLOBAL_DYNAMIC;
  else
    error ("%qE argument must be one of %qs, %qs, %qs, or %qs",
	   name,
	   "local-exec", "initial-exec", "local-dynamic", "global-dynamic");

  set_decl_tls_model (decl, kind);
  return NULL_TREE;
}

/* Handle a "no_instrument_function" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_instrument_function_attribute (tree *node, tree name,
					 tree ARG_UNUSED (args),
					 int ARG_UNUSED (flags),
					 bool *no_add_attrs)
{
  tree decl = *node;

  if (TREE_CODE (decl) != FUNCTION_DECL)
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"%qE attribute applies only to functions", name);
      *no_add_attrs = true;
    }
  else
    DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;

  return NULL_TREE;
}

/* Handle a "no_profile_instrument_function" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_profile_instrument_function_attribute (tree *node, tree name, tree,
						 int, bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* If ALLOC_DECL and DEALLOC_DECL are a pair of user-defined functions,
   if they are declared inline issue warnings and return null.  Otherwise
   create attribute noinline, install it in ALLOC_DECL, and return it.
   Otherwise return null. */

static tree
maybe_add_noinline (tree name, tree alloc_decl, tree dealloc_decl,
		    bool *no_add_attrs)
{
  if (fndecl_built_in_p (alloc_decl) || fndecl_built_in_p (dealloc_decl))
    return NULL_TREE;

  /* When inlining (or optimization) is enabled and the allocator and
     deallocator are not built-in functions, ignore the attribute on
     functions declared inline since it could lead to false positives
     when inlining one or the other call would wind up calling
     a mismatched allocator or  deallocator.  */
  if ((optimize && DECL_DECLARED_INLINE_P (alloc_decl))
      || lookup_attribute ("always_inline", DECL_ATTRIBUTES (alloc_decl)))
    {
      warning (OPT_Wattributes,
	       "%<%E (%E)%> attribute ignored on functions "
	       "declared %qs", name, DECL_NAME (dealloc_decl), "inline");
      *no_add_attrs = true;
      return NULL_TREE;
    }

  if ((optimize && DECL_DECLARED_INLINE_P (dealloc_decl))
      || lookup_attribute ("always_inline", DECL_ATTRIBUTES (dealloc_decl)))
    {
      warning (OPT_Wattributes,
	       "%<%E (%E)%> attribute ignored with deallocation "
	       "functions declared %qs",
	       name, DECL_NAME (dealloc_decl), "inline");
      inform (DECL_SOURCE_LOCATION (dealloc_decl),
	      "deallocation function declared here" );
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* Disable inlining for non-standard deallocators to avoid false
     positives due to mismatches between the inlined implementation
     of one and not the other pair of functions.  */
  tree attr = tree_cons (get_identifier ("noinline"), NULL_TREE, NULL_TREE);
  decl_attributes (&alloc_decl, attr, 0);
  return attr;
}

/* Handle the "malloc" attribute.  */

static tree
handle_malloc_attribute (tree *node, tree name, tree args, int flags,
			 bool *no_add_attrs)
{
  if (flags & ATTR_FLAG_INTERNAL)
    /* Recursive call.  */
    return NULL_TREE;

  tree fndecl = *node;

  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored; valid only "
	       "for functions",
	       name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  tree rettype = TREE_TYPE (TREE_TYPE (*node));
  if (!POINTER_TYPE_P (rettype))
    {
      warning (OPT_Wattributes, "%qE attribute ignored on functions "
	       "returning %qT; valid only for pointer return types",
	       name, rettype);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  if (!args)
    {
      /* Only the form of the attribute with no arguments declares
	 a function malloc-like.  */
      DECL_IS_MALLOC (*node) = 1;
      return NULL_TREE;
    }

  tree dealloc = TREE_VALUE (args);
  if (error_operand_p (dealloc))
    {
      /* If the argument is in error it will have already been diagnosed.
	 Avoid issuing redundant errors here.  */
      *no_add_attrs = true;
      return NULL_TREE;
    }

  STRIP_NOPS (dealloc);
  if (TREE_CODE (dealloc) == ADDR_EXPR)
    {
      /* In C++ the argument may be wrapped in a cast to disambiguate
	 one of a number of overloads (such as operator delete).  To
	 make things interesting, the cast looks different between
	 different C++ versions.  Strip it and install the attribute
	 with the disambiguated function.  */
      dealloc = TREE_OPERAND (dealloc, 0);

      *no_add_attrs = true;
      tree attr = tree_cons (NULL_TREE, dealloc, TREE_CHAIN (args));
      attr = build_tree_list (name, attr);
      return decl_attributes (node, attr, 0);
    }

  if (TREE_CODE (dealloc) != FUNCTION_DECL)
    {
      if (TREE_CODE (dealloc) == OVERLOAD)
	{
	  /* Handle specially the common case of specifying one of a number
	     of overloads, such as operator delete.  */
	  error ("%qE attribute argument 1 is ambiguous", name);
	  inform (input_location,
		  "use a cast to the expected type to disambiguate");
	  *no_add_attrs = true;
	  return NULL_TREE;
	}

      error ("%qE attribute argument 1 does not name a function", name);
      if (DECL_P (dealloc))
	inform (DECL_SOURCE_LOCATION (dealloc),
		"argument references a symbol declared here");
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* Mentioning the deallocation function qualifies as its use.  */
  TREE_USED (dealloc) = 1;

  tree fntype = TREE_TYPE (dealloc);
  tree argpos = TREE_CHAIN (args) ? TREE_VALUE (TREE_CHAIN (args)) : NULL_TREE;
  if (!argpos)
    {
      tree argtypes = TYPE_ARG_TYPES (fntype);
      if (!argtypes)
	{
	  /* Reject functions without a prototype.  */
	  error ("%qE attribute argument 1 must take a pointer "
		 "type as its first argument", name);
	  inform (DECL_SOURCE_LOCATION (dealloc),
		  "referenced symbol declared here");
	  *no_add_attrs = true;
	  return NULL_TREE;
	}

      tree argtype = TREE_VALUE (argtypes);
      if (TREE_CODE (argtype) != POINTER_TYPE)
	{
	  /* Reject functions that don't take a pointer as their first
	     argument.  */
	  error ("%qE attribute argument 1 must take a pointer type "
		 "as its first argument; have %qT", name, argtype);
	  inform (DECL_SOURCE_LOCATION (dealloc),
		  "referenced symbol declared here");
	  *no_add_attrs = true;
	  return NULL_TREE;
	}

      /* Disable inlining for non-standard deallocators to avoid false
	 positives (or warn if either function is explicitly inline).  */
      tree at_noinline =
	maybe_add_noinline (name, fndecl, dealloc, no_add_attrs);
      if (*no_add_attrs)
	return NULL_TREE;

      /* Add attribute *dealloc to the deallocator function associating
	 it with this one.  Ideally, the attribute would reference
	 the DECL of the deallocator but since that changes for each
	 redeclaration, use DECL_NAME instead.  (DECL_ASSEMBLER_NAME
	 need not be set set this point and setting it here is too early.  */
      tree attrs = build_tree_list (NULL_TREE, DECL_NAME (fndecl));
      attrs = tree_cons (get_identifier ("*dealloc"), attrs, at_noinline);
      decl_attributes (&dealloc, attrs, 0);
      return NULL_TREE;
    }

  /* Validate the positional argument.  */
  argpos = positional_argument (fntype, name, argpos, POINTER_TYPE);
  if (!argpos)
    {
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* As above, disable inlining for non-standard deallocators to avoid
     false positives (or warn).  */
  tree at_noinline =
    maybe_add_noinline (name, fndecl, dealloc, no_add_attrs);
  if (*no_add_attrs)
    return NULL_TREE;

  /* It's valid to declare the same function with multiple instances
     of attribute malloc, each naming the same or different deallocator
     functions, and each referencing either the same or a different
     positional argument.  */
  tree attrs = tree_cons (NULL_TREE, argpos, NULL_TREE);
  attrs = tree_cons (NULL_TREE, DECL_NAME (fndecl), attrs);
  attrs = tree_cons (get_identifier ("*dealloc"), attrs, at_noinline);
  decl_attributes (&dealloc, attrs, 0);
  return NULL_TREE;
}

/* Handle the internal "*dealloc" attribute added for functions declared
   with the one- and two-argument forms of attribute malloc.  Add it
   to *NODE unless it's already there with the same arguments.  */

static tree
handle_dealloc_attribute (tree *node, tree name, tree args, int,
			  bool *no_add_attrs)
{
  tree fndecl = *node;

  tree attrs = DECL_ATTRIBUTES (fndecl);
  if (!attrs)
    return NULL_TREE;

  tree arg = TREE_VALUE (args);
  args = TREE_CHAIN (args);
  tree arg_pos = args ? TREE_VALUE (args) : integer_zero_node;

  gcc_checking_assert ((DECL_P (arg)
			&& fndecl_built_in_p (arg, BUILT_IN_NORMAL))
		       || TREE_CODE (arg) == IDENTIFIER_NODE);

  const char* const namestr = IDENTIFIER_POINTER (name);
  for (tree at = attrs; (at = lookup_attribute (namestr, at));
       at = TREE_CHAIN (at))
    {
      tree alloc = TREE_VALUE (at);
      if (!alloc)
	continue;

      tree pos = TREE_CHAIN (alloc);
      alloc = TREE_VALUE (alloc);
      pos = pos ? TREE_VALUE (pos) : integer_zero_node;
      gcc_checking_assert ((DECL_P (alloc)
			    && fndecl_built_in_p (alloc, BUILT_IN_NORMAL))
			   || TREE_CODE (alloc) == IDENTIFIER_NODE);

      if (alloc == arg && tree_int_cst_equal (pos, arg_pos))
	{
	  /* The function already has the attribute either without any
	     arguments or with the same arguments as the attribute that's
	     being added.  Return without adding another copy.  */
	  *no_add_attrs = true;
	  return NULL_TREE;
	}
    }

  return NULL_TREE;
}

/* Handle the "alloc_size (argpos1 [, argpos2])" function type attribute.
   *NODE is the type of the function the attribute is being applied to.  */

static tree
handle_alloc_size_attribute (tree *node, tree name, tree args,
			     int ARG_UNUSED (flags), bool *no_add_attrs)
{
  tree fntype = *node;
  tree rettype = TREE_TYPE (fntype);
  if (!POINTER_TYPE_P (rettype))
    {
      warning (OPT_Wattributes,
	       "%qE attribute ignored on a function returning %qT",
	       name, rettype);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  tree newargs[2] = { NULL_TREE, NULL_TREE };
  for (int i = 1; args; ++i)
    {
      tree pos = TREE_VALUE (args);
      /* NEXT is null when the attribute includes just one argument.
	 That's used to tell positional_argument to avoid mentioning
	 the argument number in diagnostics (since there's just one
	 mentioning it is unnecessary and coule be confusing).  */
      tree next = TREE_CHAIN (args);
      if (tree val = positional_argument (fntype, name, pos, INTEGER_TYPE,
					  next || i > 1 ? i : 0))
	{
	  TREE_VALUE (args) = val;
	  newargs[i - 1] = val;
	}
      else
	{
	  *no_add_attrs = true;
	  return NULL_TREE;
	}

      args = next;
    }

  if (!validate_attr_args (node, name, newargs))
    *no_add_attrs = true;

  return NULL_TREE;
}


/* Handle an "alloc_align (argpos)" attribute.  */

static tree
handle_alloc_align_attribute (tree *node, tree name, tree args, int,
			      bool *no_add_attrs)
{
  tree fntype = *node;
  tree rettype = TREE_TYPE (fntype);
  if (!POINTER_TYPE_P (rettype))
    {
      warning (OPT_Wattributes,
	       "%qE attribute ignored on a function returning %qT",
	       name, rettype);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  if (tree val = positional_argument (*node, name, TREE_VALUE (args),
				      INTEGER_TYPE))
    if (validate_attr_arg (node, name, val))
      return NULL_TREE;

  *no_add_attrs = true;
  return NULL_TREE;
}

/* Handle a "assume_aligned" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_assume_aligned_attribute (tree *node, tree name, tree args, int,
				 bool *no_add_attrs)
{
  tree decl = *node;
  tree rettype = TREE_TYPE (decl);
  if (TREE_CODE (rettype) != POINTER_TYPE)
    {
      warning (OPT_Wattributes,
	       "%qE attribute ignored on a function returning %qT",
	       name, rettype);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* The alignment specified by the first argument.  */
  tree align = NULL_TREE;

  for (; args; args = TREE_CHAIN (args))
    {
      tree val = TREE_VALUE (args);
      if (val && TREE_CODE (val) != IDENTIFIER_NODE
	  && TREE_CODE (val) != FUNCTION_DECL)
	val = default_conversion (val);

      if (!tree_fits_shwi_p (val))
	{
	  warning (OPT_Wattributes,
		   "%qE attribute argument %E is not an integer constant",
		   name, val);
	  *no_add_attrs = true;
	  return NULL_TREE;
	}
      else if (tree_int_cst_sgn (val) < 0)
	{
	  warning (OPT_Wattributes,
		   "%qE attribute argument %E is not positive", name, val);
	  *no_add_attrs = true;
	  return NULL_TREE;
	}

      if (!align)
	{
	  /* Validate and save the alignment.  */
	  if (!integer_pow2p (val))
	    {
	      warning (OPT_Wattributes,
		       "%qE attribute argument %E is not a power of 2",
		       name, val);
	      *no_add_attrs = true;
	      return NULL_TREE;
	    }

	  align = val;
	}
      else if (tree_int_cst_le (align, val))
	{
	  /* The misalignment specified by the second argument
	     must be non-negative and less than the alignment.  */
	  warning (OPT_Wattributes,
		   "%qE attribute argument %E is not in the range [0, %wu]",
		   name, val, tree_to_uhwi (align) - 1);
	  *no_add_attrs = true;
	  return NULL_TREE;
	}
    }
  return NULL_TREE;
}

/* Handle the internal-only "arg spec" attribute.  */

static tree
handle_argspec_attribute (tree *, tree, tree args, int, bool *)
{
  /* Verify the attribute has one or two arguments and their kind.  */
  gcc_assert (args && TREE_CODE (TREE_VALUE (args)) == STRING_CST);
  for (tree next = TREE_CHAIN (args); next; next = TREE_CHAIN (next))
    {
      tree val = TREE_VALUE (next);
      gcc_assert (DECL_P (val) || EXPR_P (val));
    }
  return NULL_TREE;
}

/* Handle the internal-only "fn spec" attribute.  */

static tree
handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
			 tree args, int ARG_UNUSED (flags),
			 bool *no_add_attrs ATTRIBUTE_UNUSED)
{
  gcc_assert (args
	      && TREE_CODE (TREE_VALUE (args)) == STRING_CST
	      && !TREE_CHAIN (args));
  return NULL_TREE;
}

/* Handle a "warn_unused" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_warn_unused_attribute (tree *node, tree name,
			      tree args ATTRIBUTE_UNUSED,
			      int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
  if (TYPE_P (*node))
    /* Do nothing else, just set the attribute.  We'll get at
       it later with lookup_attribute.  */
    ;
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle an "omp declare simd" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *)
{
  return NULL_TREE;
}

/* Handle an "omp declare variant {base,variant}" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_omp_declare_variant_attribute (tree *, tree, tree, int, bool *)
{
  return NULL_TREE;
}

/* Handle a "simd" attribute.  */

static tree
handle_simd_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL)
    {
      tree t = get_identifier ("omp declare simd");
      tree attr = NULL_TREE;
      if (args)
	{
	  tree id = TREE_VALUE (args);

	  if (TREE_CODE (id) != STRING_CST)
	    {
	      error ("attribute %qE argument not a string", name);
	      *no_add_attrs = true;
	      return NULL_TREE;
	    }

	  if (strcmp (TREE_STRING_POINTER (id), "notinbranch") == 0)
	    attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
				     OMP_CLAUSE_NOTINBRANCH);
	  else if (strcmp (TREE_STRING_POINTER (id), "inbranch") == 0)
	    attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
				     OMP_CLAUSE_INBRANCH);
	  else
	    {
	      error ("only %<inbranch%> and %<notinbranch%> flags are "
		     "allowed for %<__simd__%> attribute");
	      *no_add_attrs = true;
	      return NULL_TREE;
	    }
	}

      DECL_ATTRIBUTES (*node)
	= tree_cons (t, build_tree_list (NULL_TREE, attr),
		     DECL_ATTRIBUTES (*node));
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle an "omp declare target" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *)
{
  return NULL_TREE;
}

/* Handle a "returns_twice" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			 int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL)
    DECL_IS_RETURNS_TWICE (*node) = 1;
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "no_limit_stack" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_no_limit_stack_attribute (tree *node, tree name,
				 tree ARG_UNUSED (args),
				 int ARG_UNUSED (flags),
				 bool *no_add_attrs)
{
  tree decl = *node;

  if (TREE_CODE (decl) != FUNCTION_DECL)
    {
      error_at (DECL_SOURCE_LOCATION (decl),
	     "%qE attribute applies only to functions", name);
      *no_add_attrs = true;
    }
  else if (DECL_INITIAL (decl))
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"cannot set %qE attribute after definition", name);
      *no_add_attrs = true;
    }
  else
    DECL_NO_LIMIT_STACK (decl) = 1;

  return NULL_TREE;
}

/* Handle a "pure" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
		       int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL)
    {
      tree type = TREE_TYPE (*node);
      if (VOID_TYPE_P (TREE_TYPE (type)))
	warning (OPT_Wattributes, "%qE attribute on function "
		 "returning %<void%>", name);

      DECL_PURE_P (*node) = 1;
      /* ??? TODO: Support types.  */
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Digest an attribute list destined for a transactional memory statement.
   ALLOWED is the set of attributes that are allowed for this statement;
   return the attribute we parsed.  Multiple attributes are never allowed.  */

int
parse_tm_stmt_attr (tree attrs, int allowed)
{
  tree a_seen = NULL;
  int m_seen = 0;

  for ( ; attrs ; attrs = TREE_CHAIN (attrs))
    {
      tree a = get_attribute_name (attrs);
      tree ns = get_attribute_namespace (attrs);
      int m = 0;

      if (is_attribute_p ("outer", a)
	  && (ns == NULL_TREE || strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0))
	m = TM_STMT_ATTR_OUTER;

      if ((m & allowed) == 0)
	{
	  warning (OPT_Wattributes, "%qE attribute directive ignored", a);
	  continue;
	}

      if (m_seen == 0)
	{
	  a_seen = a;
	  m_seen = m;
	}
      else if (m_seen == m)
	warning (OPT_Wattributes, "%qE attribute duplicated", a);
      else
	warning (OPT_Wattributes, "%qE attribute follows %qE", a, a_seen);
    }

  return m_seen;
}

/* Transform a TM attribute name into a maskable integer and back.
   Note that NULL (i.e. no attribute) is mapped to UNKNOWN, corresponding
   to how the lack of an attribute is treated.  */

int
tm_attr_to_mask (tree attr)
{
  if (attr == NULL)
    return 0;
  if (is_attribute_p ("transaction_safe", attr))
    return TM_ATTR_SAFE;
  if (is_attribute_p ("transaction_callable", attr))
    return TM_ATTR_CALLABLE;
  if (is_attribute_p ("transaction_pure", attr))
    return TM_ATTR_PURE;
  if (is_attribute_p ("transaction_unsafe", attr))
    return TM_ATTR_IRREVOCABLE;
  if (is_attribute_p ("transaction_may_cancel_outer", attr))
    return TM_ATTR_MAY_CANCEL_OUTER;
  return 0;
}

tree
tm_mask_to_attr (int mask)
{
  const char *str;
  switch (mask)
    {
    case TM_ATTR_SAFE:
      str = "transaction_safe";
      break;
    case TM_ATTR_CALLABLE:
      str = "transaction_callable";
      break;
    case TM_ATTR_PURE:
      str = "transaction_pure";
      break;
    case TM_ATTR_IRREVOCABLE:
      str = "transaction_unsafe";
      break;
    case TM_ATTR_MAY_CANCEL_OUTER:
      str = "transaction_may_cancel_outer";
      break;
    default:
      gcc_unreachable ();
    }
  return get_identifier (str);
}

/* Return the first TM attribute seen in LIST.  */

tree
find_tm_attribute (tree list)
{
  for (; list ; list = TREE_CHAIN (list))
    {
      tree name = get_attribute_name (list);
      if (tm_attr_to_mask (name) != 0)
	return name;
    }
  return NULL_TREE;
}

/* Handle the TM attributes; arguments as in struct attribute_spec.handler.
   Here we accept only function types, and verify that none of the other
   function TM attributes are also applied.  */
/* ??? We need to accept class types for C++, but not C.  This greatly
   complicates this function, since we can no longer rely on the extra
   processing given by function_type_required.  */

static tree
handle_tm_attribute (tree *node, tree name, tree args,
		     int flags, bool *no_add_attrs)
{
  /* Only one path adds the attribute; others don't.  */
  *no_add_attrs = true;

  switch (TREE_CODE (*node))
    {
    case RECORD_TYPE:
    case UNION_TYPE:
      /* Only tm_callable and tm_safe apply to classes.  */
      if (tm_attr_to_mask (name) & ~(TM_ATTR_SAFE | TM_ATTR_CALLABLE))
	goto ignored;
      /* FALLTHRU */

    case FUNCTION_TYPE:
    case METHOD_TYPE:
      {
	tree old_name = find_tm_attribute (TYPE_ATTRIBUTES (*node));
	if (old_name == name)
	  ;
	else if (old_name != NULL_TREE)
	  error ("type was previously declared %qE", old_name);
	else
	  *no_add_attrs = false;
      }
      break;

    case FUNCTION_DECL:
      {
	/* transaction_safe_dynamic goes on the FUNCTION_DECL, but we also
	   want to set transaction_safe on the type.  */
	gcc_assert (is_attribute_p ("transaction_safe_dynamic", name));
	if (!TYPE_P (DECL_CONTEXT (*node)))
	  error_at (DECL_SOURCE_LOCATION (*node),
		    "%<transaction_safe_dynamic%> may only be specified for "
		    "a virtual function");
	*no_add_attrs = false;
	decl_attributes (&TREE_TYPE (*node),
			 build_tree_list (get_identifier ("transaction_safe"),
					  NULL_TREE),
			 0);
	break;
      }

    case POINTER_TYPE:
      {
	enum tree_code subcode = TREE_CODE (TREE_TYPE (*node));
	if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE)
	  {
	    tree fn_tmp = TREE_TYPE (*node);
	    decl_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
	    *node = build_pointer_type (fn_tmp);
	    break;
	  }
      }
      /* FALLTHRU */

    default:
      /* If a function is next, pass it on to be tried next.  */
      if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
	return tree_cons (name, args, NULL);

    ignored:
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      break;
    }

  return NULL_TREE;
}

/* Handle the TM_WRAP attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_tm_wrap_attribute (tree *node, tree name, tree args,
			  int ARG_UNUSED (flags), bool *no_add_attrs)
{
  tree decl = *node;

  /* We don't need the attribute even on success, since we
     record the entry in an external table.  */
  *no_add_attrs = true;

  if (TREE_CODE (decl) != FUNCTION_DECL)
    warning (OPT_Wattributes, "%qE attribute ignored", name);
  else
    {
      tree wrap_decl = TREE_VALUE (args);
      if (error_operand_p (wrap_decl))
	;
      else if (TREE_CODE (wrap_decl) != IDENTIFIER_NODE
	       && !VAR_OR_FUNCTION_DECL_P (wrap_decl))
	error ("%qE argument not an identifier", name);
      else
	{
	  if (TREE_CODE (wrap_decl) == IDENTIFIER_NODE)
	    wrap_decl = lookup_name (wrap_decl);
	  if (wrap_decl && TREE_CODE (wrap_decl) == FUNCTION_DECL)
	    {
	      if (lang_hooks.types_compatible_p (TREE_TYPE (decl),
						 TREE_TYPE (wrap_decl)))
		record_tm_replacement (wrap_decl, decl);
	      else
		error ("%qD is not compatible with %qD", wrap_decl, decl);
	    }
	  else
	    error ("%qE argument is not a function", name);
	}
    }

  return NULL_TREE;
}

/* Ignore the given attribute.  Used when this attribute may be usefully
   overridden by the target, but is not used generically.  */

static tree
ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
		  tree ARG_UNUSED (args), int ARG_UNUSED (flags),
		  bool *no_add_attrs)
{
  *no_add_attrs = true;
  return NULL_TREE;
}

/* Handle a "no vops" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
			 bool *ARG_UNUSED (no_add_attrs))
{
  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
  DECL_IS_NOVOPS (*node) = 1;
  return NULL_TREE;
}

/* Handle a "deprecated" attribute; arguments as in
   struct attribute_spec.handler.  */

tree
handle_deprecated_attribute (tree *node, tree name,
			     tree args, int flags,
			     bool *no_add_attrs)
{
  tree type = NULL_TREE;
  int warn = 0;
  tree what = NULL_TREE;

  if (!args)
    *no_add_attrs = true;
  else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
    {
      error ("deprecated message is not a string");
      *no_add_attrs = true;
    }

  if (DECL_P (*node))
    {
      tree decl = *node;
      type = TREE_TYPE (decl);

      if (TREE_CODE (decl) == TYPE_DECL
	  || TREE_CODE (decl) == PARM_DECL
	  || VAR_OR_FUNCTION_DECL_P (decl)
	  || TREE_CODE (decl) == FIELD_DECL
	  || TREE_CODE (decl) == CONST_DECL
	  || objc_method_decl (TREE_CODE (decl)))
	TREE_DEPRECATED (decl) = 1;
      else
	warn = 1;
    }
  else if (TYPE_P (*node))
    {
      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
	*node = build_variant_type_copy (*node);
      TREE_DEPRECATED (*node) = 1;
      type = *node;
    }
  else
    warn = 1;

  if (warn)
    {
      *no_add_attrs = true;
      if (type && TYPE_NAME (type))
	{
	  if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
	    what = TYPE_NAME (*node);
	  else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
		   && DECL_NAME (TYPE_NAME (type)))
	    what = DECL_NAME (TYPE_NAME (type));
	}
      if (what)
	warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
      else
	warning (OPT_Wattributes, "%qE attribute ignored", name);
    }

  return NULL_TREE;
}

/* Return the "base" type from TYPE that is suitable to apply attribute
   vector_size to by stripping arrays, function types, etc.  */
static tree
type_for_vector_size (tree type)
{
  /* We need to provide for vector pointers, vector arrays, and
     functions returning vectors.  For example:

       __attribute__((vector_size(16))) short *foo;

     In this case, the mode is SI, but the type being modified is
     HI, so we need to look further.  */

  while (POINTER_TYPE_P (type)
	 || TREE_CODE (type) == FUNCTION_TYPE
	 || TREE_CODE (type) == METHOD_TYPE
	 || TREE_CODE (type) == ARRAY_TYPE
	 || TREE_CODE (type) == OFFSET_TYPE)
    type = TREE_TYPE (type);

  return type;
}

/* Given TYPE, return the base type to which the vector_size attribute
   ATNAME with ARGS, when non-null, can be applied, if one exists.
   On success and when both ARGS and PTRNUNITS are non-null, set
   *PTRNUNINTS to the number of vector units.  When PTRNUNITS is not
   null, issue a warning when the attribute argument is not constant
   and an error if there is no such type.  Otherwise issue a warning
   in the latter case and return null.  */

static tree
type_valid_for_vector_size (tree type, tree atname, tree args,
			    unsigned HOST_WIDE_INT *ptrnunits)
{
  bool error_p = ptrnunits != NULL;

  /* Get the mode of the type being modified.  */
  machine_mode orig_mode = TYPE_MODE (type);

  if ((!INTEGRAL_TYPE_P (type)
       && !SCALAR_FLOAT_TYPE_P (type)
       && !FIXED_POINT_TYPE_P (type))
      || (!SCALAR_FLOAT_MODE_P (orig_mode)
	  && GET_MODE_CLASS (orig_mode) != MODE_INT
	  && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode))
      || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
      || TREE_CODE (type) == BOOLEAN_TYPE)
    {
      if (error_p)
	error ("invalid vector type for attribute %qE", atname);
      else
	warning (OPT_Wattributes, "invalid vector type for attribute %qE",
		 atname);
      return NULL_TREE;
    }

  /* When no argument has been provided this is just a request to validate
     the type above.  Return TYPE to indicate success.  */
  if (!args)
    return type;

  tree size = TREE_VALUE (args);
  /* Erroneous arguments have already been diagnosed.  */
  if (size == error_mark_node)
    return NULL_TREE;

  if (size && TREE_CODE (size) != IDENTIFIER_NODE
      && TREE_CODE (size) != FUNCTION_DECL)
    size = default_conversion (size);

  if (TREE_CODE (size) != INTEGER_CST)
    {
      if (error_p)
	error ("%qE attribute argument value %qE is not an integer constant",
	       atname, size);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument value %qE is not an integer constant",
		 atname, size);
      return NULL_TREE;
    }

  if (!TYPE_UNSIGNED (TREE_TYPE (size))
      && tree_int_cst_sgn (size) < 0)
    {
      if (error_p)
	error ("%qE attribute argument value %qE is negative",
	       atname, size);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument value %qE is negative",
		 atname, size);
      return NULL_TREE;
    }

  /* The attribute argument value is constrained by the maximum bit
     alignment representable in unsigned int on the host.  */
  unsigned HOST_WIDE_INT vecsize;
  unsigned HOST_WIDE_INT maxsize = tree_to_uhwi (max_object_size ());
  if (!tree_fits_uhwi_p (size)
      || (vecsize = tree_to_uhwi (size)) > maxsize)
    {
      if (error_p)
	error ("%qE attribute argument value %qE exceeds %wu",
	       atname, size, maxsize);
      else
	warning (OPT_Wattributes,
		 "%qE attribute argument value %qE exceeds %wu",
		 atname, size, maxsize);
      return NULL_TREE;
    }

  if (vecsize % tree_to_uhwi (TYPE_SIZE_UNIT (type)))
    {
      if (error_p)
	error ("vector size not an integral multiple of component size");
      return NULL_TREE;
    }

  if (vecsize == 0)
    {
      error ("zero vector size");
      return NULL;
    }

  /* Calculate how many units fit in the vector.  */
  unsigned HOST_WIDE_INT nunits = vecsize / tree_to_uhwi (TYPE_SIZE_UNIT (type));
  if (nunits & (nunits - 1))
    {
      if (error_p)
	error ("number of vector components %wu not a power of two", nunits);
      else
	warning (OPT_Wattributes,
		 "number of vector components %wu not a power of two", nunits);
      return NULL_TREE;
    }

  if (nunits >= (unsigned HOST_WIDE_INT)INT_MAX)
    {
      if (error_p)
	error ("number of vector components %wu exceeds %d",
	       nunits, INT_MAX - 1);
      else
	warning (OPT_Wattributes,
		 "number of vector components %wu exceeds %d",
		 nunits, INT_MAX - 1);
      return NULL_TREE;
    }

  if (ptrnunits)
    *ptrnunits = nunits;

  return type;
}

/* Handle a "vector_size" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_vector_size_attribute (tree *node, tree name, tree args,
			      int ARG_UNUSED (flags),
			      bool *no_add_attrs)
{
  *no_add_attrs = true;

  /* Determine the "base" type to apply the attribute to.  */
  tree type = type_for_vector_size (*node);

  /* Get the vector size (in bytes) and let the function compute
     the number of vector units.  */
  unsigned HOST_WIDE_INT nunits;
  type = type_valid_for_vector_size (type, name, args, &nunits);
  if (!type)
    return NULL_TREE;

  gcc_checking_assert (args != NULL);

  tree new_type = build_vector_type (type, nunits);

  /* Build back pointers if needed.  */
  *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);

  return NULL_TREE;
}

/* Handle the "nonnull" attribute.  */

static tree
handle_nonnull_attribute (tree *node, tree name,
			  tree args, int ARG_UNUSED (flags),
			  bool *no_add_attrs)
{
  tree type = *node;

  /* If no arguments are specified, all pointer arguments should be
     non-null.  Verify a full prototype is given so that the arguments
     will have the correct types when we actually check them later.
     Avoid diagnosing type-generic built-ins since those have no
     prototype.  */
  if (!args)
    {
      if (!prototype_p (type)
	  && (!TYPE_ATTRIBUTES (type)
	      || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))))
	{
	  error ("%qE attribute without arguments on a non-prototype",
		 name);
	  *no_add_attrs = true;
	}
      return NULL_TREE;
    }

  for (int i = 1; args; ++i)
    {
      tree pos = TREE_VALUE (args);
      /* NEXT is null when the attribute includes just one argument.
	 That's used to tell positional_argument to avoid mentioning
	 the argument number in diagnostics (since there's just one
	 mentioning it is unnecessary and coule be confusing).  */
      tree next = TREE_CHAIN (args);
      if (tree val = positional_argument (type, name, pos, POINTER_TYPE,
					  next || i > 1 ? i : 0))
	TREE_VALUE (args) = val;
      else
	{
	  *no_add_attrs = true;
	  break;
	}
      args = next;
    }

  return NULL_TREE;
}

/* Handle the "nonstring" variable attribute.  */

static tree
handle_nonstring_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			    int ARG_UNUSED (flags), bool *no_add_attrs)
{
  gcc_assert (!args);
  tree_code code = TREE_CODE (*node);

  if (VAR_P (*node)
      || code == FIELD_DECL
      || code == PARM_DECL)
    {
      tree type = TREE_TYPE (*node);

      if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
	{
	  /* Accept the attribute on arrays and pointers to all three
	     narrow character types.  */
	  tree eltype = TREE_TYPE (type);
	  eltype = TYPE_MAIN_VARIANT (eltype);
	  if (eltype == char_type_node
	      || eltype == signed_char_type_node
	      || eltype == unsigned_char_type_node)
	    return NULL_TREE;
	}

      warning (OPT_Wattributes,
	       "%qE attribute ignored on objects of type %qT",
	       name, type);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  if (code == FUNCTION_DECL)
    warning (OPT_Wattributes,
	     "%qE attribute does not apply to functions", name);
  else if (code == TYPE_DECL)
    warning (OPT_Wattributes,
	     "%qE attribute does not apply to types", name);
  else
    warning (OPT_Wattributes, "%qE attribute ignored", name);

  *no_add_attrs = true;
  return NULL_TREE;
}

/* Given a function type FUNCTYPE, returns the type of the parameter
   ARGNO or null if ARGNO exceeds the number of parameters.  On failure
   set *NARGS to the number of function parameters.  */

static tree
get_argument_type (tree functype, unsigned argno, unsigned *nargs)
{
  function_args_iterator iter;
  function_args_iter_init (&iter, functype);

  unsigned count = 0;

  for ( ; iter.next; ++count, function_args_iter_next (&iter))
    {
      if (count + 1 == argno)
	{
	  tree argtype = function_args_iter_cond (&iter);
	  if (VOID_TYPE_P (argtype))
	    break;
	  if (argtype != error_mark_node)
	    return argtype;
	}
    }

  *nargs = count;
  return NULL_TREE;
}

/* Given a function FNDECL return the function argument at the zero-
   based position ARGNO or null if it can't be found.  */

static tree
get_argument (tree fndecl, unsigned argno)
{
  if (!DECL_P (fndecl))
    return NULL_TREE;

  unsigned i = 0;
  for (tree arg = DECL_ARGUMENTS (fndecl); arg; arg = TREE_CHAIN (arg))
    if (i++ == argno)
      return arg;

  return NULL_TREE;
}

/* Attempt to append attribute access specification ATTRSPEC, optionally
   described by the human-readable string ATTRSTR, for type T, to one in
   ATTRS. VBLIST is an optional list of bounds of variable length array
   parameters described by ATTRSTR.
   Issue warning for conflicts and return null if any are found.
   Return the concatenated access string on success.  */

static tree
append_access_attr (tree node[3], tree attrs, const char *attrstr,
		    const char *attrspec, tree vblist = NULL_TREE)
{
  tree argstr = build_string (strlen (attrspec) + 1, attrspec);
  tree ataccess = tree_cons (NULL_TREE, argstr, vblist);
  ataccess = tree_cons (get_identifier ("access"), ataccess, NULL_TREE);

  /* The access specification being applied.  This may be an implicit
     access spec synthesized for array (or VLA) parameters even for
     a declaration with an explicit access spec already applied, if
     this call corresponds to the first declaration of the function.  */
  rdwr_map new_idxs;
  init_attr_rdwr_indices (&new_idxs, ataccess);

  /* The current access specification alrady applied.  */
  rdwr_map cur_idxs;
  init_attr_rdwr_indices (&cur_idxs, attrs);

  std::string spec;
  for (auto it = new_idxs.begin (); it != new_idxs.end (); ++it)
    {
      const auto &newaxsref = *it;

      /* The map has two equal entries for each pointer argument that
	 has an associated size argument.  Process just the entry for
	 the former.  */
      if ((unsigned)newaxsref.first != newaxsref.second.ptrarg)
	continue;

      const attr_access* const cura = cur_idxs.get (newaxsref.first);
      if (!cura)
	{
	  /* The new attribute needs to be added.  */
	  tree str = newaxsref.second.to_internal_string ();
	  spec += TREE_STRING_POINTER (str);
	  continue;
	}

      /* The new access spec refers to an array/pointer argument for
	 which an access spec already exists.  Check and diagnose any
	 conflicts.  If no conflicts are found, merge the two.  */
      const attr_access* const newa = &newaxsref.second;

      if (!attrstr)
	{
	  tree str = NULL_TREE;
	  if (newa->mode != access_deferred)
	    str = newa->to_external_string ();
	  else if (cura->mode != access_deferred)
	    str = cura->to_external_string ();
	  if (str)
	    attrstr = TREE_STRING_POINTER (str);
	}

      location_t curloc = input_location;
      if (node[2] && DECL_P (node[2]))
	curloc = DECL_SOURCE_LOCATION (node[2]);

      location_t prevloc = UNKNOWN_LOCATION;
      if (node[1] && DECL_P (node[1]))
	prevloc = DECL_SOURCE_LOCATION (node[1]);

      if (newa->mode != cura->mode
	  && newa->mode != access_deferred
	  && cura->mode != access_deferred
	  && newa->internal_p == cura->internal_p)
	{
	  /* Mismatch in access mode.  */
	  auto_diagnostic_group d;
	  if (warning_at (curloc, OPT_Wattributes,
			  "attribute %qs mismatch with mode %qs",
			  attrstr, cura->mode_names[cura->mode])
	      && prevloc != UNKNOWN_LOCATION)
	    inform (prevloc, "previous declaration here");
	  continue;
	}

      /* Set if PTRARG refers to a VLA with an unspecified bound (T[*]).
	 Be prepared for either CURA or NEWA to refer to it, depending
	 on which happens to come first in the declaration.  */
      const bool cur_vla_ub = (cura->internal_p
			       && cura->sizarg == UINT_MAX
			       && cura->minsize == HOST_WIDE_INT_M1U);
      const bool new_vla_ub = (newa->internal_p
			       && newa->sizarg == UINT_MAX
			       && newa->minsize == HOST_WIDE_INT_M1U);

      if (newa->sizarg != cura->sizarg
	  && attrstr
	  && (!(cur_vla_ub ^ new_vla_ub)
	      || (!cura->internal_p && !newa->internal_p)))
	{
	  /* Avoid diagnosing redeclarations of functions with no explicit
	     attribute access that add one.  */
	  if (newa->mode == access_deferred
	      && cura->mode != access_deferred
	      && newa->sizarg == UINT_MAX
	      && cura->sizarg != UINT_MAX)
	    continue;

	  if (cura->mode == access_deferred
	      && newa->mode != access_deferred
	      && cura->sizarg == UINT_MAX
	      && newa->sizarg != UINT_MAX)
	    continue;

	  /* The two specs designate different size arguments.  It's okay
	     for the explicit spec to specify a size where none is provided
	     by the implicit (VLA) one, as in:
	       __attribute__ ((access (read_write, 1, 2)))
	       void f (int*, int);
	     but not for two explicit access attributes to do that.  */
	  bool warned = false;

	  auto_diagnostic_group d;

	  if (newa->sizarg == UINT_MAX)
	    /* Mismatch in the presence of the size argument.  */
	    warned = warning_at (curloc, OPT_Wattributes,
				 "attribute %qs missing positional argument 2 "
				 "provided in previous designation by argument "
				 "%u", attrstr, cura->sizarg + 1);
	  else if (cura->sizarg == UINT_MAX)
	    /* Mismatch in the presence of the size argument.  */
	    warned = warning_at (curloc, OPT_Wattributes,
				 "attribute %qs positional argument 2 "
				 "missing in previous designation",
				 attrstr);
	  else if (newa->internal_p || cura->internal_p)
	    /* Mismatch in the value of the size argument and a VLA bound.  */
	    warned = warning_at (curloc, OPT_Wattributes,
				 "attribute %qs positional argument 2 "
				 "conflicts with previous designation "
				 "by argument %u",
				 attrstr, cura->sizarg + 1);
	  else
	    /* Mismatch in the value of the size argument between two
	       explicit access attributes.  */
	    warned = warning_at (curloc, OPT_Wattributes,
				 "attribute %qs mismatched positional argument "
				 "values %i and %i",
				 attrstr, newa->sizarg + 1, cura->sizarg + 1);

	  if (warned)
	    {
	      /* If the previous declaration is a function (as opposed
		 to a typedef of one), find the location of the array
		 or pointer argument that uses the conflicting VLA bound
		 and point to it in the note.  */
	      const attr_access* const pa = cura->size ? cura : newa;
	      tree size = pa->size ? TREE_VALUE (pa->size) : NULL_TREE;
	      if (size && DECL_P (size))
		{
		  location_t argloc = UNKNOWN_LOCATION;
		  if (tree arg = get_argument (node[2], pa->ptrarg))
		    argloc = DECL_SOURCE_LOCATION (arg);

		  gcc_rich_location richloc (DECL_SOURCE_LOCATION (size));
		  if (argloc != UNKNOWN_LOCATION)
		    richloc.add_range (argloc);

		  inform (&richloc, "designating the bound of variable "
			  "length array argument %u",
			  pa->ptrarg + 1);
		}
	      else if (prevloc != UNKNOWN_LOCATION)
		inform (prevloc, "previous declaration here");
	    }

	  continue;
	}

      if (newa->internal_p == cura->internal_p)
	continue;

      /* Merge the CURA and NEWA.  */
      attr_access merged = newaxsref.second;

      /* VLA seen in a declaration takes precedence.  */
      if (cura->minsize == HOST_WIDE_INT_M1U)
	merged.minsize = HOST_WIDE_INT_M1U;

      /* Use the explicitly specified size positional argument.  */
      if (cura->sizarg != UINT_MAX)
	merged.sizarg = cura->sizarg;

      /* Use the explicitly specified mode.  */
      if (merged.mode == access_deferred)
	merged.mode = cura->mode;

      tree str = merged.to_internal_string ();
      spec += TREE_STRING_POINTER (str);
    }

  if (!spec.length ())
    return NULL_TREE;

  return build_string (spec.length (), spec.c_str ());
}

/* Convenience wrapper for the above.  */

tree
append_access_attr (tree node[3], tree attrs, const char *attrstr,
		    char code, HOST_WIDE_INT idxs[2])
{
  char attrspec[80];
  int n = sprintf (attrspec, "%c%u", code, (unsigned) idxs[0] - 1);
  if (idxs[1])
    n += sprintf (attrspec + n, ",%u", (unsigned) idxs[1] - 1);

  return append_access_attr (node, attrs, attrstr, attrspec);
}

/* Handle the access attribute for function type NODE[0], with the function
   DECL optionally in NODE[1].  The handler is called both in response to
   an explict attribute access on a declaration with a mode and one or two
   positional arguments, and for internally synthesized access specifications
   with a string argument optionally followd by a DECL or expression
   representing a VLA bound.  To speed up parsing, the handler transforms
   the attribute and its arguments into a string.  */

static tree
handle_access_attribute (tree node[3], tree name, tree args, int flags,
			 bool *no_add_attrs)
{
  tree attrs = TYPE_ATTRIBUTES (*node);
  tree type = *node;
  if (POINTER_TYPE_P (type))
    {
      tree ptype = TREE_TYPE (type);
      if (FUNC_OR_METHOD_TYPE_P (ptype))
	type = ptype;
    }

  *no_add_attrs = true;

  /* Verify a full prototype is provided so that the argument types
     can be validated.  Avoid diagnosing type-generic built-ins since
     those have no prototype.  */
  if (!args
      && !prototype_p (type)
      && (!attrs || !lookup_attribute ("type generic", attrs)))
    {
      error ("attribute %qE without arguments on a non-prototype", name);
      return NULL_TREE;
    }

  tree access_mode = TREE_VALUE (args);
  if (TREE_CODE (access_mode) == STRING_CST)
    {
      const char* const str = TREE_STRING_POINTER (access_mode);
      if (*str == '+')
	{
	  /* This is a request to merge an internal specification for
	     a function declaration involving arrays but no explicit
	     attribute access.  */
	  tree vblist = TREE_CHAIN (args);
	  tree axstr = append_access_attr (node, attrs, NULL, str + 1,
					   vblist);
	  if (!axstr)
	    return NULL_TREE;

	  /* Replace any existing access attribute specification with
	     the concatenation above.  */
	  tree axsat = tree_cons (NULL_TREE, axstr, vblist);
	  axsat = tree_cons (name, axsat, NULL_TREE);

	  /* Recursively call self to "replace" the documented/external
	     form of the attribute with the condensend internal form.  */
	  decl_attributes (node, axsat, flags | ATTR_FLAG_INTERNAL);
	  return NULL_TREE;
	}

      if (flags & ATTR_FLAG_INTERNAL)
	{
	  /* This is a recursive call to handle the condensed internal
	     form of the attribute (see below).  Since all validation
	     has been done simply return here, accepting the attribute
	     as is.  */
	  *no_add_attrs = false;
	  return NULL_TREE;
	}
    }

  /* Set to true when the access mode has the form of a function call
     as in 'attribute (read_only (1, 2))'.  That's an easy mistake to
     make and so worth a special diagnostic.  */
  bool funcall = false;
  if (TREE_CODE (access_mode) == CALL_EXPR)
    {
      access_mode = CALL_EXPR_FN (access_mode);
      if (TREE_CODE (access_mode) != ADDR_EXPR)
	{
	  error ("attribute %qE invalid mode", name);
	  return NULL_TREE;
	}
      access_mode = TREE_OPERAND (access_mode, 0);
      access_mode = DECL_NAME (access_mode);
      funcall = true;
    }
  else if (TREE_CODE (access_mode) != IDENTIFIER_NODE)
    {
      error ("attribute %qE mode %qE is not an identifier; expected one of "
	     "%qs, %qs, %qs, or %qs", name, access_mode,
	     "read_only", "read_write", "write_only", "none");
      return NULL_TREE;
    }

  const char* const access_str = IDENTIFIER_POINTER (access_mode);
  const char *ps = access_str;
  if (ps[0] == '_' && ps[1] == '_')
    {
      size_t len = strlen (ps);
      if (ps[len - 1] == '_' && ps[len - 2] == '_')
	ps += 2;
    }

  int imode;

  {
    const int nmodes =
      sizeof attr_access::mode_names / sizeof *attr_access::mode_names;

    for (imode = 0; imode != nmodes; ++imode)
      if (!strncmp (ps, attr_access::mode_names[imode],
		    strlen (attr_access::mode_names[imode])))
	break;

    if (imode == nmodes)
      {
	error ("attribute %qE invalid mode %qs; expected one of "
	       "%qs, %qs, %qs, or %qs", name, access_str,
	       "read_only", "read_write", "write_only", "none");
	return NULL_TREE;
      }
  }

  const ::access_mode mode = static_cast<::access_mode>(imode);

  if (funcall)
    {
      error ("attribute %qE unexpected %<(%> after mode %qs; expected "
	     "a positional argument or %<)%>",
	     name, access_str);
      return NULL_TREE;
    }

  args = TREE_CHAIN (args);
  if (!args)
    {
      /* The first positional argument is required.  It may be worth
	 dropping the requirement at some point and having read_only
	 apply to all const-qualified pointers and read_write or
	 write_only to the rest.  */
      error ("attribute %<%E(%s)%> missing an argument",
	     name, access_str);
      return NULL_TREE;
    }

  /* One or more positional arguments have been specified.  Validate
     them.  */
  tree idxnodes[2] = { NULL_TREE, NULL_TREE };
  tree argtypes[2] = { NULL_TREE, NULL_TREE };
  /* 1-based attribute positional arguments or zero if not specified.
     Invalid negative or excessive values are also stored but used
     only in diagnostics.  */
  HOST_WIDE_INT idxs[2] = { 0, 0 };

  /* Number of function formal arguments (used in diagnostics).  */
  unsigned nfuncargs = 0;
  /* Number of (optional) attribute positional arguments.  */
  unsigned nattrargs = 0;

  for (unsigned i = 0; i != 2; ++i, args = TREE_CHAIN (args), ++nattrargs)
    {
      if (!args)
	break;

      idxnodes[i] = TREE_VALUE (args);

      if (TREE_CODE (idxnodes[i]) != IDENTIFIER_NODE
	  && TREE_CODE (idxnodes[i]) != FUNCTION_DECL)
	idxnodes[i] = default_conversion (idxnodes[i]);

      if (tree_fits_shwi_p (idxnodes[i]))
	{
	  idxs[i] = tree_to_shwi (idxnodes[i]);
	  argtypes[i] = get_argument_type (type, idxs[i], &nfuncargs);
	}
    }

  if ((nattrargs == 1 && !idxs[0])
      || (nattrargs == 2 && (!idxs[0] || !idxs[1])))
    {
      if (idxnodes[1])
	error ("attribute %<%E(%s, %E, %E)%> invalid positional argument %i",
	       name, access_str, idxnodes[0], idxnodes[1], idxs[0] ? 2 : 1);
      else
	error ("attribute %<%E(%s, %E)%> invalid positional argument %i",
	       name, access_str, idxnodes[0], idxs[0] ? 2 : 1);
      return NULL_TREE;
    }

  /* Format the attribute specification to include in diagnostics.  */
  char attrstr[80];
  if (idxnodes[1])
    snprintf (attrstr, sizeof attrstr, "%s(%s, %lli, %lli)",
	      IDENTIFIER_POINTER (name), access_str,
	      (long long) idxs[0], (long long) idxs[1]);
  else if (idxnodes[0])
    snprintf (attrstr, sizeof attrstr, "%s(%s, %lli)",
	      IDENTIFIER_POINTER (name), access_str,
	      (long long) idxs[0]);
  else
    snprintf (attrstr, sizeof attrstr, "%s(%s)",
	      IDENTIFIER_POINTER (name), access_str);

  /* Verify the positional argument values are in range.  */
  if (!argtypes[0] || (idxnodes[1] && !argtypes[1]))
    {
      if (idxnodes[0])
	{
	  if (idxs[0] < 0 || idxs[1] < 0)
	    error ("attribute %qs positional argument %i invalid value %wi",
		   attrstr, idxs[0] < 0 ? 1 : 2,
		   idxs[0] < 0 ? idxs[0] : idxs[1]);
	  else
	    error ("attribute %qs positional argument %i value %wi exceeds "
		   "number of function arguments %u",
		   attrstr, idxs[0] ? 1 : 2,
		   idxs[0] ? idxs[0] : idxs[1],
		   nfuncargs);
	}
      else
	error ("attribute %qs invalid positional argument", attrstr);

      return NULL_TREE;
    }

  if (!POINTER_TYPE_P (argtypes[0]))
    {
      /* The first argument must have a pointer or reference type.  */
      error ("attribute %qs positional argument 1 references "
	     "non-pointer argument type %qT",
	     attrstr, argtypes[0]);
      return NULL_TREE;
    }

  {
    /* Pointers to functions are not allowed.  */
    tree ptrtype = TREE_TYPE (argtypes[0]);
    if (FUNC_OR_METHOD_TYPE_P (ptrtype))
      {
	error ("attribute %qs positional argument 1 references "
	       "argument of function type %qT",
	       attrstr, ptrtype);
	return NULL_TREE;
      }
  }

  if (mode == access_read_write || mode == access_write_only)
    {
      /* Read_write and write_only modes must reference non-const
	 arguments.  */
      if (TYPE_READONLY (TREE_TYPE (argtypes[0])))
	{
	  error ("attribute %qs positional argument 1 references "
		 "%qs-qualified argument type %qT",
		 attrstr, "const", argtypes[0]);
	  return NULL_TREE;
	}
    }
  else if (!TYPE_READONLY (TREE_TYPE (argtypes[0])))
    {
      /* A read_only mode should ideally reference const-qualified
	 arguments but it's not diagnosed error if one doesn't.
	 This makes it possible to annotate legacy, const-incorrect
	 APIs.  It might be worth a diagnostic along the lines of
	 -Wsuggest-const.  */
      ;
    }

  if (argtypes[1] && !INTEGRAL_TYPE_P (argtypes[1]))
    {
      error ("attribute %qs positional argument 2 references "
	     "non-integer argument type %qT",
	     attrstr, argtypes[1]);
      return NULL_TREE;
    }

  /* Verify that the new attribute doesn't conflict with any existing
     attributes specified on previous declarations of the same type
     and if not, concatenate the two.  */
  const char code = attr_access::mode_chars[mode];
  tree new_attrs = append_access_attr (node, attrs, attrstr, code, idxs);
  if (!new_attrs)
    return NULL_TREE;

  /* Replace any existing access attribute specification with
     the concatenation above.  */
  new_attrs = tree_cons (NULL_TREE, new_attrs, NULL_TREE);
  new_attrs = tree_cons (name, new_attrs, NULL_TREE);

  if (node[1])
    {
      /* Repeat for the previously declared type.  */
      attrs = TYPE_ATTRIBUTES (TREE_TYPE (node[1]));
      new_attrs = append_access_attr (node, attrs, attrstr, code, idxs);
      if (!new_attrs)
	return NULL_TREE;

      new_attrs = tree_cons (NULL_TREE, new_attrs, NULL_TREE);
      new_attrs = tree_cons (name, new_attrs, NULL_TREE);
    }

  /* Recursively call self to "replace" the documented/external form
     of the attribute with the condensed internal form.  */
  decl_attributes (node, new_attrs, flags | ATTR_FLAG_INTERNAL);
  return NULL_TREE;
}

/* Extract attribute "arg spec" from each FNDECL argument that has it,
   build a single attribute access corresponding to all the arguments,
   and return the result.  SKIP_VOIDPTR set to ignore void* parameters
   (used for user-defined functions for which, unlike in for built-ins,
   void* cannot be relied on to determine anything about the access
   through it or whether it even takes place).

   For example, the parameters in the declaration:

     void f (int x, int y, char [x][1][y][3], char [y][2][y][5]);

   result in the following attribute access:

     value: "+^2[*],$0$1^3[*],$1$1"
     list:  < <0, x> <1, y> >

   where the list has a single value which itself is is a list each
   of whose <node>s corresponds to one VLA bound for each of the two
   parameters.  */

tree
build_attr_access_from_parms (tree parms, bool skip_voidptr)
{
  /* Maps each named integral argument DECL seen so far to its position
     in the argument list; used to associate VLA sizes with arguments.  */
  hash_map<tree, unsigned> arg2pos;

  /* The string representation of the access specification for all
     arguments.  */
  std::string spec;
  unsigned argpos = 0;

  /* A TREE_LIST of VLA bounds.  */
  tree vblist = NULL_TREE;

  for (tree arg = parms; arg; arg = TREE_CHAIN (arg), ++argpos)
    {
      if (!DECL_P (arg))
	continue;

      tree argtype = TREE_TYPE (arg);
      if (DECL_NAME (arg) && INTEGRAL_TYPE_P (argtype))
	arg2pos.put (arg, argpos);

      tree argspec = DECL_ATTRIBUTES (arg);
      if (!argspec)
	continue;

      if (POINTER_TYPE_P (argtype))
	{
	  /* void* arguments in user-defined functions could point to
	     anything; skip them.  */
	  tree reftype = TREE_TYPE (argtype);
	  if (skip_voidptr && VOID_TYPE_P (reftype))
	    continue;
	}

      /* Each parameter should have at most one "arg spec" attribute.  */
      argspec = lookup_attribute ("arg spec", argspec);
      if (!argspec)
	continue;

      /* Attribute arg spec should have one or two arguments.  */
      argspec = TREE_VALUE (argspec);

      /* The attribute arg spec string.  */
      tree str = TREE_VALUE (argspec);
      const char *s = TREE_STRING_POINTER (str);

      /* Create the attribute access string from the arg spec string,
	 optionally followed by position of the VLA bound argument if
	 it is one.  */
      {
	size_t specend = spec.length ();
	if (!specend)
	  {
	    spec = '+';
	    specend = 1;
	  }

	/* Format the access string in place.  */
	int len = snprintf (NULL, 0, "%c%u%s",
			    attr_access::mode_chars[access_deferred],
			    argpos, s);
	spec.resize (specend + len + 1);
	sprintf (&spec[specend], "%c%u%s",
		 attr_access::mode_chars[access_deferred],
		 argpos, s);
	/* Trim the trailing NUL.  */
	spec.resize (specend + len);
      }

      /* The (optional) list of expressions denoting the VLA bounds
	 N in ARGTYPE <arg>[Ni]...[Nj]...[Nk].  */
      tree argvbs = TREE_CHAIN (argspec);
      if (argvbs)
	{
	  spec += ',';
	  /* Add ARGVBS to the list.  Their presence is indicated by
	     appending a comma followed by the dollar sign and, when
	     it corresponds to a function parameter, the position of
	     each bound Ni, so it can be distinguished from
	     an unspecified bound (as in T[*]).  The list is in reverse
	     order of arguments and needs to be reversed to access in
	     order.  */
	  vblist = tree_cons (NULL_TREE, argvbs, vblist);

	  unsigned nelts = 0;
	  for (tree vb = argvbs; vb; vb = TREE_CHAIN (vb), ++nelts)
	    {
	      tree bound = TREE_VALUE (vb);
	      if (const unsigned *psizpos = arg2pos.get (bound))
		{
		  /* BOUND previously seen in the parameter list.  */
		  TREE_PURPOSE (vb) = size_int (*psizpos);
		  /* Format the position string in place.  */
		  int len = snprintf (NULL, 0, "$%u", *psizpos);
		  size_t specend = spec.length ();
		  spec.resize (specend + len + 1);
		  sprintf (&spec[specend], "$%u", *psizpos);
		  /* Trim the trailing NUL.  */
		  spec.resize (specend + len);
		}
	      else
		{
		  /* BOUND doesn't name a parameter (it could be a global
		     variable or an expression such as a function call).  */
		  spec += '$';
		}
	    }
	}
    }

  if (!spec.length ())
    return NULL_TREE;

  /* Attribute access takes a two or three arguments.  Wrap VBLIST in
     another list in case it has more nodes than would otherwise fit.  */
  vblist = build_tree_list (NULL_TREE, vblist);

  /* Build a single attribute access with the string describing all
     array arguments and an optional list of any non-parameter VLA
     bounds in order.  */
  tree str = build_string (spec.length (), spec.c_str ());
  tree attrargs = tree_cons (NULL_TREE, str, vblist);
  tree name = get_identifier ("access");
  return build_tree_list (name, attrargs);
}

/* Handle a "nothrow" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_nothrow_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			  int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (TREE_CODE (*node) == FUNCTION_DECL)
    TREE_NOTHROW (*node) = 1;
  /* ??? TODO: Support types.  */
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "cleanup" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_cleanup_attribute (tree *node, tree name, tree args,
			  int ARG_UNUSED (flags), bool *no_add_attrs)
{
  tree decl = *node;
  tree cleanup_id, cleanup_decl;

  /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
     for global destructors in C++.  This requires infrastructure that
     we don't have generically at the moment.  It's also not a feature
     we'd be missing too much, since we do have attribute constructor.  */
  if (!VAR_P (decl) || TREE_STATIC (decl))
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* Verify that the argument is a function in scope.  */
  /* ??? We could support pointers to functions here as well, if
     that was considered desirable.  */
  cleanup_id = TREE_VALUE (args);
  if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
    {
      error ("cleanup argument not an identifier");
      *no_add_attrs = true;
      return NULL_TREE;
    }
  cleanup_decl = lookup_name (cleanup_id);
  if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
    {
      error ("cleanup argument not a function");
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* That the function has proper type is checked with the
     eventual call to build_function_call.  */

  return NULL_TREE;
}

/* Handle a "warn_unused_result" attribute.  No special handling.  */

static tree
handle_warn_unused_result_attribute (tree *node, tree name,
			       tree ARG_UNUSED (args),
			       int ARG_UNUSED (flags), bool *no_add_attrs)
{
  /* Ignore the attribute for functions not returning any value.  */
  if (VOID_TYPE_P (TREE_TYPE (*node)))
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "sentinel" attribute.  */

static tree
handle_sentinel_attribute (tree *node, tree name, tree args,
			   int ARG_UNUSED (flags), bool *no_add_attrs)
{
  if (!prototype_p (*node))
    {
      warning (OPT_Wattributes,
	       "%qE attribute requires prototypes with named arguments", name);
      *no_add_attrs = true;
    }
  else
    {
      if (!stdarg_p (*node))
	{
	  warning (OPT_Wattributes,
		   "%qE attribute only applies to variadic functions", name);
	  *no_add_attrs = true;
	}
    }

  if (args)
    {
      tree position = TREE_VALUE (args);
      if (position && TREE_CODE (position) != IDENTIFIER_NODE
	  && TREE_CODE (position) != FUNCTION_DECL)
	position = default_conversion (position);

      if (TREE_CODE (position) != INTEGER_CST
	  || !INTEGRAL_TYPE_P (TREE_TYPE (position)))
	{
	  warning (OPT_Wattributes,
		   "requested position is not an integer constant");
	  *no_add_attrs = true;
	}
      else
	{
	  if (tree_int_cst_lt (position, integer_zero_node))
	    {
	      warning (OPT_Wattributes,
		       "requested position is less than zero");
	      *no_add_attrs = true;
	    }
	}
    }

  return NULL_TREE;
}

/* Handle a "type_generic" attribute.  */

static tree
handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
			       tree ARG_UNUSED (args), int ARG_UNUSED (flags),
			       bool * ARG_UNUSED (no_add_attrs))
{
  /* Ensure we have a function type.  */
  gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);

  /* Ensure we have a variadic function.  */
  gcc_assert (!prototype_p (*node) || stdarg_p (*node));

  return NULL_TREE;
}

/* Handle a "target" attribute.  */

static tree
handle_target_attribute (tree *node, tree name, tree args, int flags,
			 bool *no_add_attrs)
{
  /* Ensure we have a function type.  */
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }
  else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)))
    {
      warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
		   "with %qs attribute", name, "target_clones");
      *no_add_attrs = true;
    }
  else if (! targetm.target_option.valid_attribute_p (*node, name, args,
						      flags))
    *no_add_attrs = true;

  /* Check that there's no empty string in values of the attribute.  */
  for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
    {
      tree value = TREE_VALUE (t);
      if (TREE_CODE (value) == STRING_CST
	  && TREE_STRING_LENGTH (value) == 1
	  && TREE_STRING_POINTER (value)[0] == '\0')
	{
	  warning (OPT_Wattributes, "empty string in attribute %<target%>");
	  *no_add_attrs = true;
	}
    }

  return NULL_TREE;
}

/* Handle a "target_clones" attribute.  */

static tree
handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
			  int ARG_UNUSED (flags), bool *no_add_attrs)
{
  /* Ensure we have a function type.  */
  if (TREE_CODE (*node) == FUNCTION_DECL)
    {
      if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
	{
	  error ("%qE attribute argument not a string constant", name);
	  *no_add_attrs = true;
	}
      else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
	{
	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
		   "with %qs attribute", name, "always_inline");
	  *no_add_attrs = true;
	}
      else if (lookup_attribute ("target", DECL_ATTRIBUTES (*node)))
	{
	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
		   "with %qs attribute", name, "target");
	  *no_add_attrs = true;
	}
      else
      /* Do not inline functions with multiple clone targets.  */
	DECL_UNINLINABLE (*node) = 1;
    }
  else
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }
  return NULL_TREE;
}

/* For handling "optimize" attribute. arguments as in
   struct attribute_spec.handler.  */

static tree
handle_optimize_attribute (tree *node, tree name, tree args,
			   int ARG_UNUSED (flags), bool *no_add_attrs)
{
  /* Ensure we have a function type.  */
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute ignored", name);
      *no_add_attrs = true;
    }
  else
    {
      struct cl_optimization cur_opts;
      tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);

      /* Save current options.  */
      cl_optimization_save (&cur_opts, &global_options, &global_options_set);
      tree prev_target_node = build_target_option_node (&global_options,
							&global_options_set);

      /* If we previously had some optimization options, use them as the
	 default.  */
      gcc_options *saved_global_options = NULL;

      /* When #pragma GCC optimize pragma is used, it modifies global_options
	 without calling targetm.override_options_after_change.  That can leave
	 target flags inconsistent for comparison.  */
      if (flag_checking && optimization_current_node == optimization_default_node)
	{
	  saved_global_options = XNEW (gcc_options);
	  *saved_global_options = global_options;
	}

      if (old_opts)
	cl_optimization_restore (&global_options, &global_options_set,
				 TREE_OPTIMIZATION (old_opts));

      /* Parse options, and update the vector.  */
      parse_optimize_options (args, true);
      DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
	= build_optimization_node (&global_options, &global_options_set);
      tree target_node = build_target_option_node (&global_options,
						   &global_options_set);
      if (prev_target_node != target_node)
	DECL_FUNCTION_SPECIFIC_TARGET (*node) = target_node;

      /* Restore current options.  */
      cl_optimization_restore (&global_options, &global_options_set,
			       &cur_opts);
      cl_target_option_restore (&global_options, &global_options_set,
				TREE_TARGET_OPTION (prev_target_node));

      if (saved_global_options != NULL)
	{
	  cl_optimization_compare (saved_global_options, &global_options);
	  free (saved_global_options);
	}
    }

  return NULL_TREE;
}

/* Handle a "no_split_stack" attribute.  */

static tree
handle_no_split_stack_attribute (tree *node, tree name,
				 tree ARG_UNUSED (args),
				 int ARG_UNUSED (flags),
				 bool *no_add_attrs)
{
  tree decl = *node;

  if (TREE_CODE (decl) != FUNCTION_DECL)
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"%qE attribute applies only to functions", name);
      *no_add_attrs = true;
    }
  else if (DECL_INITIAL (decl))
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"cannot set %qE attribute after definition", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "zero_call_used_regs" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_zero_call_used_regs_attribute (tree *node, tree name, tree args,
				      int ARG_UNUSED (flags),
				      bool *no_add_attrs)
{
  tree decl = *node;
  tree id = TREE_VALUE (args);

  if (TREE_CODE (decl) != FUNCTION_DECL)
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"%qE attribute applies only to functions", name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  if (TREE_CODE (id) != STRING_CST)
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"%qE argument not a string", name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  bool found = false;
  for (unsigned int i = 0; zero_call_used_regs_opts[i].name != NULL; ++i)
    if (strcmp (TREE_STRING_POINTER (id),
		zero_call_used_regs_opts[i].name) == 0)
      {
	found = true;
	break;
      }

  if (!found)
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"unrecognized %qE attribute argument %qs",
		name, TREE_STRING_POINTER (id));
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "returns_nonnull" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_returns_nonnull_attribute (tree *node, tree name, tree, int,
				  bool *no_add_attrs)
{
  // Even without a prototype we still have a return type we can check.
  if (TREE_CODE (TREE_TYPE (*node)) != POINTER_TYPE)
    {
      error ("%qE attribute on a function not returning a pointer", name);
      *no_add_attrs = true;
    }
  return NULL_TREE;
}

/* Handle a "designated_init" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_designated_init_attribute (tree *node, tree name, tree, int,
				  bool *no_add_attrs)
{
  if (TREE_CODE (*node) != RECORD_TYPE)
    {
      error ("%qE attribute is only valid on %<struct%> type", name);
      *no_add_attrs = true;
    }
  return NULL_TREE;
}


/* Handle a "fallthrough" attribute; arguments as in struct
   attribute_spec.handler.  */

tree
handle_fallthrough_attribute (tree *, tree name, tree, int,
			      bool *no_add_attrs)
{
  pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", name);
  *no_add_attrs = true;
  return NULL_TREE;
}

/* Handle a "patchable_function_entry" attributes; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_patchable_function_entry_attribute (tree *, tree name, tree args,
					   int, bool *no_add_attrs)
{
  for (; args; args = TREE_CHAIN (args))
    {
      tree val = TREE_VALUE (args);
      if (val && TREE_CODE (val) != IDENTIFIER_NODE
	  && TREE_CODE (val) != FUNCTION_DECL)
	val = default_conversion (val);

      if (!tree_fits_uhwi_p (val))
	{
	  warning (OPT_Wattributes,
		   "%qE attribute argument %qE is not an integer constant",
		   name, val);
	  *no_add_attrs = true;
	  return NULL_TREE;
	}

      if (tree_to_uhwi (val) > USHRT_MAX)
	{
	  warning (OPT_Wattributes,
		   "%qE attribute argument %qE exceeds %u",
		   name, val, USHRT_MAX);
	  *no_add_attrs = true;
	  return NULL_TREE;
	}
    }
  return NULL_TREE;
}

/* Handle a "NSObject" attributes; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_nsobject_attribute (tree *node, tree name, tree args,
			   int /*flags*/, bool *no_add_attrs)
{
  *no_add_attrs = true;

  /* This attribute only applies to typedefs (or field decls for properties),
     we drop it otherwise - but warn about this if enabled.  */
  if (TREE_CODE (*node) != TYPE_DECL && TREE_CODE (*node) != FIELD_DECL)
    {
      warning (OPT_WNSObject_attribute, "%qE attribute may be put on a"
	       " typedef only; attribute is ignored", name);
      return NULL_TREE;
    }

  /* The original implementation only allowed pointers to records, however
     recent implementations also allow void *.  */
  tree type = TREE_TYPE (*node);
  if (!type || !POINTER_TYPE_P (type)
      || (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE
          && !VOID_TYPE_P (TREE_TYPE (type))))
    {
      error ("%qE attribute is for pointer types only", name);
      return NULL_TREE;
    }

  tree t = tree_cons (name, args, TYPE_ATTRIBUTES (type));
  TREE_TYPE (*node) = build_type_attribute_variant (type, t);

  return NULL_TREE;
}

/* Handle a "objc_root_class" attributes; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_objc_root_class_attribute (tree */*node*/, tree name, tree /*args*/,
				  int /*flags*/, bool *no_add_attrs)
{
  /* This has no meaning outside Objective-C.  */
  if (!c_dialect_objc())
    warning (OPT_Wattributes, "%qE is only applicable to Objective-C"
	     " class interfaces, attribute ignored", name);

  *no_add_attrs = true;
  return NULL_TREE;
}

/* Handle an "objc_nullability" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_objc_nullability_attribute (tree *node, tree name, tree args,
				   int /*flags*/,
				   bool *no_add_attrs)
{
  *no_add_attrs = true;

  tree type = TREE_TYPE (*node);
  if (TREE_CODE (*node) == FUNCTION_DECL)
    type = TREE_TYPE (type);

  if (type && !POINTER_TYPE_P (type))
    {
      error ("%qE cannot be applied to non-pointer type %qT", name, type);
      return NULL_TREE;
    }

  /* We accept objc_nullability() with a single argument.
     string: "unspecified", "nullable", "nonnull" or "resettable"
     integer: 0 and 3 where the values have the same meaning as
     the strings.  */
  tree val = TREE_VALUE (args);
  if (TREE_CODE (val) == INTEGER_CST)
    {
      val = default_conversion (val);
      if (!tree_fits_uhwi_p (val) || tree_to_uhwi (val) > 3)
	error ("%qE attribute argument %qE is not an integer constant"
	       " between 0 and 3", name, val);
      else
	*no_add_attrs = false; /* OK */
    }
  else if (TREE_CODE (val) == STRING_CST
	   && (strcmp (TREE_STRING_POINTER (val), "nullable") == 0
	      || strcmp (TREE_STRING_POINTER (val), "nonnull") == 0
	      || strcmp (TREE_STRING_POINTER (val), "unspecified") == 0
	      || strcmp (TREE_STRING_POINTER (val), "resettable") == 0))
    *no_add_attrs = false; /* OK */
  else if (val != error_mark_node)
    error ("%qE attribute argument %qE is not recognised", name, val);

  return NULL_TREE;
}

/* Attempt to partially validate a single attribute ATTR as if
   it were to be applied to an entity OPER.  */

static bool
validate_attribute (location_t atloc, tree oper, tree attr)
{
  /* Determine whether the name of the attribute is valid
     and fail with an error if not.  */
  tree atname = get_attribute_name (attr);
  if (!lookup_attribute_spec (atname))
    {
      if (atloc != UNKNOWN_LOCATION)
	error_at (atloc, "unknown attribute %qE", atname);
      return false;
    }

  tree args = TREE_VALUE (attr);
  if (!args)
    return true;

  /* FIXME: Do some validation.  */
  const char *atstr = IDENTIFIER_POINTER (atname);
  if (!strcmp (atstr, "format"))
    return true;

  /* Only when attribute arguments have been provided try to validate
     the whole thing.  decl_attributes doesn't return an indication of
     success or failure so proceed regardless.  */
  const char tmpname[] = "__builtin_has_attribute_tmp.";
  tree tmpid = get_identifier (tmpname);
  tree tmpdecl;
  if (!strcmp (atstr, "vector_size"))
    {
      tree type = TYPE_P (oper) ? oper : TREE_TYPE (oper);
      /* Check for function type here since type_for_vector_size
	 strips it while looking for a function's return type.  */
      if (FUNC_OR_METHOD_TYPE_P (type))
	{
	  warning_at (atloc, OPT_Wattributes,
		      "invalid operand type %qT for %qs", type, atstr);
	  return false;
	}

      type = type_for_vector_size (type);
      if (VECTOR_TYPE_P (type))
	type = TREE_TYPE (type);
      /* Avoid trying to apply attribute vector_size to OPER since
	 it's overly restrictive.  Simply make sure it has the right
	 type.  */
      return type_valid_for_vector_size (type, atname, args, NULL);
    }

  if (TYPE_P (oper))
    tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
  else if (DECL_P (oper))
    tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
  else if (EXPR_P (oper))
    tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, TREE_TYPE (oper));
  else
    return false;

  /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
     believe the DECL declared above is at file scope.  (See bug 87526.)  */
  tree save_curfunc = current_function_decl;
  current_function_decl = NULL_TREE;
  if (DECL_P (tmpdecl))
    {
      if (DECL_P (oper))
	/* An alias cannot be a definition so declare the symbol extern.  */
	DECL_EXTERNAL (tmpdecl) = true;
      /* Attribute visibility only applies to symbols visible from other
	 translation units so make it "public."   */
      TREE_PUBLIC (tmpdecl) = TREE_PUBLIC (oper);
    }
  decl_attributes (&tmpdecl, attr, 0);
  current_function_decl = save_curfunc;

  /* FIXME: Change decl_attributes to indicate success or failure (and
     parameterize it to avoid failing with errors).  */
  return true;
}

/* Return true if the DECL, EXPR, or TYPE t has been declared with
   attribute ATTR.  For DECL, consider also its type.  For EXPR,
   consider just its type.  */

bool
has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree))
{
  if (!attr || !t || t == error_mark_node)
    return false;

  if (!validate_attribute (atloc, t, attr))
    return false;

  tree type = NULL_TREE;
  tree expr = NULL_TREE;
  if (TYPE_P (t))
    type = t;
  else
    {
      do
	{
	  /* Determine the array element/member declaration from
	     a COMPONENT_REF and an INDIRECT_REF involving a refeence.  */
	  STRIP_NOPS (t);
	  tree_code code = TREE_CODE (t);
	  if (code == INDIRECT_REF)
	    {
	      tree op0 = TREE_OPERAND (t, 0);
	      if (TREE_CODE (TREE_TYPE (op0)) == REFERENCE_TYPE)
		t = op0;
	      else
		break;
	    }
	  else if (code == COMPONENT_REF)
	    t = TREE_OPERAND (t, 1);
	  else
	    break;
	} while (true);
      expr = t;
    }

  /* Set to true when an attribute is found in the referenced entity
     that matches the specified attribute.  */
  bool found_match = false;

  tree atname = get_attribute_name (attr);
  const char *namestr = IDENTIFIER_POINTER (atname);

   /* Iterate once for a type and twice for a function or variable
     declaration: once for the DECL and the second time for its
     TYPE.  */
  for (bool done = false; !found_match && !done; )
    {
      tree atlist;
      if (type)
	{
	  if (type == error_mark_node)
	    {
	      /* This could be a label.  FIXME: add support for labels.  */
	      warning_at (atloc, OPT_Wattributes,
			  (TYPE_P (t)
			   ? G_("%qs attribute not supported for %qT "
				"in %<__builtin_has_attribute%>")
			   : G_("%qs attribute not supported for %qE "
				"in %<__builtin_has_attribute%>")),
			  namestr, t);
	      return false;
	    }

	  /* Clear EXPR to prevent considering it again below.  */
	  atlist = TYPE_ATTRIBUTES (type);
	  expr = NULL_TREE;
	  done = true;
	}
      else if (DECL_P (expr))
	{
	  /* Set TYPE to the DECL's type to process it on the next
	     iteration.  */
	  atlist = DECL_ATTRIBUTES (expr);
	  type = TREE_TYPE (expr);
	}
      else
	{
	  type = TREE_TYPE (expr);
	  atlist = TYPE_ATTRIBUTES (type);
	  done = true;
	}

     /* True when an attribute with the sought name (though not necessarily
	 with the sought attributes) has been found on the attribute chain.  */
      bool found_attr = false;

      /* When clear, the first mismatched attribute argument results
	 in failure.  Otherwise, the first matched attribute argument
	 results in success.  */
      bool attr_nonnull = !strcmp ("nonnull", namestr);
      bool ignore_mismatches = attr_nonnull;

      /* Iterate over the instances of the sought attribute on the DECL or
	 TYPE (there may be multiple instances with different arguments).  */
      for (; (atlist = lookup_attribute (namestr, atlist));
	   found_attr = true, atlist = TREE_CHAIN (atlist))
	{
	  /* If there are no arguments to match the result is true except
	     for nonnull where the attribute with no arguments must match.  */
	  if (!TREE_VALUE (attr))
	    return attr_nonnull ? !TREE_VALUE (atlist) : true;

	  /* Attribute nonnull with no arguments subsumes all values of
	     the attribute.  FIXME: This is overly broad since it only
	     applies to pointer arguments, but querying non-pointer
	     arguments is diagnosed.  */
	  if (!TREE_VALUE (atlist) && attr_nonnull)
	    return true;

	  /* Iterate over the DECL or TYPE attribute argument's values.  */
	  for (tree val = TREE_VALUE (atlist); val; val = TREE_CHAIN (val))
	    {
	      /* Iterate over the arguments in the sought attribute comparing
		 their values to those specified for the DECL or TYPE.  */
	      for (tree arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
		{
		  tree v1 = TREE_VALUE (val);
		  tree v2 = TREE_VALUE (arg);
		  if (v1 == v2)
		    return true;

		  if (!v1 || !v2)
		    break;

		  if (TREE_CODE (v1) == IDENTIFIER_NODE
		      || TREE_CODE (v2) == IDENTIFIER_NODE)
		    /* Two identifiers are the same if their values are
		       equal (that's handled above).  Otherwise ther are
		       either not the same or oneis not an identifier.  */
		    return false;

		  /* Convert to make them equality-comparable.  */
		  v1 = convert (v1);
		  v2 = convert (v2);

		  /* A positive value indicates equality, negative means
		     "don't know."  */
		  if (simple_cst_equal (v1, v2) == 1)
		    return true;

		  if (!ignore_mismatches)
		    break;
		}
	    }
	}

      if (!found_attr)
	{
	  /* Some attributes are encoded directly in the tree node.  */
	  if (!strcmp ("aligned", namestr))
	    {
	      if (tree arg = TREE_VALUE (attr))
		{
		  arg = convert (TREE_VALUE (arg));
		  if (!tree_fits_uhwi_p (arg))
		    /* Invalid argument.  */;
		  else if (expr && DECL_P (expr)
			   && DECL_USER_ALIGN (expr))
		    found_match = DECL_ALIGN_UNIT (expr) == tree_to_uhwi (arg);
		  else if (type && TYPE_USER_ALIGN (type))
		    found_match = TYPE_ALIGN_UNIT (type) == tree_to_uhwi (arg);
		}
	      else if (expr && DECL_P (expr))
		found_match = DECL_USER_ALIGN (expr);
	      else if (type)
		found_match = TYPE_USER_ALIGN (type);
	    }
	  else if (!strcmp ("const", namestr))
	    {
	      if (expr && DECL_P (expr))
		found_match = TREE_READONLY (expr);
	    }
	  else if (!strcmp ("noreturn", namestr))
	    {
	      /* C11 _Noreturn sets the volatile bit without attaching
		 an attribute to the decl.  */
	      if (expr
		  && DECL_P (expr)
		  && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr)))
		found_match = TREE_THIS_VOLATILE (expr);
	    }
	  else if (!strcmp ("pure", namestr))
	    {
	      if (expr && DECL_P (expr))
		found_match = DECL_PURE_P (expr);
	    }
	  else if (!strcmp ("deprecated", namestr))
	    {
	      found_match = TREE_DEPRECATED (expr ? expr : type);
	      if (found_match)
		return true;
	    }
	  else if (!strcmp ("vector_size", namestr))
	    {
	      if (!type || !VECTOR_TYPE_P (type))
		return false;

	      if (tree arg = TREE_VALUE (attr))
		{
		  /* Compare the vector size argument for equality.  */
		  arg = convert (TREE_VALUE (arg));
		  return tree_int_cst_equal (arg, TYPE_SIZE_UNIT (type)) == 1;
		}
	      else
		return true;
	    }
	  else if (!strcmp ("warn_if_not_aligned", namestr))
	    {
	      if (tree arg = TREE_VALUE (attr))
		{
		  arg = convert (TREE_VALUE (arg));
		  if (expr && DECL_P (expr))
		    found_match = (DECL_WARN_IF_NOT_ALIGN (expr)
				   == tree_to_uhwi (arg) * BITS_PER_UNIT);
		  else if (type)
		    found_match = (TYPE_WARN_IF_NOT_ALIGN (type)
				   == tree_to_uhwi (arg) * BITS_PER_UNIT);
		}
	      else if (expr && DECL_P (expr))
		found_match = DECL_WARN_IF_NOT_ALIGN (expr);
	      else if (type)
		found_match = TYPE_WARN_IF_NOT_ALIGN (type);
	    }
	  else if (!strcmp ("transparent_union", namestr))
	    {
	      if (type)
		found_match = TYPE_TRANSPARENT_AGGR (type) != 0;
	    }
	  else if (!strcmp ("mode", namestr))
	    {
	      /* Finally issue a warning for attributes that cannot
		 be supported in this context.  Attribute mode is not
		 added to a symbol and cannot be determined from it.  */
	      warning_at (atloc, OPT_Wattributes,
			  "%qs attribute not supported in "
			  "%<__builtin_has_attribute%>", namestr);
	      break;
	    }
	}
    }
  return found_match;
}
