[PATCH] make a bunch of attribute handlers globally available

Olivier Hainque hainque@adacore.com
Wed Jun 24 10:12:00 GMT 2009


Hello,

Following up a on recent exchange about vector_size handling for Ada
at http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01799.html, this is a
re-post of the patch initially suggested at

  http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01203.html

  << A number of GCC attribute handlers today shared by the C family of
     languages are needed by at least Ada and possibly others, e.g. for
     builtins support.
 
     For Ada, we so far dealt with this by copy-paste operations, not
     exactly proper software engineering practice.  We'd like to
     improve the situation, all the more that we now have needs for
     the vector_size attribute as well, and maybe others in the future.
  >>

... adjusted to account for Paolo's suggestion to move the common
attribute handling object files to libbackend instead of explicitely
adding them to every front-end.

Tested on x86_64-linux-suse with languages=all,ada.

Thanks in advance,

With Kind Regards,

Olivier

2009-06-26  Olivier Hainque  <hainque@adacore.com>

	* c-common.c (handle_noreturn_attribute, handle_const_attribute,
	handle_malloc_attribute, handle_pure_attribute,
	handle_novops_attribute, handle_vector_size_attribute,
	handle_nonnull_attribute, handle_nothrow_attribute, 
	handle_sentinel_attribute, handle_type_generic_attribute,
	get_nonnull_operand): Move bodies to attrib-handlers.c.
	(c_common_attribute_table, "noreturn", "volatile", "const", "malloc",
	"pure", "no vops", "vector_size", "nonnull", "nothrow", "sentinel",
	"type generic"): Move entries to global_attribute_table in ...
	* attrib-handlers.c: New file. Host global attribute handlers
	extracted from c-common.c.
	(global_attribute_table): Define.
	* tree.h (get_nonnull_operand): Declare.
	* attribs.c (global_attribute_table): Declare.
	(attribute_tables, init_attributes): Handle global_attribute_table.
	Use enum symbols instead of harcoded constants to designate the slots.
	* Makefile.in (attrib-handlers.o): List dependencies.
	(OBJS-common): Add attribs.o and attrib-handlers.o.
	(C_AND_OBJC_OBJS): Remove attribs.o.
	
	ada/
	* Make-lang.in (ADA_BACKEND): Remove.
	(gnat1): Use $(BACKEND) instead.
	* gcc-interface/utils.c: Remove attribute handlers formerly
	imported from c-common and now available to all languages.  Use
	NULL instead of fake_attribute_handler and remove the latter.

	cp/
	* Make-lang.in (CXX_C_OBJS): Remove attribs.o.

	fortran/
	* Make-lang.in (f951): Remove attribs.o from the dependencies.

	java/
	* Make-lang.in (jc1): Remove attribs.o from the dependencies.
	* lang.c (java_attribute_table, LANG_HOOKS_ATTRIBUTE_TABLE): Remove.

-------------- next part --------------
Index: attribs.c
===================================================================
*** attribs.c	(revision 148540)
--- attribs.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 37,45 ****
  
  static void init_attributes (void);
  
! /* Table of the tables of attributes (common, language, format, machine)
!    searched.  */
! static const struct attribute_spec *attribute_tables[4];
  
  /* Hashtable mapping names (represented as substrings) to attribute specs. */
  static htab_t attribute_hash;
--- 37,55 ----
  
  static void init_attributes (void);
  
! /* Table of the tables of attributes searched.  */
! enum {
!     ATT_GLOBAL,   /* Global, available to all languages and targets.  */
!     ATT_COMMON,   /* Common to a family of front-ends.  */
!     ATT_LANGUAGE, /* Language specific.  */
!     ATT_FORMAT,   /* For C printf format processing.  */
!     ATT_MACHINE,  /* Machine specific.  */
!     N_ATT
! };
! static const struct attribute_spec *attribute_tables[N_ATT];
! 
! /* The global attribute table, exposed by a dedicated unit.  */
! extern const struct attribute_spec global_attribute_table[];
  
  /* Hashtable mapping names (represented as substrings) to attribute specs. */
  static htab_t attribute_hash;
*************** init_attributes (void)
*** 114,123 ****
    size_t i;
    int k;
  
!   attribute_tables[0] = lang_hooks.common_attribute_table;
!   attribute_tables[1] = lang_hooks.attribute_table;
!   attribute_tables[2] = lang_hooks.format_attribute_table;
!   attribute_tables[3] = targetm.attribute_table;
  
    /* Translate NULL pointers to pointers to the empty table.  */
    for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
--- 124,134 ----
    size_t i;
    int k;
  
!   attribute_tables[ATT_GLOBAL]   = global_attribute_table;
!   attribute_tables[ATT_COMMON]   = lang_hooks.common_attribute_table;
!   attribute_tables[ATT_LANGUAGE] = lang_hooks.attribute_table;
!   attribute_tables[ATT_FORMAT]   = lang_hooks.format_attribute_table;
!   attribute_tables[ATT_MACHINE]  = targetm.attribute_table;
  
    /* Translate NULL pointers to pointers to the empty table.  */
    for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
Index: java/Make-lang.in
===================================================================
*** java/Make-lang.in	(revision 148540)
--- java/Make-lang.in	(working copy)
*************** java-warn = $(STRICT_WARN)
*** 98,107 ****
  # String length warnings
  jvspec.o-warn = -Wno-error
  
! jc1$(exeext): $(JAVA_OBJS) $(BACKEND) $(LIBDEPS) attribs.o
  	rm -f $@
  	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
! 		$(JAVA_OBJS) $(BACKEND) $(ZLIB) $(LIBICONV) $(LIBS) attribs.o $(BACKENDLIBS)
  
  jcf-dump$(exeext): $(JCFDUMP_OBJS) $(LIBDEPS)
  	rm -f $@
--- 98,108 ----
  # String length warnings
  jvspec.o-warn = -Wno-error
  
! jc1$(exeext): $(JAVA_OBJS) $(BACKEND) $(LIBDEPS)
  	rm -f $@
  	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
! 		$(JAVA_OBJS) $(BACKEND) $(ZLIB) $(LIBICONV) $(LIBS) \
! 		$(BACKENDLIBS)
  
  jcf-dump$(exeext): $(JCFDUMP_OBJS) $(LIBDEPS)
  	rm -f $@
Index: java/lang.c
===================================================================
*** java/lang.c	(revision 148540)
--- java/lang.c	(working copy)
*************** static enum classify_record java_classif
*** 68,81 ****
  # define TARGET_OBJECT_SUFFIX ".o"
  #endif
  
- /* Table of machine-independent attributes.  */
- const struct attribute_spec java_attribute_table[] =
- {
-  { "nonnull",                0, -1, false, true, true,
- 			      NULL },
-   { NULL,                     0, 0, false, false, false, NULL }
- };
- 
  /* Used to avoid printing error messages with bogus function
     prototypes.  Starts out false.  */
  static bool inhibit_error_function_printing;
--- 68,73 ----
*************** struct GTY(()) language_function {
*** 157,165 ****
  #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
  #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME java_mangle_decl
  
- #undef LANG_HOOKS_ATTRIBUTE_TABLE
- #define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table
- 
  /* Each front end provides its own.  */
  const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
  
--- 149,154 ----
Index: tree.h
===================================================================
*** tree.h	(revision 148540)
--- tree.h	(working copy)
*************** extern const struct attribute_spec *look
*** 4985,4990 ****
--- 4985,4995 ----
     a decl attribute to the declaration rather than to its type).  */
  extern tree decl_attributes (tree *, tree, int);
  
+ /* In attrib-handlers.c.  */
+ 
+ /* Fetch operand number from the attribute argument list.  */
+ extern bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
+ 
  /* In integrate.c */
  extern void set_decl_abstract_flags (tree, int);
  extern void set_decl_origin_self (tree);
Index: cp/Make-lang.in
===================================================================
*** cp/Make-lang.in	(revision 148540)
--- cp/Make-lang.in	(working copy)
*************** g++-cross$(exeext): g++$(exeext)
*** 70,76 ****
  
  # The compiler itself.
  # Shared with C front end:
! CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
  	c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
  	incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
  	c-gimplify.o c-omp.o tree-inline.o
--- 70,76 ----
  
  # The compiler itself.
  # Shared with C front end:
! CXX_C_OBJS = c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
  	c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
  	incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
  	c-gimplify.o c-omp.o tree-inline.o
Index: ada/gcc-interface/utils.c
===================================================================
*** ada/gcc-interface/utils.c	(revision 148540)
--- ada/gcc-interface/utils.c	(working copy)
*************** tree gnat_std_decls[(int) ADT_LAST];
*** 90,134 ****
  /* Functions to call for each of the possible raise reasons.  */
  tree gnat_raise_decls[(int) LAST_REASON_CODE + 1];
  
- /* Forward declarations for handlers of attributes.  */
- static tree handle_const_attribute (tree *, tree, tree, int, bool *);
- static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
- static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
- static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
- static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
- static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
- static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
- static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
- static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
- 
- /* Fake handler for attributes we don't properly support, typically because
-    they'd require dragging a lot of the common-c front-end circuitry.  */
- static tree fake_attribute_handler      (tree *, tree, tree, int, bool *);
- 
- /* Table of machine-independent internal attributes for Ada.  We support
-    this minimal set of attributes to accommodate the needs of builtins.  */
- const struct attribute_spec gnat_internal_attribute_table[] =
- {
-   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-   { "const",        0, 0,  true,  false, false, handle_const_attribute   },
-   { "nothrow",      0, 0,  true,  false, false, handle_nothrow_attribute },
-   { "pure",         0, 0,  true,  false, false, handle_pure_attribute },
-   { "no vops",      0, 0,  true,  false, false, handle_novops_attribute },
-   { "nonnull",      0, -1, false, true,  true,  handle_nonnull_attribute },
-   { "sentinel",     0, 1,  false, true,  true,  handle_sentinel_attribute },
-   { "noreturn",     0, 0,  true,  false, false, handle_noreturn_attribute },
-   { "malloc",       0, 0,  true,  false, false, handle_malloc_attribute },
-   { "type generic", 0, 0, false, true, true, handle_type_generic_attribute },
- 
-   /* ??? format and format_arg are heavy and not supported, which actually
-      prevents support for stdio builtins, which we however declare as part
-      of the common builtins.def contents.  */
-   { "format",     3, 3,  false, true,  true,  fake_attribute_handler },
-   { "format_arg", 1, 1,  false, true,  true,  fake_attribute_handler },
- 
-   { NULL,         0, 0, false, false, false, NULL }
- };
- 
  /* Associates a GNAT tree node to a GCC tree node. It is used in
     `save_gnu_tree', `get_gnu_tree' and `present_gnu_tree'. See documentation
     of `save_gnu_tree' for more info.  */
--- 90,95 ----
*************** install_builtin_attributes (void)
*** 4998,5249 ****
  #undef DEF_ATTR_TREE_LIST
  }
  
! /* Handle a "const" attribute; arguments as in
!    struct attribute_spec.handler.  */
! 
! static tree
! handle_const_attribute (tree *node, tree ARG_UNUSED (name),
! 			tree ARG_UNUSED (args), int ARG_UNUSED (flags),
! 			bool *no_add_attrs)
! {
!   if (TREE_CODE (*node) == FUNCTION_DECL)
!     TREE_READONLY (*node) = 1;
!   else
!     *no_add_attrs = true;
! 
!   return NULL_TREE;
! }
! 
! /* Handle a "nothrow" attribute; arguments as in
!    struct attribute_spec.handler.  */
! 
! static tree
! handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),
! 			  tree ARG_UNUSED (args), int ARG_UNUSED (flags),
! 			  bool *no_add_attrs)
! {
!   if (TREE_CODE (*node) == FUNCTION_DECL)
!     TREE_NOTHROW (*node) = 1;
!   else
!     *no_add_attrs = true;
! 
!   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)
!     DECL_PURE_P (*node) = 1;
!   /* ??? TODO: Support types.  */
!   else
!     {
!       warning (OPT_Wattributes, "%qE attribute ignored", name);
!       *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;
! }
! 
! /* Helper for nonnull attribute handling; fetch the operand number
!    from the attribute argument list.  */
! 
! static bool
! get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
! {
!   /* Verify the arg number is a constant.  */
!   if (TREE_CODE (arg_num_expr) != INTEGER_CST
!       || TREE_INT_CST_HIGH (arg_num_expr) != 0)
!     return false;
! 
!   *valp = TREE_INT_CST_LOW (arg_num_expr);
!   return true;
! }
! 
! /* Handle the "nonnull" attribute.  */
! static tree
! handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
! 			  tree args, int ARG_UNUSED (flags),
! 			  bool *no_add_attrs)
! {
!   tree type = *node;
!   unsigned HOST_WIDE_INT attr_arg_num;
! 
!   /* 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.  */
!   if (!args)
!     {
!       if (!TYPE_ARG_TYPES (type))
! 	{
! 	  error ("nonnull attribute without arguments on a non-prototype");
! 	  *no_add_attrs = true;
! 	}
!       return NULL_TREE;
!     }
! 
!   /* Argument list specified.  Verify that each argument number references
!      a pointer argument.  */
!   for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
!     {
!       tree argument;
!       unsigned HOST_WIDE_INT arg_num = 0, ck_num;
! 
!       if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
! 	{
! 	  error ("nonnull argument has invalid operand number (argument %lu)",
! 		 (unsigned long) attr_arg_num);
! 	  *no_add_attrs = true;
! 	  return NULL_TREE;
! 	}
! 
!       argument = TYPE_ARG_TYPES (type);
!       if (argument)
! 	{
! 	  for (ck_num = 1; ; ck_num++)
! 	    {
! 	      if (!argument || ck_num == arg_num)
! 		break;
! 	      argument = TREE_CHAIN (argument);
! 	    }
! 
! 	  if (!argument
! 	      || TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
! 	    {
! 	      error ("nonnull argument with out-of-range operand number (argument %lu, operand %lu)",
! 		     (unsigned long) attr_arg_num, (unsigned long) arg_num);
! 	      *no_add_attrs = true;
! 	      return NULL_TREE;
! 	    }
! 
! 	  if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
! 	    {
! 	      error ("nonnull argument references non-pointer operand (argument %lu, operand %lu)",
! 		   (unsigned long) attr_arg_num, (unsigned long) arg_num);
! 	      *no_add_attrs = true;
! 	      return NULL_TREE;
! 	    }
! 	}
!     }
! 
!   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)
! {
!   tree params = TYPE_ARG_TYPES (*node);
! 
!   if (!params)
!     {
!       warning (OPT_Wattributes,
! 	       "%qE attribute requires prototypes with named arguments", name);
!       *no_add_attrs = true;
!     }
!   else
!     {
!       while (TREE_CHAIN (params))
! 	params = TREE_CHAIN (params);
! 
!       if (VOID_TYPE_P (TREE_VALUE (params)))
!         {
! 	  warning (OPT_Wattributes,
! 		   "%qE attribute only applies to variadic functions", name);
! 	  *no_add_attrs = true;
! 	}
!     }
! 
!   if (args)
!     {
!       tree position = TREE_VALUE (args);
! 
!       if (TREE_CODE (position) != INTEGER_CST)
!         {
! 	  warning (0, "requested position is not an integer constant");
! 	  *no_add_attrs = true;
! 	}
!       else
!         {
! 	  if (tree_int_cst_lt (position, integer_zero_node))
! 	    {
! 	      warning (0, "requested position is less than zero");
! 	      *no_add_attrs = true;
! 	    }
! 	}
!     }
! 
!   return NULL_TREE;
! }
! 
! /* Handle a "noreturn" attribute; arguments as in
!    struct attribute_spec.handler.  */
! 
! static 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)
!     TREE_THIS_VOLATILE (*node) = 1;
!   else if (TREE_CODE (type) == POINTER_TYPE
! 	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
!     TREE_TYPE (*node)
!       = build_pointer_type
! 	(build_type_variant (TREE_TYPE (type),
! 			     TYPE_READONLY (TREE_TYPE (type)), 1));
!   else
!     {
!       warning (OPT_Wattributes, "%qE attribute ignored", name);
!       *no_add_attrs = true;
!     }
! 
!   return NULL_TREE;
! }
! 
! /* Handle a "malloc" attribute; arguments as in
!    struct attribute_spec.handler.  */
! 
! static tree
! handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
! 			 int ARG_UNUSED (flags), bool *no_add_attrs)
! {
!   if (TREE_CODE (*node) == FUNCTION_DECL
!       && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
!     DECL_IS_MALLOC (*node) = 1;
!   else
!     {
!       warning (OPT_Wattributes, "%qE attribute ignored", name);
!       *no_add_attrs = true;
!     }
  
!   return NULL_TREE;
! }
  
  /* Fake handler for attributes we don't properly support.  */
  
! tree
  fake_attribute_handler (tree * ARG_UNUSED (node),
  			tree ARG_UNUSED (name),
  			tree ARG_UNUSED (args),
--- 4959,4976 ----
  #undef DEF_ATTR_TREE_LIST
  }
  
! /* ----------------------------------------------------------------------- *
!  *                            ATTRIBUTES HANDLERS                          *
!  * ----------------------------------------------------------------------- */
  
! /* Most of the attributes are simple and have a common handler for all
!    languages.  The io format related attributes are complex and very C
!    specific, so remain part of the C family specific units.  We fake them
!    for Ada and don't support the corresponding builtin functions.  */
  
  /* Fake handler for attributes we don't properly support.  */
  
! static tree
  fake_attribute_handler (tree * ARG_UNUSED (node),
  			tree ARG_UNUSED (name),
  			tree ARG_UNUSED (args),
*************** fake_attribute_handler (tree * ARG_UNUSE
*** 5253,5279 ****
    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))
  {
!   tree params;
! 
!   /* Ensure we have a function type.  */
!   gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
! 
!   params = TYPE_ARG_TYPES (*node);
!   while (params && ! VOID_TYPE_P (TREE_VALUE (params)))
!     params = TREE_CHAIN (params);
! 
!   /* Ensure we have a variadic function.  */
!   gcc_assert (!params);
  
!   return NULL_TREE;
! }
  
  /* ----------------------------------------------------------------------- *
   *                              BUILTIN FUNCTIONS                          *
--- 4980,4992 ----
    return NULL_TREE;
  }
  
! const struct attribute_spec gnat_internal_attribute_table[] =
  {
!   { "format",     3, 3,  false, true,  true,  fake_attribute_handler },
!   { "format_arg", 1, 1,  false, true,  true,  fake_attribute_handler },
  
!   { NULL,         0, 0, false, false, false, NULL }
! };
  
  /* ----------------------------------------------------------------------- *
   *                              BUILTIN FUNCTIONS                          *
Index: ada/gcc-interface/Make-lang.in
===================================================================
*** ada/gcc-interface/Make-lang.in	(revision 148540)
--- ada/gcc-interface/Make-lang.in	(working copy)
*************** GNATBIND_OBJS = \
*** 299,315 ****
  EXTRA_GNAT1_OBJS = prefix.o
  EXTRA_GNATBIND_OBJS = prefix.o version.o
  
- # Language-independent object files.
- ADA_BACKEND = $(BACKEND) attribs.o
- 
  # List of target dependent sources, overridden below as necessary
  TARGET_ADA_SRCS =
  
  # Needs to be built with CC=gcc
  # Since the RTL should be built with the latest compiler, remove the
  #  stamp target in the parent directory whenever gnat1 is rebuilt
! gnat1$(exeext): $(TARGET_ADA_SRCS) $(GNAT1_OBJS) $(ADA_BACKEND) $(LIBDEPS)
! 	$(GCC_LINK) -o $@ $(GNAT1_OBJS) $(ADA_BACKEND) $(LIBS) $(SYSLIBS) $(BACKENDLIBS) $(CFLAGS)
  	$(RM) stamp-gnatlib2-rts stamp-tools
  
  gnatbind$(exeext): ada/b_gnatb.o $(CONFIG_H) $(GNATBIND_OBJS)
--- 299,312 ----
  EXTRA_GNAT1_OBJS = prefix.o
  EXTRA_GNATBIND_OBJS = prefix.o version.o
  
  # List of target dependent sources, overridden below as necessary
  TARGET_ADA_SRCS =
  
  # Needs to be built with CC=gcc
  # Since the RTL should be built with the latest compiler, remove the
  #  stamp target in the parent directory whenever gnat1 is rebuilt
! gnat1$(exeext): $(TARGET_ADA_SRCS) $(GNAT1_OBJS) $(BACKEND) $(LIBDEPS)
! 	$(GCC_LINK) -o $@ $(GNAT1_OBJS) $(BACKEND) $(LIBS) $(SYSLIBS) $(BACKENDLIBS) $(CFLAGS)
  	$(RM) stamp-gnatlib2-rts stamp-tools
  
  gnatbind$(exeext): ada/b_gnatb.o $(CONFIG_H) $(GNATBIND_OBJS)
Index: fortran/Make-lang.in
===================================================================
*** fortran/Make-lang.in	(revision 148540)
--- fortran/Make-lang.in	(working copy)
*************** gfortran-cross$(exeext): gfortran$(exeex
*** 95,104 ****
  	cp gfortran$(exeext) gfortran-cross$(exeext)
  
  # The compiler itself is called f951.
! f951$(exeext): $(F95_OBJS) \
! 		$(BACKEND) $(LIBDEPS) attribs.o
  	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
! 		$(F95_OBJS) $(BACKEND) $(LIBS) attribs.o $(BACKENDLIBS)
  
  gt-fortran-trans.h    : s-gtype; @true
  #
--- 95,103 ----
  	cp gfortran$(exeext) gfortran-cross$(exeext)
  
  # The compiler itself is called f951.
! f951$(exeext): $(F95_OBJS) $(BACKEND) $(LIBDEPS)
  	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
! 		$(F95_OBJS) $(BACKEND) $(LIBS) $(BACKENDLIBS)
  
  gt-fortran-trans.h    : s-gtype; @true
  #
Index: attrib-handlers.c
===================================================================
*** attrib-handlers.c	(revision 0)
--- attrib-handlers.c	(revision 0)
***************
*** 0 ****
--- 1,438 ----
+ /* Global attribute handlers.
+    Copyright (C) 2009 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/>.  */
+ 
+ /* This unit exposes attribute handlers of possible use to all front-ends and
+    known to be of use to at least the C family plus another language.  Typical
+    examples are handlers for attributes of builtin functions or those required
+    to access to core compiler features such as vector modes processing.  */
+ 
+ /* Some handlers use C specific format specifiers in warning messages.  Make
+    sure they are properly recognized.  */
+ #define GCC_DIAG_STYLE __gcc_cdiag__
+ 
+ #include <config.h>
+ #include <system.h>
+ #include <coretypes.h>
+ #include <tm.h>
+ #include <tree.h>
+ #include <langhooks.h>
+ #include <toplev.h>
+ 
+ /* Fetch operand number from the attribute argument list.  */
+ 
+ bool
+ get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
+ {
+   /* Verify the arg number is a constant.  */
+   if (TREE_CODE (arg_num_expr) != INTEGER_CST
+       || TREE_INT_CST_HIGH (arg_num_expr) != 0)
+     return false;
+ 
+   *valp = TREE_INT_CST_LOW (arg_num_expr);
+   return true;
+ }
+ 
+ /* Handle a "const" attribute.  */
+ 
+ static tree
+ handle_const_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 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_pointer_type
+ 	(build_type_variant (TREE_TYPE (type), 1,
+ 			     TREE_THIS_VOLATILE (TREE_TYPE (type))));
+   else
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
+       *no_add_attrs = true;
+     }
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Handle a "nothrow" attribute.  */
+ 
+ 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 "pure" attribute.  */
+ 
+ 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)
+     DECL_PURE_P (*node) = 1;
+   /* ??? TODO: Support types.  */
+   else
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
+       *no_add_attrs = true;
+     }
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Handle a "no vops" attribute.  */
+ 
+ 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 the "nonnull" attribute.  */
+ 
+ static tree
+ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
+ 			  tree args, int ARG_UNUSED (flags),
+ 			  bool *no_add_attrs)
+ {
+   tree type = *node;
+   unsigned HOST_WIDE_INT attr_arg_num;
+ 
+   /* 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.  */
+   if (!args)
+     {
+       if (!TYPE_ARG_TYPES (type))
+ 	{
+ 	  error ("nonnull attribute without arguments on a non-prototype");
+ 	  *no_add_attrs = true;
+ 	}
+       return NULL_TREE;
+     }
+ 
+   /* Argument list specified.  Verify that each argument number references
+      a pointer argument.  */
+   for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
+     {
+       tree argument;
+       unsigned HOST_WIDE_INT arg_num = 0, ck_num;
+ 
+       if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
+ 	{
+ 	  error ("nonnull argument has invalid operand number (argument %lu)",
+ 		 (unsigned long) attr_arg_num);
+ 	  *no_add_attrs = true;
+ 	  return NULL_TREE;
+ 	}
+ 
+       argument = TYPE_ARG_TYPES (type);
+       if (argument)
+ 	{
+ 	  for (ck_num = 1; ; ck_num++)
+ 	    {
+ 	      if (!argument || ck_num == arg_num)
+ 		break;
+ 	      argument = TREE_CHAIN (argument);
+ 	    }
+ 
+ 	  if (!argument
+ 	      || TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
+ 	    {
+ 	      error ("nonnull argument with out-of-range operand number "
+ 		     "(argument %lu, operand %lu)",
+ 		     (unsigned long) attr_arg_num, (unsigned long) arg_num);
+ 	      *no_add_attrs = true;
+ 	      return NULL_TREE;
+ 	    }
+ 
+ 	  if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
+ 	    {
+ 	      error ("nonnull argument references non-pointer operand "
+ 		     "(argument %lu, operand %lu)",
+ 		   (unsigned long) attr_arg_num, (unsigned long) arg_num);
+ 	      *no_add_attrs = true;
+ 	      return NULL_TREE;
+ 	    }
+ 	}
+     }
+ 
+   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)
+ {
+   tree params = TYPE_ARG_TYPES (*node);
+ 
+   if (!params)
+     {
+       warning (OPT_Wattributes,
+ 	       "%qE attribute requires prototypes with named arguments", name);
+       *no_add_attrs = true;
+     }
+   else
+     {
+       while (TREE_CHAIN (params))
+ 	params = TREE_CHAIN (params);
+ 
+       if (VOID_TYPE_P (TREE_VALUE (params)))
+ 	{
+ 	  warning (OPT_Wattributes,
+ 		   "%qE attribute only applies to variadic functions", name);
+ 	  *no_add_attrs = true;
+ 	}
+     }
+ 
+   if (args)
+     {
+       tree position = TREE_VALUE (args);
+ 
+       if (TREE_CODE (position) != INTEGER_CST)
+ 	{
+ 	  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 "noreturn" attribute.  */
+ 
+ static 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)
+     TREE_THIS_VOLATILE (*node) = 1;
+   else if (TREE_CODE (type) == POINTER_TYPE
+ 	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
+     TREE_TYPE (*node)
+       = build_pointer_type
+ 	(build_type_variant (TREE_TYPE (type),
+ 			     TYPE_READONLY (TREE_TYPE (type)), 1));
+   else
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
+       *no_add_attrs = true;
+     }
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Handle a "malloc" attribute.  */
+ 
+ static tree
+ handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+ 			 int ARG_UNUSED (flags), bool *no_add_attrs)
+ {
+   if (TREE_CODE (*node) == FUNCTION_DECL
+       && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
+     DECL_IS_MALLOC (*node) = 1;
+   else
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
+       *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))
+ {
+   tree params;
+   
+   /* Ensure we have a function type.  */
+   gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
+   
+   params = TYPE_ARG_TYPES (*node);
+   while (params && ! VOID_TYPE_P (TREE_VALUE (params)))
+     params = TREE_CHAIN (params);
+ 
+   /* Ensure we have a variadic function.  */
+   gcc_assert (!params);
+ 
+   return NULL_TREE;
+ }
+ 
+ /* Handle a "vector_size" attribute.  */
+ 
+ static tree
+ handle_vector_size_attribute (tree *node, tree name, tree args,
+ 			      int ARG_UNUSED (flags),
+ 			      bool *no_add_attrs)
+ {
+   unsigned HOST_WIDE_INT vecsize, nunits;
+   enum machine_mode orig_mode;
+   tree type = *node, new_type, size;
+ 
+   *no_add_attrs = true;
+ 
+   size = TREE_VALUE (args);
+ 
+   if (!host_integerp (size, 1))
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
+       return NULL_TREE;
+     }
+ 
+   /* Get the vector size (in bytes).  */
+   vecsize = tree_low_cst (size, 1);
+ 
+   /* 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);
+ 
+   /* Get the mode of the type being modified.  */
+   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))
+       || !host_integerp (TYPE_SIZE_UNIT (type), 1)
+       || TREE_CODE (type) == BOOLEAN_TYPE)
+     {
+       error ("invalid vector type for attribute %qE", name);
+       return NULL_TREE;
+     }
+ 
+   if (vecsize % tree_low_cst (TYPE_SIZE_UNIT (type), 1))
+     {
+       error ("vector size not an integral multiple of component size");
+       return NULL;
+     }
+ 
+   if (vecsize == 0)
+     {
+       error ("zero vector size");
+       return NULL;
+     }
+ 
+   /* Calculate how many units fit in the vector.  */
+   nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1);
+   if (nunits & (nunits - 1))
+     {
+       error ("number of components of the vector not a power of two");
+       return 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;
+ }
+ 
+ 
+ /* Global attribute table, available to all the target machines and language
+    front-ends.  */
+ 
+ const struct attribute_spec global_attribute_table[] =
+ {
+   /* FIXME: logically, noreturn and const 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,
+ 			      handle_noreturn_attribute },
+   { "volatile",               0, 0, true,  false, false,
+ 			      handle_noreturn_attribute },
+   { "const",                  0, 0, true,  false, false,
+ 			      handle_const_attribute },
+   { "nothrow",                0, 0, true,  false, false,
+ 			      handle_nothrow_attribute },
+   { "pure",                   0, 0, true,  false, false,
+ 			      handle_pure_attribute },
+   { "nonnull",                0, -1, false, true, true,
+ 			      handle_nonnull_attribute },
+   { "sentinel",               0, 1, false, true, true,
+ 			      handle_sentinel_attribute },
+   { "malloc",                 0, 0, true,  false, false,
+ 			      handle_malloc_attribute },
+   /* 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,
+ 			      handle_novops_attribute },
+   { "type generic",           0, 0, false, true, true,
+ 			      handle_type_generic_attribute },
+ 
+   { "vector_size",	      1, 1, false, true, false,
+ 			      handle_vector_size_attribute },
+ 
+   { NULL,         0, 0, false, false, false, NULL }
+ };
+ 
+ 
Index: c-common.c
===================================================================
*** c-common.c	(revision 148540)
--- c-common.c	(working copy)
*************** static bool check_case_bounds (tree, tre
*** 478,484 ****
  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_noreturn_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_noinline_attribute (tree *, tree, tree, int, bool *);
--- 478,483 ----
*************** static tree handle_used_attribute (tree 
*** 492,498 ****
  static tree handle_unused_attribute (tree *, tree, tree, int, bool *);
  static tree handle_externally_visible_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_constructor_attribute (tree *, tree, tree, int, bool *);
--- 491,496 ----
*************** static tree handle_tls_model_attribute (
*** 509,531 ****
  					bool *);
  static tree handle_no_instrument_function_attribute (tree *, tree,
  						     tree, int, bool *);
- static tree handle_malloc_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_novops_attribute (tree *, tree, tree, int, bool *);
  static tree handle_deprecated_attribute (tree *, tree, tree, int,
  					 bool *);
- static tree handle_vector_size_attribute (tree *, tree, tree, int,
- 					  bool *);
- static tree handle_nonnull_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_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_target_attribute (tree *, tree, tree, int, bool *);
  static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
--- 507,520 ----
*************** static tree handle_optimize_attribute (t
*** 533,539 ****
  static void check_function_nonnull (tree, int, tree *);
  static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
  static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
- static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
  static int resort_field_decl_cmp (const void *, const void *);
  
  /* Reserved words.  The third field is a mask: keywords are disabled
--- 522,527 ----
*************** const struct attribute_spec c_common_att
*** 720,734 ****
  			      handle_nocommon_attribute },
    { "common",                 0, 0, true,  false, false,
  			      handle_common_attribute },
-   /* 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,
- 			      handle_noreturn_attribute },
-   { "volatile",               0, 0, true,  false, false,
- 			      handle_noreturn_attribute },
    { "noinline",               0, 0, true,  false, false,
  			      handle_noinline_attribute },
    { "always_inline",          0, 0, true,  false, false,
--- 708,713 ----
*************** const struct attribute_spec c_common_att
*** 745,753 ****
  			      handle_unused_attribute },
    { "externally_visible",     0, 0, true,  false, false,
  			      handle_externally_visible_attribute },
-   /* The same comments as for noreturn attributes apply to const ones.  */
-   { "const",                  0, 0, true,  false, false,
- 			      handle_const_attribute },
    { "transparent_union",      0, 0, false, false, false,
  			      handle_transparent_union_attribute },
    { "constructor",            0, 1, true,  false, false,
--- 724,729 ----
*************** const struct attribute_spec c_common_att
*** 768,808 ****
  			      handle_weakref_attribute },
    { "no_instrument_function", 0, 0, true,  false, false,
  			      handle_no_instrument_function_attribute },
-   { "malloc",                 0, 0, true,  false, false,
- 			      handle_malloc_attribute },
    { "returns_twice",          0, 0, true,  false, false,
  			      handle_returns_twice_attribute },
    { "no_stack_limit",         0, 0, true,  false, false,
  			      handle_no_limit_stack_attribute },
-   { "pure",                   0, 0, true,  false, false,
- 			      handle_pure_attribute },
-   /* 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,
- 			      handle_novops_attribute },
    { "deprecated",             0, 1, false, false, false,
  			      handle_deprecated_attribute },
-   { "vector_size",	      1, 1, false, true, false,
- 			      handle_vector_size_attribute },
    { "visibility",	      1, 1, false, false, false,
  			      handle_visibility_attribute },
    { "tls_model",	      1, 1, true,  false, false,
  			      handle_tls_model_attribute },
-   { "nonnull",                0, -1, false, true, true,
- 			      handle_nonnull_attribute },
-   { "nothrow",                0, 0, true,  false, false,
- 			      handle_nothrow_attribute },
    { "may_alias",	      0, 0, false, true, false, NULL },
    { "cleanup",		      1, 1, true, false, false,
  			      handle_cleanup_attribute },
    { "warn_unused_result",     0, 0, false, true, true,
  			      handle_warn_unused_result_attribute },
-   { "sentinel",               0, 1, false, true, true,
- 			      handle_sentinel_attribute },
-   /* 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,
- 			      handle_type_generic_attribute },
    { "alloc_size",	      1, 2, false, true, true,
  			      handle_alloc_size_attribute },
    { "cold",                   0, 0, true,  false, false,
--- 744,764 ----
*************** handle_common_attribute (tree *node, tre
*** 5812,5844 ****
    return NULL_TREE;
  }
  
- /* Handle a "noreturn" attribute; arguments as in
-    struct attribute_spec.handler.  */
- 
- static 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)
-     TREE_THIS_VOLATILE (*node) = 1;
-   else if (TREE_CODE (type) == POINTER_TYPE
- 	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
-     TREE_TYPE (*node)
-       = build_pointer_type
- 	(build_type_variant (TREE_TYPE (type),
- 			     TYPE_READONLY (TREE_TYPE (type)), 1));
-   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.  */
  
--- 5768,5773 ----
*************** handle_externally_visible_attribute (tre
*** 6110,6142 ****
    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 ARG_UNUSED (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_pointer_type
- 	(build_type_variant (TREE_TYPE (type), 1,
- 			     TREE_THIS_VOLATILE (TREE_TYPE (type))));
-   else
-     {
-       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.  */
  
--- 6039,6044 ----
*************** handle_no_instrument_function_attribute 
*** 6975,6999 ****
    return NULL_TREE;
  }
  
- /* Handle a "malloc" attribute; arguments as in
-    struct attribute_spec.handler.  */
- 
- static tree
- handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
- 			 int ARG_UNUSED (flags), bool *no_add_attrs)
- {
-   if (TREE_CODE (*node) == FUNCTION_DECL
-       && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
-     DECL_IS_MALLOC (*node) = 1;
-   else
-     {
-       warning (OPT_Wattributes, "%qE attribute ignored", name);
-       *no_add_attrs = true;
-     }
- 
-   return NULL_TREE;
- }
- 
  /* Handle a "alloc_size" attribute; arguments as in
     struct attribute_spec.handler.  */
  
--- 6877,6882 ----
*************** handle_no_limit_stack_attribute (tree *n
*** 7065,7102 ****
    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)
-     DECL_PURE_P (*node) = 1;
-   /* ??? TODO: Support types.  */
-   else
-     {
-       warning (OPT_Wattributes, "%qE attribute ignored", name);
-       *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.  */
  
--- 6948,6953 ----
*************** handle_deprecated_attribute (tree *node,
*** 7161,7319 ****
    return NULL_TREE;
  }
  
- /* 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)
- {
-   unsigned HOST_WIDE_INT vecsize, nunits;
-   enum machine_mode orig_mode;
-   tree type = *node, new_type, size;
- 
-   *no_add_attrs = true;
- 
-   size = TREE_VALUE (args);
- 
-   if (!host_integerp (size, 1))
-     {
-       warning (OPT_Wattributes, "%qE attribute ignored", name);
-       return NULL_TREE;
-     }
- 
-   /* Get the vector size (in bytes).  */
-   vecsize = tree_low_cst (size, 1);
- 
-   /* 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);
- 
-   /* Get the mode of the type being modified.  */
-   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))
-       || !host_integerp (TYPE_SIZE_UNIT (type), 1)
-       || TREE_CODE (type) == BOOLEAN_TYPE)
-     {
-       error ("invalid vector type for attribute %qE", name);
-       return NULL_TREE;
-     }
- 
-   if (vecsize % tree_low_cst (TYPE_SIZE_UNIT (type), 1))
-     {
-       error ("vector size not an integral multiple of component size");
-       return NULL;
-     }
- 
-   if (vecsize == 0)
-     {
-       error ("zero vector size");
-       return NULL;
-     }
- 
-   /* Calculate how many units fit in the vector.  */
-   nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1);
-   if (nunits & (nunits - 1))
-     {
-       error ("number of components of the vector not a power of two");
-       return 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 ARG_UNUSED (name),
- 			  tree args, int ARG_UNUSED (flags),
- 			  bool *no_add_attrs)
- {
-   tree type = *node;
-   unsigned HOST_WIDE_INT attr_arg_num;
- 
-   /* 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.  */
-   if (!args)
-     {
-       if (!TYPE_ARG_TYPES (type))
- 	{
- 	  error ("nonnull attribute without arguments on a non-prototype");
- 	  *no_add_attrs = true;
- 	}
-       return NULL_TREE;
-     }
- 
-   /* Argument list specified.  Verify that each argument number references
-      a pointer argument.  */
-   for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
-     {
-       tree argument;
-       unsigned HOST_WIDE_INT arg_num = 0, ck_num;
- 
-       if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
- 	{
- 	  error ("nonnull argument has invalid operand number (argument %lu)",
- 		 (unsigned long) attr_arg_num);
- 	  *no_add_attrs = true;
- 	  return NULL_TREE;
- 	}
- 
-       argument = TYPE_ARG_TYPES (type);
-       if (argument)
- 	{
- 	  for (ck_num = 1; ; ck_num++)
- 	    {
- 	      if (!argument || ck_num == arg_num)
- 		break;
- 	      argument = TREE_CHAIN (argument);
- 	    }
- 
- 	  if (!argument
- 	      || TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
- 	    {
- 	      error ("nonnull argument with out-of-range operand number (argument %lu, operand %lu)",
- 		     (unsigned long) attr_arg_num, (unsigned long) arg_num);
- 	      *no_add_attrs = true;
- 	      return NULL_TREE;
- 	    }
- 
- 	  if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
- 	    {
- 	      error ("nonnull argument references non-pointer operand (argument %lu, operand %lu)",
- 		   (unsigned long) attr_arg_num, (unsigned long) arg_num);
- 	      *no_add_attrs = true;
- 	      return NULL_TREE;
- 	    }
- 	}
-     }
- 
-   return NULL_TREE;
- }
- 
  /* Check the argument list of a function call for null in argument slots
     that are marked as requiring a non-null pointer argument.  The NARGS
     arguments are passed in the array ARGARRAY.
--- 7012,7017 ----
*************** check_nonnull_arg (void * ARG_UNUSED (ct
*** 7438,7477 ****
  	     "(argument %lu)", (unsigned long) param_num);
  }
  
- /* Helper for nonnull attribute handling; fetch the operand number
-    from the attribute argument list.  */
- 
- static bool
- get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
- {
-   /* Verify the arg number is a constant.  */
-   if (TREE_CODE (arg_num_expr) != INTEGER_CST
-       || TREE_INT_CST_HIGH (arg_num_expr) != 0)
-     return false;
- 
-   *valp = TREE_INT_CST_LOW (arg_num_expr);
-   return true;
- }
- 
- /* 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.  */
  
--- 7136,7141 ----
*************** handle_warn_unused_result_attribute (tre
*** 7534,7612 ****
    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)
- {
-   tree params = TYPE_ARG_TYPES (*node);
- 
-   if (!params)
-     {
-       warning (OPT_Wattributes,
- 	       "%qE attribute requires prototypes with named arguments", name);
-       *no_add_attrs = true;
-     }
-   else
-     {
-       while (TREE_CHAIN (params))
- 	params = TREE_CHAIN (params);
- 
-       if (VOID_TYPE_P (TREE_VALUE (params)))
- 	{
- 	  warning (OPT_Wattributes,
- 		   "%qE attribute only applies to variadic functions", name);
- 	  *no_add_attrs = true;
- 	}
-     }
- 
-   if (args)
-     {
-       tree position = TREE_VALUE (args);
- 
-       if (TREE_CODE (position) != INTEGER_CST)
- 	{
- 	  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))
- {
-   tree params;
-   
-   /* Ensure we have a function type.  */
-   gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
-   
-   params = TYPE_ARG_TYPES (*node);
-   while (params && ! VOID_TYPE_P (TREE_VALUE (params)))
-     params = TREE_CHAIN (params);
- 
-   /* Ensure we have a variadic function.  */
-   gcc_assert (!params);
- 
-   return NULL_TREE;
- }
- 
  /* Handle a "target" attribute.  */
  
  static tree
--- 7198,7203 ----
Index: Makefile.in
===================================================================
*** Makefile.in	(revision 148540)
--- Makefile.in	(working copy)
*************** FORTRAN_TARGET_OBJS=@fortran_target_objs
*** 1053,1059 ****
  GCC_OBJS = gcc.o opts-common.o gcc-options.o
  
  # Language-specific object files for C and Objective C.
! C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
    c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
    c-ppoutput.o c-cppbuiltin.o \
    c-objc-common.o c-dump.o c-pch.o c-parser.o $(C_TARGET_OBJS) \
--- 1053,1059 ----
  GCC_OBJS = gcc.o opts-common.o gcc-options.o
  
  # Language-specific object files for C and Objective C.
! C_AND_OBJC_OBJS = c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
    c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
    c-ppoutput.o c-cppbuiltin.o \
    c-objc-common.o c-dump.o c-pch.o c-parser.o $(C_TARGET_OBJS) \
*************** OBJS-common = \
*** 1080,1085 ****
--- 1080,1087 ----
  	$(GGC) \
  	alias.o \
  	alloc-pool.o \
+ 	attribs.o \
+ 	attrib-handlers.o \
  	auto-inc-dec.o \
  	bb-reorder.o \
  	bitmap.o \
*************** c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG
*** 1947,1957 ****
  	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
  		-DBASEVER=$(BASEVER_s) $< $(OUTPUT_OPTION)
  
! # A file used by all variants of C and some other languages.
  
  attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
  	$(FLAGS_H) $(TOPLEV_H) output.h $(RTL_H) $(GGC_H) $(TM_P_H) \
  	$(TARGET_H) langhooks.h $(CPPLIB_H)
  
  c-format.o : c-format.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) langhooks.h \
  	$(C_COMMON_H) $(FLAGS_H) $(TOPLEV_H) intl.h $(DIAGNOSTIC_H) alloc-pool.h \
--- 1949,1961 ----
  	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
  		-DBASEVER=$(BASEVER_s) $< $(OUTPUT_OPTION)
  
! # A couple of files used by all variants of C and some other languages.
  
  attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
  	$(FLAGS_H) $(TOPLEV_H) output.h $(RTL_H) $(GGC_H) $(TM_P_H) \
  	$(TARGET_H) langhooks.h $(CPPLIB_H)
+ attrib-handlers.o : attrib-handlers.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ 	$(TM_H) $(TREE_H) langhooks.h toplev.h
  
  c-format.o : c-format.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) langhooks.h \
  	$(C_COMMON_H) $(FLAGS_H) $(TOPLEV_H) intl.h $(DIAGNOSTIC_H) alloc-pool.h \


More information about the Gcc-patches mailing list