https://gcc.gnu.org/g:27e2ba94e16ab5bf7972e626f5df4e753d305152
commit r17-5490-g27e2ba94e16ab5bf7972e626f5df4e753d305152 Author: Guillaume Gomez <[email protected]> Date: Fri Oct 9 11:00:42 2026 +0200 Merge common attribute handling code between D and c-family gcc/d/ChangeLog: * Make-lang.in: Add compilation of `attr-handlers.c` in D front-end. * d-attribs.cc (handle_leaf_attribute) (handle_const_attribute) (handle_pure_attribute) (handle_novops_attribute) (handle_nothrow_attribute) (handle_type_generic_attribute) (handle_returns_twice_attribute) (handle_fnspec_attribute) (d_handle_noinline_attribute) (d_handle_used_attribute) (d_handle_simd_attribute): Remove the functions provided by `attr-handlers.c`. Diff: --- gcc/d/Make-lang.in | 4 +- gcc/d/d-attribs.cc | 234 +---------------------------------------------------- 2 files changed, 6 insertions(+), 232 deletions(-) diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index 9f91346290cc..f11f809945ec 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -240,10 +240,10 @@ D_ALL_OBJS = $(D_FRONTEND_OBJS) $(D_OBJS) $(D_TARGET_OBJS) d_OBJS = $(D_ALL_OBJS) d/d-spec.o -d21$(exeext): $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS) $(d.prev) +d21$(exeext): $(D_ALL_OBJS) attribs.o attr-handlers.o $(BACKEND) $(LIBDEPS) $(d.prev) @$(call LINK_PROGRESS,$(INDEX.d),start) +$(DLLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -static-libphobos -o $@ \ - $(D_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS) + $(D_ALL_OBJS) attribs.o attr-handlers.o $(BACKEND) $(LIBS) $(BACKENDLIBS) @$(call LINK_PROGRESS,$(INDEX.d),end) # Documentation. diff --git a/gcc/d/d-attribs.cc b/gcc/d/d-attribs.cc index 803f2e05bbd2..fcba75de065a 100644 --- a/gcc/d/d-attribs.cc +++ b/gcc/d/d-attribs.cc @@ -41,27 +41,19 @@ along with GCC; see the file COPYING3. If not see #include "varasm.h" #include "fold-const.h" #include "opts.h" +#include "attr-handlers.h" #include "d-tree.h" /* Internal attribute handlers for built-in functions. */ static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); -static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); -static tree handle_const_attribute (tree *, tree, tree, int, bool *); static tree handle_malloc_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_nothrow_attribute (tree *, tree, tree, int, bool *); -static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *); -static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); -static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *); /* D attribute handlers for user defined attributes. */ -static tree d_handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree d_handle_always_inline_attribute (tree *, tree, tree, int, bool *); static tree d_handle_flatten_attribute (tree *, tree, tree, int, bool *); static tree d_handle_target_attribute (tree *, tree, tree, int, bool *); @@ -78,7 +70,6 @@ static tree d_handle_alloc_size_attribute (tree *, tree, tree, int, bool *); static tree d_handle_cold_attribute (tree *, tree, tree, int, bool *); static tree d_handle_register_attribute (tree *, tree, tree, int, bool *); static tree d_handle_restrict_attribute (tree *, tree, tree, int, bool *); -static tree d_handle_used_attribute (tree *, tree, tree, int, bool *); static tree d_handle_visibility_attribute (tree *, tree, tree, int, bool *); static tree d_handle_no_sanitize_attribute (tree *, tree, tree, int, bool *); static tree d_handle_no_split_stack_attribute (tree *, tree, tree, int, bool *); @@ -89,51 +80,6 @@ static tree d_handle_simd_attribute (tree *, tree, tree, int, bool *); { name, function, type, variable } /* Define attributes that are mutually exclusive with one another. */ -static const struct attribute_spec::exclusions attr_noreturn_exclusions[] = -{ - ATTR_EXCL ("alloc_size", true, true, true), - ATTR_EXCL ("const", true, true, true), - ATTR_EXCL ("malloc", true, true, true), - ATTR_EXCL ("pure", true, true, true), - ATTR_EXCL ("returns_twice", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] = -{ - ATTR_EXCL ("noreturn", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -static const struct attribute_spec::exclusions attr_const_pure_exclusions[] = -{ - ATTR_EXCL ("alloc_size", true, true, true), - ATTR_EXCL ("const", true, true, true), - ATTR_EXCL ("noreturn", true, true, true), - ATTR_EXCL ("pure", true, true, true), - ATTR_EXCL (NULL, false, false, false) -}; - -static const struct attribute_spec::exclusions attr_inline_exclusions[] = -{ - ATTR_EXCL ("noinline", true, true, true), - ATTR_EXCL ("target_clones", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -static const struct attribute_spec::exclusions attr_noinline_exclusions[] = -{ - ATTR_EXCL ("always_inline", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -static const struct attribute_spec::exclusions attr_target_exclusions[] = -{ - ATTR_EXCL ("target_clones", TARGET_HAS_FMV_TARGET_ATTRIBUTE, - TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE), - ATTR_EXCL (NULL, false, false, false), -}; - static const struct attribute_spec::exclusions attr_target_clones_exclusions[] = { ATTR_EXCL ("always_inline", true, true, true), @@ -142,21 +88,6 @@ static const struct attribute_spec::exclusions attr_target_clones_exclusions[] = ATTR_EXCL (NULL, false, false, false), }; -static const struct attribute_spec::exclusions attr_alloc_exclusions[] = -{ - ATTR_EXCL ("const", true, true, true), - ATTR_EXCL ("noreturn", true, true, true), - ATTR_EXCL ("pure", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] = -{ - ATTR_EXCL ("cold", true, true, true), - ATTR_EXCL ("hot", true, true, true), - ATTR_EXCL (NULL, false, false, false) -}; - /* Helper to define an attribute. */ #define ATTR_SPEC(name, min_len, max_len, decl_req, type_req, fn_type_req, \ affects_type_identity, handler, exclude) \ @@ -204,9 +135,9 @@ const scoped_attribute_specs d_langhook_common_attribute_table = static const attribute_spec d_langhook_gnu_attributes[] = { ATTR_SPEC ("noinline", 0, 0, true, false, false, false, - d_handle_noinline_attribute, attr_noinline_exclusions), + handle_noinline_attribute, attr_noinline_exclusions), ATTR_SPEC ("always_inline", 0, 0, true, false, false, false, - d_handle_always_inline_attribute, attr_inline_exclusions), + d_handle_always_inline_attribute, attr_always_inline_exclusions), ATTR_SPEC ("flatten", 0, 0, true, false, false, false, d_handle_flatten_attribute, NULL), ATTR_SPEC ("target", 1, -1, true, false, false, false, @@ -244,7 +175,7 @@ static const attribute_spec d_langhook_gnu_attributes[] = ATTR_SPEC ("simd", 0, 1, true, false, false, false, d_handle_simd_attribute, NULL), ATTR_SPEC ("used", 0, 0, true, false, false, false, - d_handle_used_attribute, NULL), + handle_used_attribute, NULL), ATTR_SPEC ("visibility", 1, 1, false, false, false, false, d_handle_visibility_attribute, NULL), }; @@ -475,48 +406,6 @@ handle_noreturn_attribute (tree *node, tree, tree, int, bool *) return NULL_TREE; } -/* Handle a "leaf" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_leaf_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) -{ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - if (!TREE_PUBLIC (*node)) - { - warning (OPT_Wattributes, "%qE attribute has no effect", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "const" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_const_attribute (tree *node, tree, tree, int, bool *) -{ - tree type = TREE_TYPE (*node); - - 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 - gcc_unreachable (); - - return NULL_TREE; -} - /* Handle a "malloc" attribute; arguments as in struct attribute_spec.handler. */ @@ -529,28 +418,6 @@ handle_malloc_attribute (tree *node, tree, tree, int, bool *) return NULL_TREE; } -/* Handle a "pure" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_pure_attribute (tree *node, tree, tree, int, bool *) -{ - gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); - DECL_PURE_P (*node) = 1; - return NULL_TREE; -} - -/* Handle a "no vops" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_novops_attribute (tree *node, tree, tree, int, bool *) -{ - 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. */ @@ -614,32 +481,6 @@ handle_nonnull_attribute (tree *node, tree, tree args, int, bool *) return NULL_TREE; } -/* Handle a "nothrow" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_nothrow_attribute (tree *node, tree, tree, int, bool *) -{ - gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); - TREE_NOTHROW (*node) = 1; - return NULL_TREE; -} - -/* Handle a "type generic" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_type_generic_attribute (tree *node, tree, tree, int, bool *) -{ - /* Ensure we have a function type. */ - gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); - - /* Ensure we have a variadic function. */ - gcc_assert (!prototype_p (*node) || stdarg_p (*node)); - - return NULL_TREE; -} - /* Handle a "transaction_pure" attribute; arguments as in struct attribute_spec.handler. */ @@ -652,31 +493,6 @@ handle_transaction_pure_attribute (tree *node, tree, tree, int, bool *) return NULL_TREE; } -/* Handle a "returns_twice" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_returns_twice_attribute (tree *node, tree, tree, int, bool *) -{ - gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); - - DECL_IS_RETURNS_TWICE (*node) = 1; - - return NULL_TREE; -} - -/* Handle a "fn spec" attribute; arguments as in - struct attribute_spec.handler. */ - -tree -handle_fnspec_attribute (tree *, tree, tree args, int, bool *) -{ - gcc_assert (args - && TREE_CODE (TREE_VALUE (args)) == STRING_CST - && !TREE_CHAIN (args)); - return NULL_TREE; -} - /* Handle an "omp declare simd" attribute; arguments as in struct attribute_spec.handler. */ @@ -691,24 +507,6 @@ handle_omp_declare_simd_attribute (tree *node, tree, tree, int, bool *) These functions take the arguments: (tree *node, tree name, tree args, int flags, bool *no_add_attrs) */ -/* Handle a "noinline" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -d_handle_noinline_attribute (tree *node, tree name, tree, int, - bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - DECL_UNINLINABLE (*node) = 1; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - /* Handle a "always_inline" attribute; arguments as in struct attribute_spec.handler. */ @@ -1574,30 +1372,6 @@ d_handle_simd_attribute (tree *node, tree name, tree args, int, return NULL_TREE; } -/* Handle a "used" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -d_handle_used_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - || (VAR_P (*node) && TREE_STATIC (*node)) - || (TREE_CODE (*node) == TYPE_DECL)) - { - TREE_USED (*node) = 1; - DECL_PRESERVE_P (*node) = 1; - if (VAR_P (*node)) - DECL_READ_P (*node) = 1; - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - /* Handle an "visibility" attribute; arguments as in struct attribute_spec.handler. */
