[C++ PATCH] Fix build_expr_type_conversion with vector types (PR c++/29734)

Jakub Jelinek jakub@redhat.com
Mon Nov 20 14:57:00 GMT 2006


Hi!

Aldy's PR c++/10611 fix made build_expr_type_conversion
accept expressions with vector types whenever WANT_INT
is set.  But, in most places where build_expr_type_conversion
is called with WANT_INT (except whe it is WANT_ARITH and one
further place) the caller expects a scalar integer or enum.
Also we can't treat all vector types equally, e.g. BIT_NOT_EXPR
is supposed to apply to scalar int, enums and vector ints, but
not e.g. vector floats.
Fixed by the following patch, the testcase shows the differences
between unpatched and patched cc1plus, including 2 ICEs.
Ok for 4.1/4.2/4.3?

2006-11-20  Jakub Jelinek  <jakub@redhat.com>

	PR c++/29734
	* cp-tree.h (WANT_VECTOR): Define.
	(WANT_ARITH): Add WANT_VECTOR.
	* cvt.c (build_expr_type_conversion): Handle vector types.
	* typeck.c (build_unary_op): Add WANT_VECTOR to
	build_expr_type_conversion flags.

	* g++.dg/conversion/simd4.C: New test.

--- gcc/cp/cp-tree.h.jj	2006-11-01 10:31:25.000000000 +0100
+++ gcc/cp/cp-tree.h	2006-11-20 12:09:28.000000000 +0100
@@ -3468,7 +3468,8 @@ enum overload_flags { NO_SPECIAL = 0, DT
 #define WANT_ENUM	4 /* enumerated types */
 #define WANT_POINTER	8 /* pointer types */
 #define WANT_NULL      16 /* null pointer constant */
-#define WANT_ARITH	(WANT_INT | WANT_FLOAT)
+#define WANT_VECTOR    32 /* vector types */
+#define WANT_ARITH	(WANT_INT | WANT_FLOAT | WANT_VECTOR)
 
 /* Used with comptypes, and related functions, to guide type
    comparison.  */
--- gcc/cp/cvt.c.jj	2006-10-05 00:26:45.000000000 +0200
+++ gcc/cp/cvt.c	2006-11-20 13:45:44.000000000 +0100
@@ -1103,7 +1103,6 @@ build_expr_type_conversion (int desires,
 	  return expr;
 	/* else fall through...  */
 
-      case VECTOR_TYPE:
       case BOOLEAN_TYPE:
 	return (desires & WANT_INT) ? expr : NULL_TREE;
       case ENUMERAL_TYPE:
@@ -1117,6 +1116,23 @@ build_expr_type_conversion (int desires,
       case ARRAY_TYPE:
 	return (desires & WANT_POINTER) ? decay_conversion (expr)
 					: NULL_TREE;
+
+      case VECTOR_TYPE:
+	if ((desires & WANT_VECTOR) == 0)
+	  return NULL_TREE;
+	switch (TREE_CODE (TREE_TYPE (basetype)))
+	  {
+	  case INTEGER_TYPE:
+	  case BOOLEAN_TYPE:
+	    return (desires & WANT_INT) ? expr : NULL_TREE;
+	  case ENUMERAL_TYPE:
+	    return (desires & WANT_ENUM) ? expr : NULL_TREE;
+	  case REAL_TYPE:
+	    return (desires & WANT_FLOAT) ? expr : NULL_TREE;
+	  default:
+	    return NULL_TREE;
+	  }
+
       default:
 	return NULL_TREE;
       }
@@ -1151,6 +1167,23 @@ build_expr_type_conversion (int desires,
 	case POINTER_TYPE:
 	  win = (desires & WANT_POINTER); break;
 
+	case VECTOR_TYPE:
+	  if ((desires & WANT_VECTOR) == 0)
+	    break;
+	  switch (TREE_CODE (TREE_TYPE (candidate)))
+	    {
+	    case BOOLEAN_TYPE:
+	    case INTEGER_TYPE:
+	      win = (desires & WANT_INT); break;
+	    case ENUMERAL_TYPE:
+	      win = (desires & WANT_ENUM); break;
+	    case REAL_TYPE:
+	      win = (desires & WANT_FLOAT); break;
+	    default:
+	      break;
+	    }
+	  break;
+
 	default:
 	  break;
 	}
--- gcc/cp/typeck.c.jj	2006-11-11 18:21:06.000000000 +0100
+++ gcc/cp/typeck.c	2006-11-20 12:10:12.000000000 +0100
@@ -3995,7 +3995,8 @@ build_unary_op (enum tree_code code, tre
 	  if (!noconvert)
 	    arg = default_conversion (arg);
 	}
-      else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM,
+      else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
+						   | WANT_VECTOR,
 						   arg, true)))
 	errstring = "wrong type argument to bit-complement";
       else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
--- gcc/testsuite/g++.dg/conversion/simd4.C.jj	2006-11-20 15:22:58.000000000 +0100
+++ gcc/testsuite/g++.dg/conversion/simd4.C	2006-11-20 15:23:55.000000000 +0100
@@ -0,0 +1,34 @@
+// PR c++/29734
+// { dg-do compile }
+// { dg-options "" }
+
+int t;
+float u;
+int __attribute__((vector_size (8))) v;
+float __attribute__((vector_size (8))) w;
+int b[10];
+
+void
+foo ()
+{
+  b[t];
+  b[u];		// { dg-error "invalid types" }
+  b[v];		// { dg-error "invalid types" }
+  b[w];		// { dg-error "invalid types" }
+  t[b];
+  u[b];		// { dg-error "invalid types" }
+  v[b];		// { dg-error "invalid types" }
+  w[b];		// { dg-error "invalid types" }
+  new int[t];
+  new int[u];	// { dg-error "new-declarator must have integral" }
+  new int[v];	// { dg-error "new-declarator must have integral" }
+  new int[w];	// { dg-error "new-declarator must have integral" }
+  switch (t) { default: break; }
+  switch (u) { default: break; }	// { dg-error "switch quantity not an integer" }
+  switch (v) { default: break; }	// { dg-error "switch quantity not an integer" }
+  switch (w) { default: break; }	// { dg-error "switch quantity not an integer" }
+  t = ~t;
+  u = ~u;	// { dg-error "wrong type argument to bit-complement" }
+  v = ~v;
+  w = ~w;	// { dg-error "wrong type argument to bit-complement" }
+}

	Jakub



More information about the Gcc-patches mailing list