summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-01-09 14:51:09 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-01-09 14:51:09 +0000
commit7c8344365f5915917fa82cab8d9f0d1565f4b62f (patch)
tree9860db1553f003a5d248886e9631536f697cf020 /gcc
parente94644293b12944cfd638494dd58586673531213 (diff)
downloadgcc-7c8344365f5915917fa82cab8d9f0d1565f4b62f.tar.gz
PR c/48418
* c-common.c (c_fully_fold_internal): Warn for LSHIFT_EXPR and RSHIFT_EXPR, if orig_op1 isn't INTEGER_CST, op1 is INTEGER_CST and is either negative or bigger or equal to type precision of the first operand. * typeck.c (cp_build_binary_op): For LSHIFT_EXPR and RSHIFT_EXPR, call maybe_constant_value for the negative or too big shift count warnings. * c-c++-common/pr48418.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@195051 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog8
-rw-r--r--gcc/c-family/c-common.c23
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/typeck.c21
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/pr48418.c20
6 files changed, 75 insertions, 9 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index a743517dcef..84addf720bb 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,11 @@
+2013-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/48418
+ * c-common.c (c_fully_fold_internal): Warn for LSHIFT_EXPR and
+ RSHIFT_EXPR, if orig_op1 isn't INTEGER_CST, op1 is INTEGER_CST
+ and is either negative or bigger or equal to type precision
+ of the first operand.
+
2012-12-03 Marek Polacek <polacek@redhat.com>
PR c/55570
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 012751330f3..72483937b7a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1,7 +1,7 @@
/* Subroutines shared by all languages that are variants of C.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
+ 2013 Free Software Foundation, Inc.
This file is part of GCC.
@@ -1269,6 +1269,25 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
&& !TREE_OVERFLOW_P (op0)
&& !TREE_OVERFLOW_P (op1))
overflow_warning (EXPR_LOCATION (expr), ret);
+ if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR)
+ && TREE_CODE (orig_op1) != INTEGER_CST
+ && TREE_CODE (op1) == INTEGER_CST
+ && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
+ && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
+ && c_inhibit_evaluation_warnings == 0)
+ {
+ if (tree_int_cst_sgn (op1) < 0)
+ warning_at (loc, 0, (code == LSHIFT_EXPR
+ ? G_("left shift count is negative")
+ : G_("right shift count is negative")));
+ else if (compare_tree_int (op1,
+ TYPE_PRECISION (TREE_TYPE (orig_op0)))
+ >= 0)
+ warning_at (loc, 0, (code == LSHIFT_EXPR
+ ? G_("left shift count >= width of type")
+ : G_("right shift count >= width of type")));
+ }
goto out;
case INDIRECT_REF:
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 46583530161..d67a3c40f35 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2013-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/48418
+ * typeck.c (cp_build_binary_op): For LSHIFT_EXPR and RSHIFT_EXPR,
+ call maybe_constant_value for the negative or too big shift
+ count warnings.
+
2013-01-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/55801
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 66fb33ab56d..864213534d8 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1,7 +1,7 @@
/* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011, 2012
+ 2011, 2012, 2013
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@@ -4095,10 +4095,13 @@ cp_build_binary_op (location_t location,
}
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
+ tree const_op1 = maybe_constant_value (op1);
+ if (TREE_CODE (const_op1) != INTEGER_CST)
+ const_op1 = op1;
result_type = type0;
- if (TREE_CODE (op1) == INTEGER_CST)
+ if (TREE_CODE (const_op1) == INTEGER_CST)
{
- if (tree_int_cst_lt (op1, integer_zero_node))
+ if (tree_int_cst_lt (const_op1, integer_zero_node))
{
if ((complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0)
@@ -4106,7 +4109,7 @@ cp_build_binary_op (location_t location,
}
else
{
- if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0
+ if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0
&& (complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0)
warning (0, "right shift count >= width of type");
@@ -4138,16 +4141,20 @@ cp_build_binary_op (location_t location,
}
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
+ tree const_op1 = maybe_constant_value (op1);
+ if (TREE_CODE (const_op1) != INTEGER_CST)
+ const_op1 = op1;
result_type = type0;
- if (TREE_CODE (op1) == INTEGER_CST)
+ if (TREE_CODE (const_op1) == INTEGER_CST)
{
- if (tree_int_cst_lt (op1, integer_zero_node))
+ if (tree_int_cst_lt (const_op1, integer_zero_node))
{
if ((complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0)
warning (0, "left shift count is negative");
}
- else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
+ else if (compare_tree_int (const_op1,
+ TYPE_PRECISION (type0)) >= 0)
{
if ((complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f300905689b..5b95a473a64 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/48418
+ * c-c++-common/pr48418.c: New test.
+
2013-01-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/55801
diff --git a/gcc/testsuite/c-c++-common/pr48418.c b/gcc/testsuite/c-c++-common/pr48418.c
new file mode 100644
index 00000000000..95ff855b89c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr48418.c
@@ -0,0 +1,20 @@
+/* PR c/48418 */
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2" } */
+
+int
+foo (int x)
+{
+ const int a = sizeof (int) * __CHAR_BIT__;
+ const int b = -7;
+ int c = 0;
+ c += x << a; /* { dg-warning "left shift count >= width of type" } */
+ c += x << b; /* { dg-warning "left shift count is negative" } */
+ c += x << (sizeof (int) * __CHAR_BIT__); /* { dg-warning "left shift count >= width of type" } */
+ c += x << -7; /* { dg-warning "left shift count is negative" } */
+ c += x >> a; /* { dg-warning "right shift count >= width of type" } */
+ c += x >> b; /* { dg-warning "right shift count is negative" } */
+ c += x >> (sizeof (int) * __CHAR_BIT__); /* { dg-warning "right shift count >= width of type" } */
+ c += x >> -7; /* { dg-warning "right shift count is negative" } */
+ return c;
+}