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 + . */ + + /* 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 + #include + #include + #include + #include + #include + #include + + /* 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 \