re PR c/48418 (Bit shift operator >>=)

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.

From-SVN: r195051
This commit is contained in:
Jakub Jelinek 2013-01-09 15:51:09 +01:00 committed by Jakub Jelinek
parent fdbff37f39
commit cc83c823a2
6 changed files with 75 additions and 9 deletions

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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;
}