@@ -1269,6 +1269,25 @@ c_fully_fold_internal (tree expr, bool i
&& !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
+ ? "left shift count is negative"
+ : "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
+ ? "left shift count >= width of type"
+ : "right shift count >= width of type"));
+ }
goto out;
case INDIRECT_REF:
@@ -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)
@@ -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;
+}