OSDN Git Service

PR 22429
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Nov 2005 21:44:17 +0000 (21:44 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Nov 2005 21:44:17 +0000 (21:44 +0000)
        * fold-const.c (build_range_check): Use unsigned when signed
        overflow is undefined also.  If etype is subtype, make sure that
        the subtraction is in the supertype.

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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/gcc.c-torture/execute/pr22429.c [new file with mode: 0644]

index f2b2f54..64a4297 100644 (file)
@@ -1,3 +1,10 @@
+2005-11-02  Andrew Pinski  <pinskia@physics.uc.edu>
+
+       PR 22429
+       * fold-const.c (build_range_check): Use unsigned when signed
+       overflow is undefined also.  If etype is subtype, make sure that
+       the subtraction is in the supertype.
+
 2005-11-02  Richard Henderson  <rth@redhat.com>
 
        PR target/24178
 2005-11-02  Richard Henderson  <rth@redhat.com>
 
        PR target/24178
index 16e7eb3..6f829ad 100644 (file)
@@ -4014,7 +4014,8 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
     }
 
   value = const_binop (MINUS_EXPR, high, low, 0);
     }
 
   value = const_binop (MINUS_EXPR, high, low, 0);
-  if (value != 0 && TREE_OVERFLOW (value) && ! TYPE_UNSIGNED (etype))
+  if (value != 0 && (!flag_wrapv || TREE_OVERFLOW (value))
+      && ! TYPE_UNSIGNED (etype))
     {
       tree utype, minv, maxv;
 
     {
       tree utype, minv, maxv;
 
@@ -4025,6 +4026,11 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
        case INTEGER_TYPE:
        case ENUMERAL_TYPE:
        case CHAR_TYPE:
        case INTEGER_TYPE:
        case ENUMERAL_TYPE:
        case CHAR_TYPE:
+         /* There is no requirement that LOW be within the range of ETYPE
+            if the latter is a subtype.  It must, however, be within the base
+            type of ETYPE.  So be sure we do the subtraction in that type.  */
+         if (TREE_TYPE (etype))
+           etype = TREE_TYPE (etype);
          utype = lang_hooks.types.unsigned_type (etype);
          maxv = fold_convert (utype, TYPE_MAX_VALUE (etype));
          maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1,
          utype = lang_hooks.types.unsigned_type (etype);
          maxv = fold_convert (utype, TYPE_MAX_VALUE (etype));
          maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1,
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr22429.c b/gcc/testsuite/gcc.c-torture/execute/pr22429.c
new file mode 100644 (file)
index 0000000..aa55b6e
--- /dev/null
@@ -0,0 +1,17 @@
+extern void abort (void);
+
+#define N      (1 << (sizeof(int) * __CHAR_BIT__ - 2))
+
+int f(int n)
+{
+  if (-N <= n && n <= N-1)
+    return 1;
+  return 0;
+}
+
+int main ()
+{
+  if (f (N))
+    abort ();
+  return 0;
+}