summaryrefslogtreecommitdiff
path: root/gcc/c-family/c-gimplify.c
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 /gcc/c-family/c-gimplify.c
parent7e015fcefe33eded9a565e7e2ad3da11952249ae (diff)
downloadgcc-541e35a6a3f8ca2d9877ea6c477e765e1d0a9497.tar.gz
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
Diffstat (limited to 'gcc/c-family/c-gimplify.c')
-rw-r--r--gcc/c-family/c-gimplify.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c
index 85b42237538..2cfa5d96a65 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