Commit cc83c823 by Jakub Jelinek Committed by Jakub Jelinek

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
parent fdbff37f
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> 2012-12-03 Marek Polacek <polacek@redhat.com>
PR c/55570 PR c/55570
......
/* Subroutines shared by all languages that are variants of C. /* Subroutines shared by all languages that are variants of C.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
Free Software Foundation, Inc. 2013 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -1269,6 +1269,25 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, ...@@ -1269,6 +1269,25 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
&& !TREE_OVERFLOW_P (op0) && !TREE_OVERFLOW_P (op0)
&& !TREE_OVERFLOW_P (op1)) && !TREE_OVERFLOW_P (op1))
overflow_warning (EXPR_LOCATION (expr), ret); 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; goto out;
case INDIRECT_REF: case INDIRECT_REF:
......
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> 2013-01-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/55801 PR c++/55801
......
/* Build expressions with type checking for C++ compiler. /* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011, 2012 2011, 2012, 2013
Free Software Foundation, Inc. Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com) Hacked by Michael Tiemann (tiemann@cygnus.com)
...@@ -4095,10 +4095,13 @@ cp_build_binary_op (location_t location, ...@@ -4095,10 +4095,13 @@ cp_build_binary_op (location_t location,
} }
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) 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; 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) if ((complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0) && c_inhibit_evaluation_warnings == 0)
...@@ -4106,7 +4109,7 @@ cp_build_binary_op (location_t location, ...@@ -4106,7 +4109,7 @@ cp_build_binary_op (location_t location,
} }
else else
{ {
if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0 if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0
&& (complain & tf_warning) && (complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0) && c_inhibit_evaluation_warnings == 0)
warning (0, "right shift count >= width of type"); warning (0, "right shift count >= width of type");
...@@ -4138,16 +4141,20 @@ cp_build_binary_op (location_t location, ...@@ -4138,16 +4141,20 @@ cp_build_binary_op (location_t location,
} }
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) 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; 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) if ((complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0) && c_inhibit_evaluation_warnings == 0)
warning (0, "left shift count is negative"); 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) if ((complain & tf_warning)
&& c_inhibit_evaluation_warnings == 0) && c_inhibit_evaluation_warnings == 0)
......
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> 2013-01-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/55801 PR c++/55801
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment