re PR c/19978 (overflow in expression of constants should not cause multiple warnings)
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org> PR c/19978 * tree.h (TREE_OVERFLOW_P): New. * c-typeck.c (parser_build_unary_op): Warn only if result overflowed and operands did not. (parser_build_binary_op): Likewise. (convert_for_assignment): Remove redundant overflow_warning. * c-common.c (overflow_warning): Don't check or set TREE_OVERFLOW. cp/ * semantics.c (finish_unary_op_expr): Warn only if result overflowed and operands did not. testsuite/ * gcc.dg/multiple-overflow-warn-1.c: New. * gcc.dg/multiple-overflow-warn-2.c: New. * gcc.dg/overflow-warn-6.c: New. * g++.dg/warn/multiple-overflow-warn-1.C: New. From-SVN: r120505
This commit is contained in:
parent
c2658540a3
commit
59c0753dd3
|
@ -1,3 +1,13 @@
|
|||
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||
|
||||
PR c/19978
|
||||
* tree.h (TREE_OVERFLOW_P): New.
|
||||
* c-typeck.c (parser_build_unary_op): Warn only if result
|
||||
overflowed and operands did not.
|
||||
(parser_build_binary_op): Likewise.
|
||||
(convert_for_assignment): Remove redundant overflow_warning.
|
||||
* c-common.c (overflow_warning): Don't check or set TREE_OVERFLOW.
|
||||
|
||||
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||
|
||||
* c-typeck.c (store_init_value): Split over two lines to follow
|
||||
|
|
|
@ -920,39 +920,45 @@ constant_expression_warning (tree value)
|
|||
pedwarn ("overflow in constant expression");
|
||||
}
|
||||
|
||||
/* Print a warning if an expression had overflow in folding.
|
||||
/* Print a warning if an expression had overflow in folding and its
|
||||
operands hadn't.
|
||||
|
||||
Invoke this function on every expression that
|
||||
(1) appears in the source code, and
|
||||
(2) might be a constant expression that overflowed, and
|
||||
(2) is a constant expression that overflowed, and
|
||||
(3) is not already checked by convert_and_check;
|
||||
however, do not invoke this function on operands of explicit casts. */
|
||||
however, do not invoke this function on operands of explicit casts
|
||||
or when the expression is the result of an operator and any operand
|
||||
already overflowed. */
|
||||
|
||||
void
|
||||
overflow_warning (tree value)
|
||||
{
|
||||
if ((TREE_CODE (value) == INTEGER_CST
|
||||
|| (TREE_CODE (value) == COMPLEX_CST
|
||||
&& TREE_CODE (TREE_REALPART (value)) == INTEGER_CST))
|
||||
&& TREE_OVERFLOW (value))
|
||||
if (skip_evaluation) return;
|
||||
|
||||
switch (TREE_CODE (value))
|
||||
{
|
||||
TREE_OVERFLOW (value) = 0;
|
||||
if (skip_evaluation == 0)
|
||||
case INTEGER_CST:
|
||||
warning (OPT_Woverflow, "integer overflow in expression");
|
||||
}
|
||||
else if ((TREE_CODE (value) == REAL_CST
|
||||
|| (TREE_CODE (value) == COMPLEX_CST
|
||||
&& TREE_CODE (TREE_REALPART (value)) == REAL_CST))
|
||||
&& TREE_OVERFLOW (value))
|
||||
{
|
||||
TREE_OVERFLOW (value) = 0;
|
||||
if (skip_evaluation == 0)
|
||||
break;
|
||||
|
||||
case REAL_CST:
|
||||
warning (OPT_Woverflow, "floating point overflow in expression");
|
||||
}
|
||||
else if (TREE_CODE (value) == VECTOR_CST && TREE_OVERFLOW (value))
|
||||
{
|
||||
TREE_OVERFLOW (value) = 0;
|
||||
if (skip_evaluation == 0)
|
||||
break;
|
||||
|
||||
case VECTOR_CST:
|
||||
warning (OPT_Woverflow, "vector overflow in expression");
|
||||
break;
|
||||
|
||||
case COMPLEX_CST:
|
||||
if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST)
|
||||
warning (OPT_Woverflow, "complex integer overflow in expression");
|
||||
else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST)
|
||||
warning (OPT_Woverflow, "complex floating point overflow in expression");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2601,7 +2601,10 @@ parser_build_unary_op (enum tree_code code, struct c_expr arg)
|
|||
|
||||
result.original_code = ERROR_MARK;
|
||||
result.value = build_unary_op (code, arg.value, 0);
|
||||
|
||||
if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
|
||||
overflow_warning (result.value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2645,6 +2648,9 @@ parser_build_binary_op (enum tree_code code, struct c_expr arg1,
|
|||
warning (OPT_Wstring_literal_comparison,
|
||||
"comparison with string literal");
|
||||
|
||||
if (TREE_OVERFLOW_P (result.value)
|
||||
&& !TREE_OVERFLOW_P (arg1.value)
|
||||
&& !TREE_OVERFLOW_P (arg2.value))
|
||||
overflow_warning (result.value);
|
||||
|
||||
return result;
|
||||
|
@ -3827,10 +3833,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
|
|||
}
|
||||
|
||||
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
|
||||
{
|
||||
overflow_warning (rhs);
|
||||
return rhs;
|
||||
}
|
||||
|
||||
if (coder == VOID_TYPE)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||
|
||||
PR c/19978
|
||||
* semantics.c (finish_unary_op_expr): Warn only if result
|
||||
overflowed and operands did not.
|
||||
|
||||
2007-01-05 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* typeck.c (build_binary_op): Warn about comparing a non-weak
|
||||
|
|
|
@ -2000,7 +2000,9 @@ finish_unary_op_expr (enum tree_code code, tree expr)
|
|||
result = copy_node (result);
|
||||
TREE_NEGATED_INT (result) = 1;
|
||||
}
|
||||
if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
|
||||
overflow_warning (result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||
|
||||
PR c/19978
|
||||
* gcc.dg/multiple-overflow-warn-1.c: New.
|
||||
* gcc.dg/multiple-overflow-warn-2.c: New.
|
||||
* gcc.dg/overflow-warn-6.c: New.
|
||||
* g++.dg/warn/multiple-overflow-warn-1.C: New.
|
||||
|
||||
2007-01-05 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* gfortran.dg/array_memcpy_1.f90: New test case.
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/* PR c/19978 : Test for duplicated warnings (unary operators). */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Woverflow" } */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
int
|
||||
g (void)
|
||||
{
|
||||
return - - - - -INT_MIN; /* { dg-bogus "integer overflow in expression.*integer overflow in expression" } */
|
||||
/* { dg-warning "integer overflow in expression" "" { target *-*-* } 10 } */
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/* PR c/19978 : Test for duplicated warnings (unary operators). */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c99 -Woverflow" } */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
int
|
||||
g (void)
|
||||
{
|
||||
return - - - - -INT_MIN; /* { dg-bogus "integer overflow in expression.*integer overflow in expression" } */
|
||||
/* { dg-warning "integer overflow in expression" "" { target *-*-* } 10 } */
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/* PR c/19978 : Test for duplicated warnings (binary operators). */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c99 -Woverflow" } */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
int
|
||||
g1 (void)
|
||||
{
|
||||
return INT_MAX + 1 - INT_MAX; /* { dg-bogus "integer overflow in expression.*integer overflow in expression" } */
|
||||
/* { dg-warning "integer overflow in expression" "" { target *-*-* } 10 } */
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* Test non-constant operands in overflowed expressions. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c99 -Woverflow" } */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
int
|
||||
h1 (int x)
|
||||
{
|
||||
return x * (0 * (INT_MAX + 1)); /* { dg-warning "warning: integer overflow in expression" } */
|
||||
}
|
||||
|
||||
int
|
||||
h2 (int x)
|
||||
{
|
||||
return ((INT_MAX + 1) * 0) * x; /* { dg-warning "warning: integer overflow in expression" } */
|
||||
}
|
||||
|
|
@ -1156,6 +1156,11 @@ extern void omp_clause_range_check_failed (const tree, const char *, int,
|
|||
|
||||
#define TREE_OVERFLOW(NODE) (CST_CHECK (NODE)->base.public_flag)
|
||||
|
||||
/* TREE_OVERFLOW can only be true for EXPR of CONSTANT_CLASS_P. */
|
||||
|
||||
#define TREE_OVERFLOW_P(EXPR) \
|
||||
(CONSTANT_CLASS_P (EXPR) && TREE_OVERFLOW (EXPR))
|
||||
|
||||
/* In a VAR_DECL, FUNCTION_DECL, NAMESPACE_DECL or TYPE_DECL,
|
||||
nonzero means name is to be accessible from outside this module.
|
||||
In an IDENTIFIER_NODE, nonzero means an external declaration
|
||||
|
|
Loading…
Reference in New Issue