diff options
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 28 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/vector-compare-4.c | 42 |
6 files changed, 101 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7d6250e..7999d2a 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2016-01-27 Marek Polacek <polacek@redhat.com> + + 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 <jakub@redhat.com> PR tree-optimization/69483 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index d602e33..65925cb 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 493b17a..52fb9d8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-01-27 Marek Polacek <polacek@redhat.com> + + PR c/68062 + * typeck.c (cp_build_binary_op): Promote operand to unsigned, if + needed. Add -Wsign-compare warning. + 2016-01-27 Ryan Burn <contact@rnburn.com> PR cilkplus/69267 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 0503c6f..d2c23f4 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 e674bf4..2cad0c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-27 Marek Polacek <polacek@redhat.com> + + PR c/68062 + * c-c++-common/vector-compare-4.c: New test. + 2016-01-27 David Malcolm <dmalcolm@redhat.com> 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 0000000..b44f474 --- /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; +} |