From 5dc1195440bf20453b2d98bfd3c3bf92a42c759e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 24 Apr 2008 18:29:40 +0200 Subject: [PATCH] re PR c++/35758 (vector_size attribute lost in function arguments for templates) PR c++/35758 * c-common.c (handle_vector_size_attribute): Call lang_hooks.types.reconstruct_complex_type instead of reconstruct_complex_type. * config/rs6000/rs6000.c (rs6000_handle_altivec_attribute): Likewise. * config/spu/spu.c (spu_handle_vector_attribute): Likewise. * langhooks.h (struct lang_hooks_for_types): Add reconstruct_complex_type hook. * langhooks-def.h (LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE): Define. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. * cp-tree.h (cp_reconstruct_complex_type): New prototype. * cp-objcp-common.h (LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE): Define. * decl2.c (is_late_template_attribute): Only make vector_size late tmpl attribute if argument is type or value dependent. (cp_reconstruct_complex_type): New function. * g++.dg/ext/vector14.C: New test. From-SVN: r134639 --- gcc/ChangeLog | 13 ++++++ gcc/c-common.c | 2 +- gcc/config/rs6000/rs6000.c | 2 +- gcc/config/spu/spu.c | 2 +- gcc/cp/ChangeLog | 9 +++++ gcc/cp/cp-objcp-common.h | 2 + gcc/cp/cp-tree.h | 1 + gcc/cp/decl2.c | 63 ++++++++++++++++++++++++++--- gcc/langhooks-def.h | 2 + gcc/langhooks.h | 6 +++ gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/g++.dg/ext/vector14.C | 17 ++++++++ 12 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/vector14.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7b850aa4ac..09609f23e49 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2008-04-24 Jakub Jelinek + + PR c++/35758 + * c-common.c (handle_vector_size_attribute): Call + lang_hooks.types.reconstruct_complex_type instead of + reconstruct_complex_type. + * config/rs6000/rs6000.c (rs6000_handle_altivec_attribute): Likewise. + * config/spu/spu.c (spu_handle_vector_attribute): Likewise. + * langhooks.h (struct lang_hooks_for_types): Add + reconstruct_complex_type hook. + * langhooks-def.h (LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE): Define. + (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it. + 2008-04-24 Richard Guenther * c-common.h (check_builtin_function_arguments): Declare. diff --git a/gcc/c-common.c b/gcc/c-common.c index 36e1c3d3442..d110b32b470 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -6170,7 +6170,7 @@ handle_vector_size_attribute (tree *node, tree name, tree args, new_type = build_vector_type (type, nunits); /* Build back pointers if needed. */ - *node = reconstruct_complex_type (*node, new_type); + *node = lang_hooks.types.reconstruct_complex_type (*node, new_type); return NULL_TREE; } diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6ac9ee159f9..8811ea53c76 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -19822,7 +19822,7 @@ rs6000_handle_altivec_attribute (tree *node, *no_add_attrs = true; /* No need to hang on to the attribute. */ if (result) - *node = reconstruct_complex_type (*node, result); + *node = lang_hooks.types.reconstruct_complex_type (*node, result); return NULL_TREE; } diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 55868ac2bb9..d37f27bc179 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -3022,7 +3022,7 @@ spu_handle_vector_attribute (tree * node, tree name, if (!result) warning (0, "`%s' attribute ignored", IDENTIFIER_POINTER (name)); else - *node = reconstruct_complex_type (*node, result); + *node = lang_hooks.types.reconstruct_complex_type (*node, result); return NULL_TREE; } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cb7e4226dce..9c116c31ef2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2008-04-24 Jakub Jelinek + + PR c++/35758 + * cp-tree.h (cp_reconstruct_complex_type): New prototype. + * cp-objcp-common.h (LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE): Define. + * decl2.c (is_late_template_attribute): Only make vector_size + late tmpl attribute if argument is type or value dependent. + (cp_reconstruct_complex_type): New function. + 2008-04-24 Richard Guenther * typeck.c (cp_build_function_call): Call diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index a15b6b47a4f..b2b8405fccd 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -125,6 +125,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, #define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE #define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type +#undef LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE +#define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE cp_reconstruct_complex_type #undef LANG_HOOKS_TO_TARGET_CHARSET #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset #undef LANG_HOOKS_GIMPLIFY_EXPR diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 27212c3c85c..8d223bc6f27 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4282,6 +4282,7 @@ extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *, tree, bool, tree, tree); extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *, tree); +extern tree cp_reconstruct_complex_type (tree, tree); extern void cplus_decl_attributes (tree *, tree, int); extern void finish_anon_union (tree); extern void cp_write_global_declarations (void); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 078ca99e6f8..41af32faec4 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -991,11 +991,8 @@ is_late_template_attribute (tree attr, tree decl) /* Unknown attribute. */ return false; - /* Attribute vector_size handling wants to dive into the back end array - building code, which breaks during template processing. */ - if (is_attribute_p ("vector_size", name) - /* Attribute weak handling wants to write out assembly right away. */ - || is_attribute_p ("weak", name)) + /* Attribute weak handling wants to write out assembly right away. */ + if (is_attribute_p ("weak", name)) return true; /* If any of the arguments are dependent expressions, we can't evaluate @@ -1120,6 +1117,62 @@ save_template_attributes (tree *attr_p, tree *decl_p) } } +/* Like reconstruct_complex_type, but handle also template trees. */ + +tree +cp_reconstruct_complex_type (tree type, tree bottom) +{ + tree inner, outer; + + if (TREE_CODE (type) == POINTER_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_pointer_type_for_mode (inner, TYPE_MODE (type), + TYPE_REF_CAN_ALIAS_ALL (type)); + } + else if (TREE_CODE (type) == REFERENCE_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_reference_type_for_mode (inner, TYPE_MODE (type), + TYPE_REF_CAN_ALIAS_ALL (type)); + } + else if (TREE_CODE (type) == ARRAY_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_cplus_array_type (inner, TYPE_DOMAIN (type)); + /* Don't call cp_build_qualified_type on ARRAY_TYPEs, the + element type qualification will be handled by the recursive + cp_reconstruct_complex_type call and cp_build_qualified_type + for ARRAY_TYPEs changes the element type. */ + return outer; + } + else if (TREE_CODE (type) == FUNCTION_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_function_type (inner, TYPE_ARG_TYPES (type)); + } + else if (TREE_CODE (type) == METHOD_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + /* The build_method_type_directly() routine prepends 'this' to argument list, + so we must compensate by getting rid of it. */ + outer + = build_method_type_directly + (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))), + inner, + TREE_CHAIN (TYPE_ARG_TYPES (type))); + } + else if (TREE_CODE (type) == OFFSET_TYPE) + { + inner = cp_reconstruct_complex_type (TREE_TYPE (type), bottom); + outer = build_offset_type (TYPE_OFFSET_BASETYPE (type), inner); + } + else + return bottom; + + return cp_build_qualified_type (outer, TYPE_QUALS (type)); +} + /* Like decl_attributes, but handle C++ complexity. */ void diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 30ff3066c8b..aae46406515 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -167,6 +167,7 @@ extern tree lhd_make_node (enum tree_code); lhd_omp_firstprivatize_type_sizes #define LANG_HOOKS_TYPE_HASH_EQ NULL #define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL +#define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type #define LANG_HOOKS_HASH_TYPES true #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \ @@ -182,6 +183,7 @@ extern tree lhd_make_node (enum tree_code); LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \ LANG_HOOKS_TYPE_HASH_EQ, \ LANG_HOOKS_GET_ARRAY_DESCR_INFO, \ + LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \ LANG_HOOKS_HASH_TYPES \ } diff --git a/gcc/langhooks.h b/gcc/langhooks.h index b693742f53d..6a54b01f060 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -130,6 +130,12 @@ struct lang_hooks_for_types for the debugger about the array bounds, strides, etc. */ bool (*get_array_descr_info) (const_tree, struct array_descr_info *); + /* If we requested a pointer to a vector, build up the pointers that + we stripped off while looking for the inner type. Similarly for + return values from functions. The argument TYPE is the top of the + chain, and BOTTOM is the new type which we will point to. */ + tree (*reconstruct_complex_type) (tree, tree); + /* Nonzero if types that are identical are to be hashed so that only one copy is kept. If a language requires unique types for each user-specified type, such as Ada, this should be set to TRUE. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6dd1a838206..002d24a16ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -2,6 +2,9 @@ * gcc.dg/pr36017.c: Run on all targets, remove -lm from dg-options. + PR c++/35758 + * g++.dg/ext/vector14.C: New test. + 2008-04-24 Richard Guenther * gcc.dg/builtin-constant_p-1.c: New testcase. diff --git a/gcc/testsuite/g++.dg/ext/vector14.C b/gcc/testsuite/g++.dg/ext/vector14.C new file mode 100644 index 00000000000..93f9e0e7820 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector14.C @@ -0,0 +1,17 @@ +// PR c++/35758 +// { dg-do compile } + +#define vector __attribute__((vector_size(16))) + +template vector signed int foo (vector float value) {} + +template void foo (float) {} + +int +main () +{ + vector float v; + float f; + foo<1> (v); + foo<1> (f); +} -- 2.30.2