From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14782 invoked by alias); 8 Apr 2008 10:12:20 -0000 Received: (qmail 14764 invoked by uid 22791); 8 Apr 2008 10:12:15 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 08 Apr 2008 10:11:42 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m38A9c7k024088; Tue, 8 Apr 2008 06:09:38 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [10.10.36.72]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m38A9bcL002733; Tue, 8 Apr 2008 06:09:37 -0400 Received: from devserv.devel.redhat.com (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id m38A9bRm018161; Tue, 8 Apr 2008 06:09:37 -0400 Received: (from jakub@localhost) by devserv.devel.redhat.com (8.12.11.20060308/8.12.11/Submit) id m38A9bSV018159; Tue, 8 Apr 2008 06:09:37 -0400 Date: Tue, 08 Apr 2008 10:18:00 -0000 From: Jakub Jelinek To: Jason Merrill Cc: Mark Mitchell , gcc-patches@gcc.gnu.org Subject: Re: [C++ PATCH] Fix vector_size handling in templates (PR c++/35758) Message-ID: <20080408100937.GG20478@devserv.devel.redhat.com> Reply-To: Jakub Jelinek References: <20080401143240.GR30807@devserv.devel.redhat.com> <47FA5AA6.7010802@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <47FA5AA6.7010802@redhat.com> User-Agent: Mutt/1.4.1i X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2008-04/txt/msg00632.txt.bz2 On Mon, Apr 07, 2008 at 01:32:22PM -0400, Jason Merrill wrote: > I believe this patch is appropriate and correct and fixes the > regression, regardless of whether we also try to implement deduction for > 'vector T'. If reconstruct_complex_type doesn't do the right thing for > C++, this is the way to fix it. Here is an updated patch, which also changes rs6000 and spu reconstruct_complex_type calls to lang_hoos.types.reconstruct_complex_type (__altivec__ and __spu_vector__ attributes aren't late and I don't think the C++ FE should hardcode their names, so they have the same issues as vector_size before it was changed into an unconditionally late attribute). I believe this patch fixes the regression part of these problems, as gcc 4.2.x and earlier weren't allowing these attributes on type dependent decls. So ok for trunk/4.3? That said, even when not regression I think the remaining issues are serious wrong-code issues and so should be fixed even on 4.3. If the needed calls of apply_late_template_attributes for TYPE_ATTRIBUTES are added where needed in tsubst* (not sure exactly where, unfortunately), then a patch like http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35758#c15 could fix the non-deduction cases (e.g. when using explicit template args etc.), both for vector_size attribute, but also for the target specific altivec/spu_vector. The deduction for vector_size is perhaps possible, it is just a matter of checking that the template parameter has vector_size attribute and if it does, see whether the matching type is VECTOR_TYPE and deduce its TREE_TYPE. But altivec/spu_vector attributes will be much harder or impossible to deduce, given that they seem to throw away the original type and only use TYPE_MODE to find out what vector type to use. Furthermore, I wonder why e.g. the altivec attribute only uses the first letter of the attribute argument, so even __attribute((altivec (bar))) will be handled as __attribute((altivec (bool__))). 2008-04-08 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. * 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. --- gcc/c-common.c.jj 2008-03-31 23:54:50.000000000 +0200 +++ gcc/c-common.c 2008-04-08 11:37:36.000000000 +0200 @@ -6104,7 +6104,7 @@ handle_vector_size_attribute (tree *node 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; } --- gcc/config/rs6000/rs6000.c.jj 2008-04-08 11:27:37.000000000 +0200 +++ gcc/config/rs6000/rs6000.c 2008-04-08 11:45:55.000000000 +0200 @@ -19743,7 +19743,7 @@ rs6000_handle_altivec_attribute (tree *n *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; } --- gcc/config/spu/spu.c.jj 2008-04-08 11:46:09.000000000 +0200 +++ gcc/config/spu/spu.c 2008-04-08 11:47:13.000000000 +0200 @@ -3022,7 +3022,7 @@ spu_handle_vector_attribute (tree * node 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; } --- gcc/langhooks.h.jj 2008-04-07 10:42:57.000000000 +0200 +++ gcc/langhooks.h 2008-04-08 11:37:36.000000000 +0200 @@ -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. */ --- gcc/langhooks-def.h.jj 2008-04-07 10:42:57.000000000 +0200 +++ gcc/langhooks-def.h 2008-04-08 11:37:36.000000000 +0200 @@ -167,6 +167,7 @@ extern tree lhd_make_node (enum tree_cod 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_cod 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 \ } --- gcc/cp/cp-tree.h.jj 2008-04-07 10:42:55.000000000 +0200 +++ gcc/cp/cp-tree.h 2008-04-08 11:37:36.000000000 +0200 @@ -4282,6 +4282,7 @@ extern tree grokfield (const cp_declarat 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); --- gcc/cp/cp-objcp-common.h.jj 2008-04-07 10:42:55.000000000 +0200 +++ gcc/cp/cp-objcp-common.h 2008-04-08 11:37:36.000000000 +0200 @@ -125,6 +125,8 @@ extern tree objcp_tsubst_copy_and_build #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 --- gcc/cp/decl2.c.jj 2008-03-25 23:31:25.000000000 +0100 +++ gcc/cp/decl2.c 2008-04-08 11:37:36.000000000 +0200 @@ -991,11 +991,8 @@ is_late_template_attribute (tree attr, t /* 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, } } +/* 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 --- gcc/testsuite/g++.dg/ext/vector14.C.jj 2008-04-08 11:37:36.000000000 +0200 +++ gcc/testsuite/g++.dg/ext/vector14.C 2008-04-08 11:37:36.000000000 +0200 @@ -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); +} Jakub