diff options
author | Marek Polacek <polacek@redhat.com> | 2014-11-28 09:06:48 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2014-11-28 09:06:48 +0000 |
commit | 541e35a6a3f8ca2d9877ea6c477e765e1d0a9497 (patch) | |
tree | 4f8a839fa82870468359fe7d2e0ca156c9cfa4ef | |
parent | 7e015fcefe33eded9a565e7e2ad3da11952249ae (diff) | |
download | gcc-541e35a6a3f8ca2d9877ea6c477e765e1d0a9497.zip gcc-541e35a6a3f8ca2d9877ea6c477e765e1d0a9497.tar.gz gcc-541e35a6a3f8ca2d9877ea6c477e765e1d0a9497.tar.bz2 |
re PR c/63862 (C frontend converts shift-count to int while standard wants integer promotions)
PR c/63862
c-family/
* c-ubsan.c (ubsan_instrument_shift): Change the type of a MINUS_EXPR
to op1_utype.
* c-gimplify.c (c_gimplify_expr): Convert right operand of a shift
expression to unsigned_type_node.
c/
* c-typeck.c (build_binary_op) <RSHIFT_EXPR, LSHIFT_EXPR>: Don't
convert the right operand to integer type.
cp/
* typeck.c (cp_build_binary_op) <RSHIFT_EXPR, LSHIFT_EXPR>: Don't
convert the right operand to integer type.
testsuite/
* gcc.c-torture/execute/shiftopt-1.c: Don't XFAIL anymore.
* c-c++-common/ubsan/shift-7.c: New test.
From-SVN: r218142
-rw-r--r-- | gcc/c-family/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/c-family/c-gimplify.c | 18 | ||||
-rw-r--r-- | gcc/c-family/c-ubsan.c | 2 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 10 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/shift-7.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/shiftopt-1.c | 5 |
10 files changed, 72 insertions, 24 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 74172f9..efb4735 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2014-11-28 Marek Polacek <polacek@redhat.com> + + PR c/63862 + * c-ubsan.c (ubsan_instrument_shift): Change the type of a MINUS_EXPR + to op1_utype. + * c-gimplify.c (c_gimplify_expr): Convert right operand of a shift + expression to unsigned_type_node. + 2014-11-20 Mark Wielaard <mjw@redhat.com> PR debug/38757 diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c index 85b4223..2cfa5d9 100644 --- a/gcc/c-family/c-gimplify.c +++ b/gcc/c-family/c-gimplify.c @@ -242,6 +242,24 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED, switch (code) { + case LSHIFT_EXPR: + case RSHIFT_EXPR: + { + /* We used to convert the right operand of a shift-expression + to an integer_type_node in the FEs. But it is unnecessary + and not desirable for diagnostics and sanitizers. We keep + this here to not pessimize the code, but we convert to an + unsigned type, because negative shift counts are undefined + anyway. + We should get rid of this conversion when we have a proper + type demotion/promotion pass. */ + tree *op1_p = &TREE_OPERAND (*expr_p, 1); + if (TREE_CODE (TREE_TYPE (*op1_p)) != VECTOR_TYPE + && TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)) != unsigned_type_node) + *op1_p = convert (unsigned_type_node, *op1_p); + break; + } + case DECL_EXPR: /* This is handled mostly by gimplify.c, but we have to deal with not warning about int x = x; as it is a GCC extension to turn off diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index 90b03f2..96afc67 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -151,7 +151,7 @@ ubsan_instrument_shift (location_t loc, enum tree_code code, && !TYPE_UNSIGNED (type0) && flag_isoc99) { - tree x = fold_build2 (MINUS_EXPR, unsigned_type_node, uprecm1, + tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1, fold_convert (op1_utype, op1)); tt = fold_convert_loc (loc, unsigned_type_for (type0), op0); tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x); diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index e2a9630..0f42b10 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2014-11-28 Marek Polacek <polacek@redhat.com> + + PR c/63862 + * c-typeck.c (build_binary_op) <RSHIFT_EXPR, LSHIFT_EXPR>: Don't + convert the right operand to integer type. + 2014-11-25 Marek Polacek <polacek@redhat.com> PR c/63877 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 67efb46..bf0f306 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -10513,11 +10513,6 @@ build_binary_op (location_t location, enum tree_code code, /* Use the type of the value to be shifted. */ result_type = type0; - /* Convert the non vector shift-count to an integer, regardless - of size of value being shifted. */ - if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); /* Avoid converting op1 to result_type later. */ converted = 1; } @@ -10563,11 +10558,6 @@ build_binary_op (location_t location, enum tree_code code, /* Use the type of the value to be shifted. */ result_type = type0; - /* Convert the non vector shift-count to an integer, regardless - of size of value being shifted. */ - if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); /* Avoid converting op1 to result_type later. */ converted = 1; } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a59182b..daf7f9b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2014-11-28 Marek Polacek <polacek@redhat.com> + + PR c/63862 + * typeck.c (cp_build_binary_op) <RSHIFT_EXPR, LSHIFT_EXPR>: Don't + convert the right operand to integer type. + 2014-11-27 Kai Tietz <ktietz@redhat.com> PR c++/63904 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 8b66acc..6ca346b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4295,10 +4295,6 @@ cp_build_binary_op (location_t location, "right shift count >= width of type"); } } - /* Convert the shift-count to an integer, regardless of - size of value being shifted. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1, complain); /* Avoid converting op1 to result_type later. */ converted = 1; } @@ -4344,10 +4340,6 @@ cp_build_binary_op (location_t location, "left shift count >= width of type"); } } - /* Convert the shift-count to an integer, regardless of - size of value being shifted. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1, complain); /* Avoid converting op1 to result_type later. */ converted = 1; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4647a46..4bb39e1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-11-28 Marek Polacek <polacek@redhat.com> + + PR c/63862 + * gcc.c-torture/execute/shiftopt-1.c: Don't XFAIL anymore. + * c-c++-common/ubsan/shift-7.c: New test. + 2014-11-28 Richard Biener <rguenther@suse.de> PR middle-end/64084 diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-7.c b/gcc/testsuite/c-c++-common/ubsan/shift-7.c new file mode 100644 index 0000000..1e33273 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/shift-7.c @@ -0,0 +1,27 @@ +/* PR c/63862 */ +/* { dg-do run } */ +/* { dg-options "-fsanitize=undefined" } */ + +unsigned long long int __attribute__ ((noinline, noclone)) +foo (unsigned long long int i, unsigned long long int j) +{ + asm (""); + return i >> j; +} + +unsigned long long int __attribute__ ((noinline, noclone)) +bar (unsigned long long int i, unsigned long long int j) +{ + asm (""); + return i << j; +} + +int +main () +{ + foo (1ULL, 0x100000000ULL); + bar (1ULL, 0x100000000ULL); +} + +/* { dg-output "shift exponent 4294967296 is too large for \[^\n\r]*-bit type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 4294967296 is too large for \[^\n\r]*-bit type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/gcc.c-torture/execute/shiftopt-1.c b/gcc/testsuite/gcc.c-torture/execute/shiftopt-1.c index 3ff714d..8c855b8 100644 --- a/gcc/testsuite/gcc.c-torture/execute/shiftopt-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/shiftopt-1.c @@ -22,16 +22,11 @@ utest (unsigned int x) if (0 >> x != 0) link_error (); - /* XFAIL: the C frontend converts the shift amount to 'int' - thus we get -1 >> (int)x which means the shift amount may - be negative. See PR63862. */ -#if 0 if (-1 >> x != -1) link_error (); if (~0 >> x != ~0) link_error (); -#endif } void |