This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR c++/30022: ICE on vector operand in division
- From: reichelt at igpm dot rwth-aachen dot de
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 29 Nov 2006 23:12:01 +0100 (CET)
- Subject: [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" }
+}
=======================================================================