https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92539

Jeffrey A. Law <law at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at gcc dot gnu.org

--- Comment #12 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Just to save it for the future.  I think this patch I've got lying around
implements the idea in c#6.

diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 3ccb77d28be..cc753e79a8a 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -325,6 +325,34 @@ simplify_using_ranges::fold_cond_with_ops (enum tree_code
code,
       if (res == range_false (type))
        return boolean_false_node;
     }
+
+  /* If we're comparing pointers and one of the pointers is
+     not a valid pointer (say &MEM <const char> [(void *)"aa" + 4B)
+     return true for EQ and false for NE.  */
+  if ((code == EQ_EXPR || code == NE_EXPR)
+      && POINTER_TYPE_P (type)
+      && TREE_CODE (op1) == ADDR_EXPR
+      && TREE_CODE (TREE_OPERAND (op1, 0)) == MEM_REF)
+    {
+      tree mem_ref = TREE_OPERAND (op1, 0);
+      if (TREE_CODE (TREE_OPERAND (mem_ref, 0)) == ADDR_EXPR)
+       {
+         tree addr_expr = TREE_OPERAND (mem_ref, 0);
+         if (TREE_CODE (TREE_OPERAND (addr_expr, 0)) == STRING_CST)
+           {
+             tree string = TREE_OPERAND (addr_expr, 0);
+
+             if (TREE_CODE (TREE_OPERAND (mem_ref, 1)) == INTEGER_CST)
+               {
+                 HOST_WIDE_INT len = TREE_STRING_LENGTH (string);
+                 HOST_WIDE_INT offset = tree_to_uhwi (TREE_OPERAND (mem_ref,
1));
+                 if (offset > len)
+                   return code == EQ_EXPR ? boolean_false_node :
boolean_true_node;
+               }
+           }
+       }
+    }
+
   return NULL;
 }

Reply via email to