This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR/16882: overload resolution of vector types


This patch fixes the problem with PR/16882. I actually don't know how it managed to pass earlier.

The problem is that const vector types were built incorrectly: the qualifier is stored in the inner type, and the vector type itself is unqualified, so every vector type is its main variant.

This patch fixes the problem by:
- using the main variant (unqualified) as the vector type's inner type
- qualifying the vector type
- ensuring the inner type is unqualified (otherwise we'd print vectors as "const const")


So instead of

    const vector signed short <-----------.
      |                |                  | TYPE_MAIN_VARIANT
      | TREE_TYPE      '------------------'
      V
    const signed short
      |
      | TYPE_MAIN_VARIANT
      V
    signed short

we now build


const vector signed short ------------. | | | TREE_TYPE | TYPE_MAIN_VARIANT V V signed short vector signed short ^ | |___________________________________| TREE_TYPE


In addition to this, the test on vector compatibility should be moved from standard_conversion to ptr_reasonably_similar, in order to give the conversion a correct rank of ck_ptr instead of ck_std; however this causes the conversion to be made a "near match" rather than a viable conversion. This should be correct since C++ is stricter about implicit conversions, but please tell me if it causes AltiVec regressions.


Bootstrapped/regtested all languages i686-pc-linux-gnu, no new failures and fixes the new testcase. Ok for mainline?

2004-08-05 Paolo Bonzini <bonzini@gnu.org>

	* tree.c (make_vector_type): Move qualifiers to the vector type,
	use the inner type's main variant and build a main variant for
	the vector type if necessary.

cp:
2004-08-05  Paolo Bonzini  <bonzini@gnu.org>

	* call.c (standard_conversion): Move check for conversions
	between vector pointers...
	* typeck.c (ptr_reasonably_similar): ... here.

testsuite:
2004-08-05  Paolo Bonzini  <bonzini@gnu.org>

* g++.dg/overload/simd1.C: New testcase.

Paolo

Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.406
diff -p -u -r1.406 tree.c
--- tree.c	28 Jul 2004 23:44:48 -0000	1.406
+++ tree.c	5 Aug 2004 07:42:58 -0000
@@ -5174,9 +5174,12 @@ make_vector_type (tree innertype, int nu
 {
   tree t = make_node (VECTOR_TYPE);
 
-  TREE_TYPE (t) = innertype;
+  TREE_TYPE (t) = TYPE_MAIN_VARIANT (innertype);
   TYPE_VECTOR_SUBPARTS (t) = nunits;
   TYPE_MODE (t) = mode;
+  TYPE_READONLY (t) = TYPE_READONLY (innertype);
+  TYPE_VOLATILE (t) = TYPE_VOLATILE (innertype);
+
   layout_type (t);
 
   {
@@ -5195,6 +5198,16 @@ make_vector_type (tree innertype, int nu
     TYPE_UID (rt) = TYPE_UID (t);
   }
 
+  /* Build our main variant, based on the main variant of the inner type.  */
+  if (TYPE_MAIN_VARIANT (innertype) != innertype)
+    {
+      tree innertype_main_variant = TYPE_MAIN_VARIANT (innertype);
+      unsigned int hash = TYPE_HASH (innertype_main_variant);
+      TYPE_MAIN_VARIANT (t)
+        = type_hash_canon (hash, make_vector_type (innertype_main_variant,
+						   nunits, mode));
+    }
+
   return t;
 }
 
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.498
diff -p -u -r1.498 call.c
--- cp/call.c	5 Aug 2004 05:51:53 -0000	1.498
+++ cp/call.c	5 Aug 2004 07:42:58 -0000
@@ -663,11 +663,6 @@ standard_conversion (tree to, tree from,
   if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to))
       && expr && null_ptr_cst_p (expr))
     conv = build_conv (ck_std, to, conv);
-  else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
-	   && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
-	   && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
-	   && vector_types_convertible_p (TREE_TYPE (to), TREE_TYPE (from)))
-    conv = build_conv (ck_std, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
 	   || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
     {
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.566
diff -p -u -r1.566 typeck.c
--- cp/typeck.c	2 Aug 2004 01:58:50 -0000	1.566
+++ cp/typeck.c	5 Aug 2004 07:42:59 -0000
@@ -6148,6 +6148,10 @@ ptr_reasonably_similar (tree to, tree fr
 			COMPARE_BASE | COMPARE_DERIVED))
 	continue;
 
+      if (TREE_CODE (to) == VECTOR_TYPE
+	  && vector_types_convertible_p (to, from))
+	return 1;
+
       if (TREE_CODE (to) == INTEGER_TYPE
 	  && TYPE_PRECISION (to) == TYPE_PRECISION (from))
 	return 1;
/* { dg-do compile } */

/* Test overload resolution of vector types.
   From Janis Johnson and Paolo Bonzini, based on PR/16882 */

#define vector __attribute__((vector_size(16)))
                                                                                
vector signed int
vld (int a1, const vector signed int *a2)
{ /* { dg-error "near match" } */
  return *a2;
}

vector signed short
vld (int a1, const vector signed short *a2)
{ /* { dg-error "near match" } */
  return *a2;
}
                                                                                
extern int i;
extern vector signed short vss;
extern vector signed char *vscp;
extern vector signed short *vssp;
extern const vector signed short *cvssp;
                                                                                
void foo ()
{
  vss = vld(i, vscp);        /* { dg-error "no matching" } */
  vss = vld(i, vssp);
  vss = vld(i, cvssp);
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]