From: Marek Polacek Date: Wed, 27 Jan 2016 19:13:42 +0000 (+0000) Subject: re PR c/68062 (ICE when comparing vectors) X-Git-Tag: basepoints/gcc-7~1275 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa74a4bca84aabe0a1500e4fe5359895c1f07e55;p=thirdparty%2Fgcc.git re PR c/68062 (ICE when comparing vectors) PR c/68062 * c-typeck.c (build_binary_op) [EQ_EXPR, GE_EXPR]: Promote operand to unsigned, if needed. Add -Wsign-compare warning. * typeck.c (cp_build_binary_op): Promote operand to unsigned, if needed. Add -Wsign-compare warning. * c-c++-common/vector-compare-4.c: New test. From-SVN: r232894 --- diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7d6250e586a6..7999d2a987a8 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2016-01-27 Marek Polacek + + PR c/68062 + * c-typeck.c (build_binary_op) [EQ_EXPR, GE_EXPR]: Promote operand + to unsigned, if needed. Add -Wsign-compare warning. + 2016-01-26 Jakub Jelinek PR tree-optimization/69483 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index d602e3383e9e..65925cbc8e7f 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -11048,6 +11048,20 @@ build_binary_op (location_t location, enum tree_code code, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + warning_at (location, OPT_Wsign_compare, "comparison between " + "types %qT and %qT", type0, type1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); @@ -11201,6 +11215,20 @@ build_binary_op (location_t location, enum tree_code code, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + warning_at (location, OPT_Wsign_compare, "comparison between " + "types %qT and %qT", type0, type1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 493b17afee32..52fb9d8c3642 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-01-27 Marek Polacek + + PR c/68062 + * typeck.c (cp_build_binary_op): Promote operand to unsigned, if + needed. Add -Wsign-compare warning. + 2016-01-27 Ryan Burn PR cilkplus/69267 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 0503c6f0c738..d2c23f42df2f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4823,6 +4823,20 @@ cp_build_binary_op (location_t location, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + warning_at (location, OPT_Wsign_compare, "comparison between " + "types %qT and %qT", type0, type1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e674bf495bab..2cad0c2585bd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-27 Marek Polacek + + PR c/68062 + * c-c++-common/vector-compare-4.c: New test. + 2016-01-27 David Malcolm PR preprocessor/69126 diff --git a/gcc/testsuite/c-c++-common/vector-compare-4.c b/gcc/testsuite/c-c++-common/vector-compare-4.c new file mode 100644 index 000000000000..b44f474f395e --- /dev/null +++ b/gcc/testsuite/c-c++-common/vector-compare-4.c @@ -0,0 +1,42 @@ +/* PR c/68062 */ +/* { dg-do compile } */ +/* { dg-options "-Wsign-compare" } */ + +typedef signed char __attribute__ ((vector_size (4))) v4qi; +typedef unsigned char __attribute__ ((vector_size (4))) uv4qi; +typedef signed int __attribute__ ((vector_size (4 * __SIZEOF_INT__))) v4si; +typedef unsigned int __attribute__ ((vector_size (4 * __SIZEOF_INT__))) uv4si; + +v4qi +fn1 (void) +{ + v4qi a = { 1, 2, 3, 4 }; + uv4qi b = { 4, 3, 2, 1 }; + v4qi v = { 0, 0, 0, 0 }; + + v += (a == b); /* { dg-warning "comparison between types" } */ + v += (a != b); /* { dg-warning "comparison between types" } */ + v += (a >= b); /* { dg-warning "comparison between types" } */ + v += (a <= b); /* { dg-warning "comparison between types" } */ + v += (a > b); /* { dg-warning "comparison between types" } */ + v += (a < b); /* { dg-warning "comparison between types" } */ + + return v; +} + +v4si +fn2 (void) +{ + v4si a = { 1, 2, 3, 4 }; + uv4si b = { 4, 3, 2, 1 }; + v4si v = { 0, 0, 0, 0 }; + + v += (a == b); /* { dg-warning "comparison between types" } */ + v += (a != b); /* { dg-warning "comparison between types" } */ + v += (a >= b); /* { dg-warning "comparison between types" } */ + v += (a <= b); /* { dg-warning "comparison between types" } */ + v += (a > b); /* { dg-warning "comparison between types" } */ + v += (a < b); /* { dg-warning "comparison between types" } */ + + return v; +}