From 61631574d437729dc9b0648d83b50bc6faabf9d2 Mon Sep 17 00:00:00 2001
From: rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 2 Nov 2005 21:44:17 +0000
Subject: [PATCH]         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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@106400 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                                 |  7 +++++++
 gcc/fold-const.c                              |  8 +++++++-
 gcc/testsuite/gcc.c-torture/execute/pr22429.c | 17 +++++++++++++++++
 3 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr22429.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f2b2f54e3772..64a4297da81a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 16e7eb30b307..6f829adfa771 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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);
-  if (value != 0 && TREE_OVERFLOW (value) && ! TYPE_UNSIGNED (etype))
+  if (value != 0 && (!flag_wrapv || TREE_OVERFLOW (value))
+      && ! TYPE_UNSIGNED (etype))
     {
       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:
+	  /* 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,
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr22429.c b/gcc/testsuite/gcc.c-torture/execute/pr22429.c
new file mode 100644
index 000000000000..aa55b6e88acc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr22429.c
@@ -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;
+}
-- 
GitLab