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] Fix PR c++/30022: ICE on vector operand in division


The following code snippet crashes the C++ frontend since GCC 4.0.0:

  void foo()
  {
    int __attribute__((vector_size(8))) v;
    v = 1/v;
  }

  bug.cc: In function 'void foo()':
  bug.cc:4: internal compiler error: in
type_after_usual_arithmetic_conversions, at cp/typeck.c:266
  Please submit a full bug report, [etc.]

The ICE is caused by a typo in type_after_usual_arithmetic_conversions
- a "t1" has to be replced with "t2" in a gcc_assert.
With this fix the ICE goes away, but we now get a bogus error message:

  bug.cc: In function 'void foo()':
  bug.cc:4: error: can't convert between vector values of different size

This is because the code that decides if a promotion for the inner types
has to be performed overwrites the actual tree_code of the vector type.
The patch fixes this by introducing temporaries for this purpose.
Btw, this is how the C frontend works as I found out after preparing the
patch (I only had to change the variable name to match the C frontend).

With this patch we get:

  bug.cc: In function 'void foo()':
  bug.cc:4: error: invalid operands of types 'int' and 'int __vector__' to
binary 'operator/'

which matches the error message for operator*.

Bootstrapped and regtested on i686-pc-linux-gnu.
Ok for mainline down to 4.0 branch?

Regards,
Volker

:ADDPATCH C++:


2006-11-25  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/30022
	* typeck.c (type_after_usual_arithmetic_conversions):
	Fix assertion for vector types.
	(build_binary_op): Use temporary for inner type of vector types.

=======================================================================
--- gcc/gcc/cp/typeck.c	2006-11-21 15:25:24 +0100
+++ gcc/gcc/cp/typeck.c	2006-11-25 16:58:48 +0100
@@ -262,7 +262,7 @@ type_after_usual_arithmetic_conversions
 	      || TREE_CODE (t1) == ENUMERAL_TYPE);
   gcc_assert (ARITHMETIC_TYPE_P (t2)
 	      || TREE_CODE (t2) == COMPLEX_TYPE
-	      || TREE_CODE (t1) == VECTOR_TYPE
+	      || TREE_CODE (t2) == VECTOR_TYPE
 	      || TREE_CODE (t2) == ENUMERAL_TYPE);

   /* In what follows, we slightly generalize the rules given in [expr] so
@@ -3093,17 +3093,19 @@ build_binary_op (enum tree_code code, tr
 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
 	      || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
 	{
+	  enum tree_code tcode0 = code0, tcode1 = code1;
+
 	  if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
 	    warning (OPT_Wdiv_by_zero, "division by zero in %<%E / 0%>", op0);
 	  else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1))
 	    warning (OPT_Wdiv_by_zero, "division by zero in %<%E / 0.%>", op0);

-	  if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
-	    code0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
-	  if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
-	    code1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
+	  if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
+	    tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
+	  if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
+	    tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));

-	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
+	  if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE))
 	    resultcode = RDIV_EXPR;
 	  else
 	    /* When dividing two signed integers, we have to promote to int.
=======================================================================

2006-11-25  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/30022
	* g++.dg/ext/vector5.C: New test.

=======================================================================
--- gcc/gcc/testsuite/g++.dg/ext/vector5.C	2003-09-23 19:59:22 +0200
+++ gcc/gcc/testsuite/g++.dg/ext/vector5.C	2006-11-25 17:06:56 +0100
@@ -0,0 +1,8 @@
+// PR c++/30022
+// { dg-do compile }
+
+void foo()
+{
+  int __attribute__((vector_size(8))) v;
+  v = 1/v;  // { dg-error "invalid operands of types" }
+}
=======================================================================




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