https://gcc.gnu.org/g:e1d862cbdaa4c3f4c9e16ba4728be03ca7d532de
commit e1d862cbdaa4c3f4c9e16ba4728be03ca7d532de Author: Mikael Morin <mik...@gcc.gnu.org> Date: Mon Mar 10 22:42:35 2025 +0100 Correction régression typebound_generic_6.f03 Diff: --- gcc/alias.cc | 11 ++++++++++- gcc/alias.h | 1 + gcc/fortran/f95-lang.cc | 28 +++++++++++++++++++++++++++ gcc/fortran/trans-types.cc | 48 +++++++++++++++++++++++++++++++++++----------- gcc/fortran/trans.h | 4 +++- 5 files changed, 79 insertions(+), 13 deletions(-) diff --git a/gcc/alias.cc b/gcc/alias.cc index 4f17664c15b3..b249588a9c59 100644 --- a/gcc/alias.cc +++ b/gcc/alias.cc @@ -972,11 +972,20 @@ get_alias_set (tree t) set = lang_hooks.get_alias_set (t); if (set != -1) return set; + else + return get_default_alias_set (t); +} + +alias_set_type +get_default_alias_set (tree t) +{ + alias_set_type set; + /* There are no objects of FUNCTION_TYPE, so there's no point in using up an alias set for them. (There are, of course, pointers and references to functions, but that's different.) */ - else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE) + if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE) set = 0; /* Unless the language specifies otherwise, let vector types alias diff --git a/gcc/alias.h b/gcc/alias.h index 7c2e33eaa73e..6271dcc7089a 100644 --- a/gcc/alias.h +++ b/gcc/alias.h @@ -42,6 +42,7 @@ int compare_base_decls (tree, tree); bool refs_same_for_tbaa_p (tree, tree); bool mems_same_for_tbaa_p (rtx, rtx); bool view_converted_memref_p (tree); +alias_set_type get_default_alias_set (tree); /* This alias set can be used to force a memory to conflict with all other memories, creating a barrier across which no memory reference diff --git a/gcc/fortran/f95-lang.cc b/gcc/fortran/f95-lang.cc index 124d62f45295..c5098a24102a 100644 --- a/gcc/fortran/f95-lang.cc +++ b/gcc/fortran/f95-lang.cc @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-types.h" #include "trans-const.h" #include "attribs.h" +#include "alias.h" /* Language-dependent contents of an identifier. */ @@ -78,6 +79,8 @@ static void gfc_finish (void); static void gfc_be_parse_file (void); static void gfc_init_ts (void); static tree gfc_builtin_function (tree); +static alias_set_type gfc_get_alias_set (tree t); + /* Handle an "omp declare target" attribute; arguments as in struct attribute_spec.handler. */ @@ -134,6 +137,7 @@ gfc_get_sarif_source_language (const char *) #undef LANG_HOOKS_TYPE_FOR_MODE #undef LANG_HOOKS_TYPE_FOR_SIZE #undef LANG_HOOKS_INIT_TS +#undef LANG_HOOKS_GET_ALIAS_SET #undef LANG_HOOKS_OMP_ARRAY_DATA #undef LANG_HOOKS_OMP_ARRAY_SIZE #undef LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR @@ -174,6 +178,7 @@ gfc_get_sarif_source_language (const char *) #define LANG_HOOKS_TYPE_FOR_MODE gfc_type_for_mode #define LANG_HOOKS_TYPE_FOR_SIZE gfc_type_for_size #define LANG_HOOKS_INIT_TS gfc_init_ts +#define LANG_HOOKS_GET_ALIAS_SET gfc_get_alias_set #define LANG_HOOKS_OMP_ARRAY_DATA gfc_omp_array_data #define LANG_HOOKS_OMP_ARRAY_SIZE gfc_omp_array_size #define LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR gfc_omp_is_allocatable_or_ptr @@ -303,6 +308,29 @@ gfc_finish (void) return; } + +static alias_set_type +gfc_get_alias_set (tree t) +{ + if (!TYPE_P (t)) + return -1; + + if (!GFC_CLASS_TYPE_P (t)) + return -1; + + if (!(TYPE_LANG_SPECIFIC (t) && GFC_TYPE_PARENT_CLASS_TYPE (t))) + return -1; + + alias_set_type new_set = get_default_alias_set (t); + TYPE_ALIAS_SET (t) = new_set; + tree parent_wrapper_type = GFC_TYPE_PARENT_CLASS_TYPE (t); + alias_set_type parent_set = get_alias_set (parent_wrapper_type); + + record_alias_subset (parent_set, new_set); + return new_set; +} + + /* These functions and variables deal with binding contours. We only need these functions for the list of PARM_DECLs, but we leave the functions more general; these are a simplified version of the diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index 046239f4dabb..7bdc9902cae8 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -2833,15 +2833,8 @@ cobounds_match_decl (const gfc_symbol *derived) gfc_symbol * -get_class_canonical_type (gfc_symbol *cls) +get_class_canonical_type (gfc_symbol *derived, int rank, int corank) { - gcc_assert (cls->attr.is_class); - - gfc_component * data_comp = cls->components; - - gfc_symbol *derived = data_comp->ts.u.derived; - int rank = data_comp->as ? data_comp->as->rank : 0; - int corank = data_comp->as ? data_comp->as->corank : 0; const char *class_name = gfc_class_name (derived, rank, corank, 0, 0); gfc_namespace *ns = gfc_class_namespace (derived); @@ -2865,12 +2858,12 @@ get_class_canonical_type (gfc_symbol *cls) gfc_array_spec as; gfc_array_spec *pas; - if (data_comp->as) + if (rank != 0 || corank != 0) { memset (&as, 0, sizeof (as)); as.type = AS_DEFERRED; - as.rank = data_comp->as->rank; - as.corank = data_comp->as->corank; + as.rank = rank; + as.corank = corank; pas = &as; } @@ -2885,6 +2878,21 @@ get_class_canonical_type (gfc_symbol *cls) } +gfc_symbol * +get_class_canonical_type (gfc_symbol *cls) +{ + gcc_assert (cls->attr.is_class); + + gfc_component * data_comp = cls->components; + + gfc_symbol *derived = data_comp->ts.u.derived; + int rank = data_comp->as ? data_comp->as->rank : 0; + int corank = data_comp->as ? data_comp->as->corank : 0; + + return get_class_canonical_type (derived, rank, corank); +} + + /* Build a tree node for a derived type. If there are equal derived types, with different local names, these are built at the same time. If an equal derived type has been built @@ -3238,6 +3246,24 @@ gfc_get_derived_type (gfc_symbol * derived, int codimen) gfc_symbol * canonical_sym = get_class_canonical_type (derived); if (canonical_sym != nullptr) TYPE_CANONICAL (typenode) = gfc_get_derived_type (canonical_sym, codimen); + gfc_component * data_comp = derived->components; + gfc_symbol *orig_type = data_comp->ts.u.derived; + if (orig_type->attr.extension) + { + int rank = data_comp->as ? data_comp->as->rank : 0; + int corank = data_comp->as ? data_comp->as->corank : 0; + + gfc_symbol * parent_type = orig_type->components->ts.u.derived; + gfc_symbol * parent_wrapper = get_class_canonical_type (parent_type, + rank, corank); + if (parent_wrapper != nullptr) + { + tree wrapper_decl = gfc_get_derived_type (parent_wrapper, codimen); + if (!TYPE_LANG_SPECIFIC (typenode)) + TYPE_LANG_SPECIFIC (typenode) = ggc_cleared_alloc<struct lang_type> (); + GFC_TYPE_PARENT_CLASS_TYPE (typenode) = wrapper_decl; + } + } } gfc_finish_type (typenode); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 17a882d16dd2..9144acce7342 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -1035,6 +1035,7 @@ struct GTY(()) lang_type { tree nonrestricted_type; tree caf_token; tree caf_offset; + tree parent_class_wrapper_type; }; struct GTY(()) lang_decl { @@ -1113,7 +1114,8 @@ struct GTY(()) lang_decl { (TYPE_LANG_SPECIFIC(node)->dataptr_type) #define GFC_TYPE_ARRAY_BASE_DECL(node, internal) \ (TYPE_LANG_SPECIFIC(node)->base_decl[(internal)]) - +#define GFC_TYPE_PARENT_CLASS_TYPE(node) \ + (TYPE_LANG_SPECIFIC(node)->parent_class_wrapper_type) /* Build an expression with void type. */ #define build1_v(code, arg) \