[PATCH/RFC] Subscripting on vector types

Andrew Pinski Andrew_Pinski@playstation.sony.com
Fri Oct 2 21:08:00 GMT 2009


PING.

On Mon, Jul 13, 2009 at 2:54 PM, Andrew Pinski
<Andrew_Pinski@playstation.sony.com> wrote:
> On Fri, Jun 19, 2009 at 6:16 AM, Julian Brown<julian@codesourcery.com> wrote:
>> On Wed, 14 May 2008 17:17:29 -0700
>> Andrew_Pinski@PlayStation.Sony.Com wrote:
>>
>>> This patch adds the subscripting for vector types.  I did not modify
>>> GCC's documentation for the vector extension because I am going to do
>>> a rewrite of that section because it seems weak and needs some help.
>>>
>>> Trevor wrote the initialize part of the patch, I cleaned it up and
>>> fixed a couple of issues related to addressing and templates and
>>> added the testcases (11 in total).
>>
>> What's the status of this patch? (I'm considering doing some work in
>> this area soon.)
>
> Here is patch with the documentation, I did not change it that major,
> just added a sentence documenting what subscripting on an vector type
> means.
>
> OK? Bootstrapped and tested on i686-linux-gnu.
>
> ChangeLog:
> * c-typeck.c (mark_addressable_vector): New function.
> (build_array_ref): Allow subscripting of vector types.
> * doc/extend.texi (Vector Extensions): Document subscripting on vector types.
>
> cp/ChangeLog:
>
> * typeck.c (mark_addressable_vector): New function.
> (build_array_ref): Allow vector[index].
> * decl2.c (mark_addressable_vector): New function.
> (grok_array_decl): Allow subscripting of vector types.
>
>
> testsuite/ChangeLog:
>
> * gcc.c-torture/execute/vector-subscript-2.c: New test.
> * gcc.c-torture/execute/vector-subscript-1.c: New test.
> * gcc.dg/vector-subscript-2.c: New test.
> * gcc.dg/vector-subscript-1.c: New test.
> * g++.dg/ext/vector-subscript-0.C: New test.
> * g++.dg/ext/vector-subscript-1.C: New test.
> * g++.dg/ext/vector-subscript-2.C: New test.
> * g++.dg/torture/vector-subscript-1.C: New test.
> * g++.dg/torture/vector-subscript-2.C: New test.
> * g++.dg/torture/vector-subscript-3.C: New test.
> * g++.dg/torture/vector-subscript-4.C: New test.
>
> * gcc.dg/array-8.c: Update error message about subscripting.
-------------- next part --------------
Index: doc/extend.texi
===================================================================
--- doc/extend.texi	(revision 149591)
+++ doc/extend.texi	(working copy)
@@ -5906,6 +5906,9 @@ minus or complement operators on a vecto
 elements are the negative or complemented values of the corresponding
 elements in the operand.
 
+Vectors can be subscripted as if the vector were an array with the same number
+of elements and base type. Out of bound accesses are undefined.  
+
 You can declare variables and use them in function calls and returns, as
 well as in assignments and some casts.  You can specify a vector type as
 a return type for a function.  Vector types can also be used as function
Index: testsuite/gcc.c-torture/execute/vector-subscript-2.c
===================================================================
--- testsuite/gcc.c-torture/execute/vector-subscript-2.c	(revision 0)
+++ testsuite/gcc.c-torture/execute/vector-subscript-2.c	(revision 0)
@@ -0,0 +1,66 @@
+#define vector __attribute__((vector_size(sizeof(int)*4) ))
+
+/* Check to make sure that we extract and insert the vector at the same
+   location for vector subscripting (with constant indexes) and
+   that vectors layout are the same as arrays. */
+
+struct TV4
+{
+    vector int v;
+};
+
+typedef struct TV4 MYV4;
+
+static inline MYV4 myfunc2( int x, int y, int z, int w )
+{
+    MYV4 temp;
+    temp.v[0] = x;
+    temp.v[1] = y;
+    temp.v[2] = z;
+    temp.v[3] = w;
+    return temp;
+}
+MYV4 val3;
+__attribute__((noinline)) void modify (void) 
+{
+    val3 = myfunc2( 1, 2, 3, 4 );
+}
+int main( int argc, char* argv[] )
+{
+  int a[4];
+  int i;
+  
+  /* Set up the vector.  */
+  modify();
+  
+  /* Check the vector via the global variable.  */
+  if (val3.v[0] != 1)
+    __builtin_abort ();
+  if (val3.v[1] != 2)
+    __builtin_abort ();
+  if (val3.v[2] != 3)
+    __builtin_abort ();
+  if (val3.v[3] != 4)
+    __builtin_abort ();
+    
+  vector int a1 = val3.v;
+  
+   /* Check the vector via a local variable.  */
+  if (a1[0] != 1)
+    __builtin_abort ();
+  if (a1[1] != 2)
+    __builtin_abort ();
+  if (a1[2] != 3)
+    __builtin_abort ();
+  if (a1[3] != 4)
+    __builtin_abort ();
+    
+  __builtin_memcpy(a, &val3, sizeof(a));  
+   /* Check the vector via copying it to an array.  */
+  for(i = 0; i < 4; i++)
+    if (a[i] != i+1)
+      __builtin_abort ();
+  
+  
+  return 0;
+}
Index: testsuite/gcc.c-torture/execute/vector-subscript-1.c
===================================================================
--- testsuite/gcc.c-torture/execute/vector-subscript-1.c	(revision 0)
+++ testsuite/gcc.c-torture/execute/vector-subscript-1.c	(revision 0)
@@ -0,0 +1,58 @@
+#define vector __attribute__((vector_size(sizeof(int)*4) ))
+
+/* Check to make sure that we extract and insert the vector at the same
+   location for vector subscripting and that vectors layout are the same
+   as arrays. */
+
+struct TV4
+{
+    vector int v;
+};
+
+typedef struct TV4 MYV4;
+static inline int *f(MYV4 *a, int i)
+{
+  return &(a->v[i]);
+}
+
+static inline MYV4 myfunc2( int x, int y, int z, int w )
+{
+    MYV4 temp;
+    *f(&temp, 0 ) = x;
+    *f(&temp, 1 ) = y;
+    *f(&temp, 2 ) = z;
+    *f(&temp, 3 ) = w;
+    return temp;
+}
+
+MYV4 val3;
+
+__attribute__((noinline)) void modify (void) 
+{
+    val3 = myfunc2( 1, 2, 3, 4 );
+}
+
+int main( int argc, char* argv[] )
+{
+  int a[4];
+  int i;
+  
+  modify();
+  
+  if (*f(&val3, 0 ) != 1)
+    __builtin_abort ();
+  if (*f(&val3, 1 ) != 2)
+    __builtin_abort ();
+  if (*f(&val3, 2 ) != 3)
+    __builtin_abort ();
+  if (*f(&val3, 3 ) != 4)
+    __builtin_abort ();
+    
+  __builtin_memcpy(a, &val3, 16);
+  for(i = 0; i < 4; i++)
+    if (a[i] != i+1)
+      __builtin_abort ();
+  
+  
+  return 0;
+}
Index: testsuite/gcc.dg/array-8.c
===================================================================
--- testsuite/gcc.dg/array-8.c	(revision 149591)
+++ testsuite/gcc.dg/array-8.c	(working copy)
@@ -35,7 +35,7 @@ g (void)
   f().c[0];
   0[f().c];
   /* Various invalid cases.  */
-  c[c]; /* { dg-error "subscripted value is neither array nor pointer" } */
+  c[c]; /* { dg-error "subscripted value is not an array, a pointer, or a vector" } */
   p[1.0]; /* { dg-error "array subscript is not an integer" } */
   1.0[a]; /* { dg-error "array subscript is not an integer" } */
   fp[0]; /* { dg-error "subscripted value is pointer to function" } */
Index: testsuite/gcc.dg/vector-subscript-1.c
===================================================================
--- testsuite/gcc.dg/vector-subscript-1.c	(revision 0)
+++ testsuite/gcc.dg/vector-subscript-1.c	(revision 0)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+
+#define vector __attribute__((vector_size(16) ))
+/* Check that vector[index] works and index[vector] is rejected.  */
+
+float vf(vector float a)
+{
+  return 0[a]; /* { dg-error "" } */
+}
+
+
+float fv(vector float a)
+{
+  return a[0];
+}
Index: testsuite/gcc.dg/vector-subscript-2.c
===================================================================
--- testsuite/gcc.dg/vector-subscript-2.c	(revision 0)
+++ testsuite/gcc.dg/vector-subscript-2.c	(revision 0)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-W -Wall" } */
+
+/* Check that subscripting of vectors work with register storage class decls.  */
+
+#define vector __attribute__((vector_size(16) ))
+
+
+float vf(void)
+{
+  register vector float a;
+  return a[0]; /* { dg-bogus "register" } */
+}
+
Index: testsuite/g++.dg/ext/vector-subscript-0.C
===================================================================
--- testsuite/g++.dg/ext/vector-subscript-0.C	(revision 0)
+++ testsuite/g++.dg/ext/vector-subscript-0.C	(revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+// { dg-options "-w" }
+
+#define vector __attribute__((vector_size(16) ))
+
+template<int i>
+static inline int f(vector int a)
+{
+  return (a[i]);
+}
+int myfunc2( int x, int y, int z, int w )
+{
+    vector int temp = (vector int){x, y, z, w};
+    return f<0>(temp);
+}
Index: testsuite/g++.dg/ext/vector-subscript-1.C
===================================================================
--- testsuite/g++.dg/ext/vector-subscript-1.C	(revision 0)
+++ testsuite/g++.dg/ext/vector-subscript-1.C	(revision 0)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+
+#define vector __attribute__((vector_size(16) ))
+/* Check that vector[index] works and index[vector] is rejected.  */
+
+float vf(vector float a)
+{
+  return 0[a]; /* { dg-error "" } */
+}
+
+
+float fv(vector float a)
+{
+  return a[0];
+}
Index: testsuite/g++.dg/ext/vector-subscript-2.C
===================================================================
--- testsuite/g++.dg/ext/vector-subscript-2.C	(revision 0)
+++ testsuite/g++.dg/ext/vector-subscript-2.C	(revision 0)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-W -Wall" } */
+
+/* Check that subscripting of vectors work with register storage class decls.  */
+
+#define vector __attribute__((vector_size(16) ))
+
+
+float vf(void)
+{
+  register vector float a;
+  return a[0]; /* { dg-bogus "register" } */
+}
+
Index: testsuite/g++.dg/torture/vector-subscript-1.C
===================================================================
--- testsuite/g++.dg/torture/vector-subscript-1.C	(revision 0)
+++ testsuite/g++.dg/torture/vector-subscript-1.C	(revision 0)
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-options "-w" } */
+#define vector __attribute__((vector_size(sizeof(int)*4) ))
+
+/* Check to make sure that we extract and insert the vector at the same
+   location for vector subscripting and that vectors layout are the same
+   as arrays. */
+
+struct TV4
+{
+    vector int v;
+};
+
+typedef struct TV4 MYV4;
+static inline int *f(MYV4 *a, int i)
+{
+  return &(a->v[i]);
+}
+
+static inline MYV4 myfunc2( int x, int y, int z, int w )
+{
+    MYV4 temp;
+    *f(&temp, 0 ) = x;
+    *f(&temp, 1 ) = y;
+    *f(&temp, 2 ) = z;
+    *f(&temp, 3 ) = w;
+    return temp;
+}
+
+MYV4 val3;
+
+__attribute__((noinline)) void modify (void) 
+{
+    val3 = myfunc2( 1, 2, 3, 4 );
+}
+
+int main( int argc, char* argv[] )
+{
+  int a[4];
+  int i;
+  
+  modify();
+  
+  if (*f(&val3, 0 ) != 1)
+    __builtin_abort ();
+  if (*f(&val3, 1 ) != 2)
+    __builtin_abort ();
+  if (*f(&val3, 2 ) != 3)
+    __builtin_abort ();
+  if (*f(&val3, 3 ) != 4)
+    __builtin_abort ();
+    
+  __builtin_memcpy(a, &val3, 16);
+  for(i = 0; i < 4; i++)
+    if (a[i] != i+1)
+      __builtin_abort ();
+  
+  
+  return 0;
+}
Index: testsuite/g++.dg/torture/vector-subscript-3.C
===================================================================
--- testsuite/g++.dg/torture/vector-subscript-3.C	(revision 0)
+++ testsuite/g++.dg/torture/vector-subscript-3.C	(revision 0)
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-options "-w" } */
+#define vector __attribute__((vector_size(sizeof(int)*4) ))
+
+/* Check to make sure that we extract and insert the vector at the same
+   location for vector subscripting and that vectors layout are the same
+   as arrays. */
+
+struct TV4
+{
+    vector int v;
+};
+
+typedef struct TV4 MYV4;
+template<int i>
+static inline int *f(MYV4 *a)
+{
+  return &(a->v[i]);
+}
+static inline MYV4 myfunc2( int x, int y, int z, int w )
+{
+    MYV4 temp;
+    *f<0>(&temp) = x;
+    *f<1>(&temp) = y;
+    *f<2>(&temp) = z;
+    *f<3>(&temp) = w;
+    return temp;
+}
+
+MYV4 val3;
+
+__attribute__((noinline)) void modify (void) 
+{
+    val3 = myfunc2( 1, 2, 3, 4 );
+}
+
+int main( int argc, char* argv[] )
+{
+  int a[4];
+  int i;
+  
+  modify();
+  
+  if (*f<0>(&val3) != 1)
+    __builtin_abort ();
+  if (*f<1>(&val3) != 2)
+    __builtin_abort ();
+  if (*f<2>(&val3) != 3)
+    __builtin_abort ();
+  if (*f<3>(&val3) != 4)
+    __builtin_abort ();
+    
+  __builtin_memcpy(a, &val3, 16);
+  for(i = 0; i < 4; i++)
+    if (a[i] != i+1)
+      __builtin_abort ();
+  
+  
+  return 0;
+}
Index: testsuite/g++.dg/torture/vector-subscript-2.C
===================================================================
--- testsuite/g++.dg/torture/vector-subscript-2.C	(revision 0)
+++ testsuite/g++.dg/torture/vector-subscript-2.C	(revision 0)
@@ -0,0 +1,67 @@
+/* { dg-do run } */
+/* { dg-options "-w" } */
+#define vector __attribute__((vector_size(sizeof(int)*4) ))
+
+/* Check to make sure that we extract and insert the vector at the same
+   location for vector subscripting (with constant indexes) and
+   that vectors layout are the same as arrays. */
+
+struct TV4
+{
+    vector int v;
+};
+typedef TV4 MYV4;
+
+static inline MYV4 myfunc2( int x, int y, int z, int w )
+{
+    MYV4 temp;
+    temp.v[0] = x;
+    temp.v[1] = y;
+    temp.v[2] = z;
+    temp.v[3] = w;
+    return temp;
+}
+MYV4 val3;
+__attribute__((noinline)) void modify (void) 
+{
+    val3 = myfunc2( 1, 2, 3, 4 );
+}
+int main( int argc, char* argv[] )
+{
+  int a[4];
+  int i;
+  
+  /* Set up the vector.  */
+  modify();
+  
+  /* Check the vector via the global variable.  */
+  if (val3.v[0] != 1)
+    __builtin_abort ();
+  if (val3.v[1] != 2)
+    __builtin_abort ();
+  if (val3.v[2] != 3)
+    __builtin_abort ();
+  if (val3.v[3] != 4)
+    __builtin_abort ();
+    
+  vector int a1 = val3.v;
+  
+   /* Check the vector via a local variable.  */
+  if (a1[0] != 1)
+    __builtin_abort ();
+  if (a1[1] != 2)
+    __builtin_abort ();
+  if (a1[2] != 3)
+    __builtin_abort ();
+  if (a1[3] != 4)
+    __builtin_abort ();
+    
+  __builtin_memcpy(a, &val3, sizeof(a));  
+   /* Check the vector via copying it to an array.  */
+  for(i = 0; i < 4; i++)
+    if (a[i] != i+1)
+      __builtin_abort ();
+  
+  
+  return 0;
+}
Index: testsuite/g++.dg/torture/vector-subscript-4.C
===================================================================
--- testsuite/g++.dg/torture/vector-subscript-4.C	(revision 0)
+++ testsuite/g++.dg/torture/vector-subscript-4.C	(revision 0)
@@ -0,0 +1,68 @@
+/* { dg-do run } */
+/* { dg-options "-w" } */
+#define vector __attribute__((vector_size(sizeof(int)*4) ))
+
+/* Check to make sure that we extract and insert the vector at the same
+   location for vector subscripting (with constant indexes) and
+   that vectors layout are the same as arrays. */
+
+struct TV4
+{
+    vector int v;
+};
+typedef struct TV4 MYV4;
+
+template <typename type>
+static inline type myfunc2( int x, int y, int z, int w )
+{
+    type temp;
+    temp.v[0] = x;
+    temp.v[1] = y;
+    temp.v[2] = z;
+    temp.v[3] = w;
+    return temp;
+}
+MYV4 val3;
+__attribute__((noinline)) void modify (void) 
+{
+    val3 = myfunc2<MYV4>( 1, 2, 3, 4 );
+}
+int main( int argc, char* argv[] )
+{
+  int a[4];
+  int i;
+  
+  /* Set up the vector.  */
+  modify();
+  
+  /* Check the vector via the global variable.  */
+  if (val3.v[0] != 1)
+    __builtin_abort ();
+  if (val3.v[1] != 2)
+    __builtin_abort ();
+  if (val3.v[2] != 3)
+    __builtin_abort ();
+  if (val3.v[3] != 4)
+    __builtin_abort ();
+    
+  vector int a1 = val3.v;
+  
+   /* Check the vector via a local variable.  */
+  if (a1[0] != 1)
+    __builtin_abort ();
+  if (a1[1] != 2)
+    __builtin_abort ();
+  if (a1[2] != 3)
+    __builtin_abort ();
+  if (a1[3] != 4)
+    __builtin_abort ();
+    
+  __builtin_memcpy(a, &val3, sizeof(a));  
+   /* Check the vector via copying it to an array.  */
+  for(i = 0; i < 4; i++)
+    if (a[i] != i+1)
+      __builtin_abort ();
+  
+  
+  return 0;
+}
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 149591)
+++ cp/typeck.c	(working copy)
@@ -2557,6 +2557,17 @@ cp_build_indirect_ref (tree ptr, const c
   return error_mark_node;
 }
 
+/* Like cxx_mark_addressable but don't check register qualifier.  */
+static void
+mark_addressable_vector (tree x)
+{
+  while (handled_component_p (x))
+    x = TREE_OPERAND (x, 0);
+  if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
+    return ;
+  TREE_ADDRESSABLE (x) = 1;
+}
+
 /* This handles expressions of the form "a[i]", which denotes
    an array reference.
 
@@ -2612,6 +2623,22 @@ build_array_ref (location_t loc, tree ar
     default:
       break;
     }
+  
+  /* For vector[index], convert the vector to a pointer of the underlying
+     type. */
+  if (TREE_CODE (TREE_TYPE (array)) == VECTOR_TYPE)
+    {
+      tree type = TREE_TYPE (array);
+      tree type1;
+      /* Mark the vector as addressable but ignore the
+         register storage class.  */   
+      mark_addressable_vector (array);
+      type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
+      type = build_pointer_type (type);
+      type1 = build_pointer_type (TREE_TYPE (array));
+      array = build1 (ADDR_EXPR, type1, array);
+      array = convert (type, array);
+    }
 
   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
     {
Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 149591)
+++ cp/decl2.c	(working copy)
@@ -282,6 +282,17 @@ grokclassfn (tree ctype, tree function, 
     maybe_retrofit_in_chrg (function);
 }
 
+/* Like cxx_mark_addressable but don't check register storage class.  */
+static void
+mark_addressable_vector (tree x)
+{
+  while (handled_component_p (x))
+    x = TREE_OPERAND (x, 0);
+  if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
+    return ;
+  TREE_ADDRESSABLE (x) = 1;
+}
+
 /* Create an ARRAY_REF, checking for the user doing things backwards
    along the way.  */
 
@@ -318,6 +329,21 @@ grok_array_decl (tree array_expr, tree i
   else
     {
       tree p1, p2, i1, i2;
+      /* For vector[index], convert the vector to a pointer of the underlying
+	 type. */
+      if (TREE_CODE (type) == VECTOR_TYPE)
+	{
+	  tree type = TREE_TYPE (array_expr);
+	  tree type1;
+	  /* Mark the vector as addressable but ignore the
+	     register storage class.  */
+	  mark_addressable_vector (array_expr);
+	  type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
+	  type = build_pointer_type (type);
+	  type1 = build_pointer_type (TREE_TYPE (array_expr));
+	  array_expr = build1 (ADDR_EXPR, type1, array_expr);
+	  array_expr = convert (type, array_expr);
+      }
 
       /* Otherwise, create an ARRAY_REF for a pointer or array type.
 	 It is a little-known fact that, if `a' is an array and `i' is
Index: c-typeck.c
===================================================================
--- c-typeck.c	(revision 149591)
+++ c-typeck.c	(working copy)
@@ -2103,6 +2103,17 @@ build_indirect_ref (location_t loc, tree
   return error_mark_node;
 }
 
+/* Like c_mark_addressable but don't check register qualifier.  */
+static void 
+mark_addressable_vector (tree x)
+{   
+  while (handled_component_p (x))
+    x = TREE_OPERAND (x, 0);
+  if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
+    return ;
+  TREE_ADDRESSABLE (x) = 1;
+}  
+
 /* This handles expressions of the form "a[i]", which denotes
    an array reference.
 
@@ -2111,6 +2122,9 @@ build_indirect_ref (location_t loc, tree
    This avoids forcing the array out of registers, and can work on
    arrays that are not lvalues (for example, members of structures returned
    by functions).
+   
+   For vector types, allow vector[i] but not i[vector], and create
+   *(((type*)&vectortype) + i) for the expression. 
 
    LOC is the location to use for the returned expression.  */
 
@@ -2124,13 +2138,17 @@ build_array_ref (location_t loc, tree ar
     return error_mark_node;
 
   if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
-      && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE)
+      && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE
+      /* Allow vector[index] but not index[vector].  */
+      && TREE_CODE (TREE_TYPE (array)) != VECTOR_TYPE)
     {
       tree temp;
       if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
 	  && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
 	{
-	  error_at (loc, "subscripted value is neither array nor pointer");
+ 	  error_at (loc,
+		    "subscripted value is not an array, a pointer, or a vector");
+
 	  return error_mark_node;
 	}
       temp = array;
@@ -2160,6 +2178,22 @@ build_array_ref (location_t loc, tree ar
   index = default_conversion (index);
 
   gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
+  
+  /* For vector[index], convert the vector to a pointer of the underlying
+     type. */
+  if (TREE_CODE (TREE_TYPE (array)) == VECTOR_TYPE)
+    {
+      tree type = TREE_TYPE (array);
+      tree type1;
+      /* Mark the vector as addressable but ignore the
+	 register storage class.  */      
+      mark_addressable_vector (array);
+      type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
+      type = build_pointer_type (type);
+      type1 = build_pointer_type (TREE_TYPE (array));
+      array = build1 (ADDR_EXPR, type1, array);
+      array = convert (type, array);
+    }
 
   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
     {


More information about the Gcc-patches mailing list