aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2014-11-28 09:06:48 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2014-11-28 09:06:48 +0000
commit541e35a6a3f8ca2d9877ea6c477e765e1d0a9497 (patch)
tree4f8a839fa82870468359fe7d2e0ca156c9cfa4ef
parent7e015fcefe33eded9a565e7e2ad3da11952249ae (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/c-family/c-gimplify.c18
-rw-r--r--gcc/c-family/c-ubsan.c2
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-typeck.c10
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/shift-7.c27
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/shiftopt-1.c5
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