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>
PR c/55570
......
/* 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:
......
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
......
/* 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)
......
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
......
/* 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