OSDN Git Service

2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 5 Jan 2007 21:57:01 +0000 (21:57 +0000)
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 5 Jan 2007 21:57:01 +0000 (21:57 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120505 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-common.c
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/multiple-overflow-warn-1.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/multiple-overflow-warn-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/multiple-overflow-warn-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/overflow-warn-6.c [new file with mode: 0644]
gcc/tree.h

index 5838242..7b0bbd5 100644 (file)
@@ -1,5 +1,15 @@
 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
        the GNU coding style.
 
index 1794bd8..8fb9541 100644 (file)
@@ -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))
-    {
-      TREE_OVERFLOW (value) = 0;
-      if (skip_evaluation == 0)
-       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)
-       warning (OPT_Woverflow, "floating point overflow in expression");
-    }
-  else if (TREE_CODE (value) == VECTOR_CST && TREE_OVERFLOW (value))
+  if (skip_evaluation) return;
+
+  switch (TREE_CODE (value))
     {
-      TREE_OVERFLOW (value) = 0;
-      if (skip_evaluation == 0)
-       warning (OPT_Woverflow, "vector overflow in expression");
+    case INTEGER_CST:
+      warning (OPT_Woverflow, "integer overflow in expression");
+      break;
+      
+    case REAL_CST:
+      warning (OPT_Woverflow, "floating point overflow in expression");
+      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;
     }
 }
 
index e8e2f69..8119e7f 100644 (file)
@@ -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);
-  overflow_warning (result.value);
+  
+  if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
+    overflow_warning (result.value);
+
   return result;
 }
 
@@ -2645,7 +2648,10 @@ parser_build_binary_op (enum tree_code code, struct c_expr arg1,
     warning (OPT_Wstring_literal_comparison,
             "comparison with string literal");
 
-  overflow_warning (result.value);
+  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;
-    }
+    return rhs;
 
   if (coder == VOID_TYPE)
     {
index 1f7945d..3c35e58 100644 (file)
@@ -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
index 5b8906e..538f7b4 100644 (file)
@@ -2000,7 +2000,9 @@ finish_unary_op_expr (enum tree_code code, tree expr)
       result = copy_node (result);
       TREE_NEGATED_INT (result) = 1;
     }
-  overflow_warning (result);
+  if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
+    overflow_warning (result);
+
   return result;
 }
 
index 1890965..5372427 100644 (file)
@@ -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.
diff --git a/gcc/testsuite/g++.dg/warn/multiple-overflow-warn-1.C b/gcc/testsuite/g++.dg/warn/multiple-overflow-warn-1.C
new file mode 100644 (file)
index 0000000..4899302
--- /dev/null
@@ -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 } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/multiple-overflow-warn-1.c b/gcc/testsuite/gcc.dg/multiple-overflow-warn-1.c
new file mode 100644 (file)
index 0000000..be7b3b8
--- /dev/null
@@ -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 } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/multiple-overflow-warn-2.c b/gcc/testsuite/gcc.dg/multiple-overflow-warn-2.c
new file mode 100644 (file)
index 0000000..8a4e9e5
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/gcc.dg/overflow-warn-6.c b/gcc/testsuite/gcc.dg/overflow-warn-6.c
new file mode 100644 (file)
index 0000000..da8cb01
--- /dev/null
@@ -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" } */
+}
+
index 3a22628..9f2d707 100644 (file)
@@ -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