http://gcc.gnu.org/ml/gcc-patches/2008-02/msg01094.html
authorDiego Novillo <dnovillo@google.com>
Sun, 24 Feb 2008 16:40:32 +0000 (11:40 -0500)
committerDiego Novillo <dnovillo@gcc.gnu.org>
Sun, 24 Feb 2008 16:40:32 +0000 (11:40 -0500)
PR 33738
* tree-vrp.c (vrp_evaluate_conditional): With
-Wtype-limits, emit a warning when comparing against a
constant outside the natural range of OP0's type.
* c.opt (Wtype-limits): Move ...
* common.opt (Wtype-limits): ... here.

testsuite/ChangeLog

PR 33738
* g++.dg/warn/pr33738.C: New.

From-SVN: r132591

gcc/ChangeLog
gcc/c.opt
gcc/common.opt
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/pr33738.C [new file with mode: 0644]
gcc/tree-vrp.c

index 0d159ee770fd7314308c08b9b9c0d14656378725..989cada2eed8947cce1c74f1d5726994d95ff9b3 100644 (file)
@@ -1,3 +1,14 @@
+2008-02-24  Diego Novillo  <dnovillo@google.com>
+
+       http://gcc.gnu.org/ml/gcc-patches/2008-02/msg01094.html
+
+       PR 33738
+       * tree-vrp.c (vrp_evaluate_conditional): With
+       -Wtype-limits, emit a warning when comparing against a
+       constant outside the natural range of OP0's type.
+       * c.opt (Wtype-limits): Move ...
+       * common.opt (Wtype-limits): ... here.
+
 2008-02-24  Edmar Wienskoski  <edmar@freescale.com>
 
        * config.gcc (powerpc*-*-*): Add new cores e300c2 and e300c3.
index 94f0398419d3095ca1d89ff6ae508e16d1e949a0..72165b96660cf352ad5de8c043f4bb4b9747f76e 100644 (file)
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -123,10 +123,6 @@ Wall
 C ObjC C++ ObjC++ Warning
 Enable most warning messages
 
-Wtype-limits
-C ObjC C++ ObjC++ Var(warn_type_limits) Init(-1) Warning
-Warn if a comparison is always true or always false due to the limited range of the data type
-
 Wassign-intercept
 ObjC ObjC++ Var(warn_assign_intercept) Warning
 Warn whenever an Objective-C assignment is being intercepted by the garbage collector
index ea48ba7d760fc2b00667ceb209ba872cab04e9e8..3a64d2a1a83daf0f1df99a368f65f60051ccc51d 100644 (file)
@@ -193,6 +193,10 @@ Wsystem-headers
 Common Var(warn_system_headers) Warning
 Do not suppress warnings from system headers
 
+Wtype-limits
+Common Var(warn_type_limits) Init(-1) Warning
+Warn if a comparison is always true or always false due to the limited range of the data type
+
 Wuninitialized
 Common Var(warn_uninitialized) Warning
 Warn about uninitialized automatic variables
index 0a0259b2dfff2cd632d946ca3391cc05c1f09d1a..6fc79d4130f54c8910780bf4cf714c11efc522b5 100644 (file)
@@ -1,3 +1,10 @@
+2008-02-24  Diego Novillo  <dnovillo@google.com>
+
+       http://gcc.gnu.org/ml/gcc-patches/2008-02/msg01094.html
+
+       PR 33738
+       * g++.dg/warn/pr33738.C: New.
+
 2008-02-24  Richard Sandiford  <rsandifo@nildram.co.uk>
 
        * gcc.c-torture/execute/nest-align-1.x: New file.
diff --git a/gcc/testsuite/g++.dg/warn/pr33738.C b/gcc/testsuite/g++.dg/warn/pr33738.C
new file mode 100644 (file)
index 0000000..8847b6e
--- /dev/null
@@ -0,0 +1,26 @@
+// { dg-do run }
+// { dg-options "-O2 -Wtype-limits" }
+extern void link_error (void);
+
+enum Alpha {
+ ZERO = 0, ONE, TWO, THREE
+};
+
+Alpha a2;
+
+int m1 = -1;
+int GetM1() {
+ return m1;
+}
+
+int main() {
+ a2 = static_cast<Alpha>(GetM1());
+ if (a2 == -1) {       // { dg-warning "always false due" }
+    link_error ();
+ }
+ if (-1 == a2) {       // { dg-warning "always false due" }
+    link_error ();
+ }
+ return 0;
+}
+
index f9615d1f815e01ae4e45fe32368e358564cb2b62..eaeaea08902c0c9f71ec629c2964d83cbdc7f739 100644 (file)
@@ -5077,6 +5077,48 @@ vrp_evaluate_conditional (tree cond, tree stmt)
        }
     }
 
+  if (warn_type_limits
+      && ret
+      && TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison)
+    {
+      /* If the comparison is being folded and the operand on the LHS
+        is being compared against a constant value that is outside of
+        the natural range of OP0's type, then the predicate will
+        always fold regardless of the value of OP0.  If -Wtype-limits
+        was specified, emit a warning.  */
+      const char *warnmsg = NULL;
+      tree op0 = TREE_OPERAND (cond, 0);
+      tree op1 = TREE_OPERAND (cond, 1);
+      tree type = TREE_TYPE (op0);
+      value_range_t *vr0 = get_value_range (op0);
+
+      if (vr0->type != VR_VARYING
+         && INTEGRAL_TYPE_P (type)
+         && vrp_val_is_min (vr0->min)
+         && vrp_val_is_max (vr0->max)
+         && is_gimple_min_invariant (op1))
+       {
+         if (integer_zerop (ret))
+           warnmsg = G_("comparison always false due to limited range of "
+                        "data type");
+         else
+           warnmsg = G_("comparison always true due to limited range of "
+                        "data type");
+       }
+
+      if (warnmsg)
+       {
+         location_t locus;
+
+         if (!EXPR_HAS_LOCATION (stmt))
+           locus = input_location;
+         else
+           locus = EXPR_LOCATION (stmt);
+
+         warning (OPT_Wtype_limits, "%H%s", &locus, warnmsg);
+       }
+    }
+
   return ret;
 }