re PR c++/35758 (vector_size attribute lost in function arguments for templates)
authorJakub Jelinek <jakub@redhat.com>
Thu, 24 Apr 2008 16:29:40 +0000 (18:29 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 24 Apr 2008 16:29:40 +0000 (18:29 +0200)
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

12 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/config/rs6000/rs6000.c
gcc/config/spu/spu.c
gcc/cp/ChangeLog
gcc/cp/cp-objcp-common.h
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/langhooks-def.h
gcc/langhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vector14.C [new file with mode: 0644]

index c7b850aa4ac82606810385d8026d1ae1bee90df2..09609f23e4906d55b713a5def178a76c5cd87c75 100644 (file)
@@ -1,3 +1,16 @@
+2008-04-24  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <rguenther@suse.de>
 
        * c-common.h (check_builtin_function_arguments): Declare.
index 36e1c3d34421e0f6342386baa70e5a3fc6643965..d110b32b47078b83e1a36d8beffd93aa194148d0 100644 (file)
@@ -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;
 }
index 6ac9ee159f9741a5f1d0e794ffa108ef108c8798..8811ea53c763603bcacb1f6cc85505bac5b57136 100644 (file)
@@ -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;
 }
index 55868ac2bb9d036a6dd3b66f710c11894500491c..d37f27bc1793c5ee5bc02975cad39d6e3921779a 100644 (file)
@@ -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;
 }
index cb7e4226dce2503a5ab1186c9313e01098a2aa42..9c116c31ef269765c5539d0c6a5f5daa14d48d1f 100644 (file)
@@ -1,3 +1,12 @@
+2008-04-24  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <rguenther@suse.de>
 
        * typeck.c (cp_build_function_call): Call
index a15b6b47a4f5c7d6471ff4d63e53029ed97e35a2..b2b8405fccdb6d74b20ade50903de2b5d7975c05 100644 (file)
@@ -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
index 27212c3c85c616b63db5d94ac8eee42ea89f24f8..8d223bc6f27cfb257a88e911d074f5e8c937e4ff 100644 (file)
@@ -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);
index 078ca99e6f89ef791d821b61590fe4dc78726819..41af32faec406109e8d1d0f0d2dbb8950790d396 100644 (file)
@@ -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
index 30ff3066c8be2148dbc51e718b825d1a458d0205..aae46406515b9bcd7b27214df11e6c8e425dc6fd 100644 (file)
@@ -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 \
 }
 
index b693742f53d1ef40d2c32d2004025d66090723db..6a54b01f060362911358c51923e34942f9e8af37 100644 (file)
@@ -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.  */
index 6dd1a838206db2de1f3370ccf968678eeadb619e..002d24a16ad6b8c154f3649a1d18440472fa844e 100644 (file)
@@ -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  <rguenther@suse.de>
 
        * 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 (file)
index 0000000..93f9e0e
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/35758
+// { dg-do compile }
+
+#define vector __attribute__((vector_size(16)))
+
+template<int N> vector signed int foo (vector float value) {}
+
+template<int> void foo (float) {}
+
+int
+main ()
+{
+  vector float v;
+  float f;
+  foo<1> (v);
+  foo<1> (f);
+}