OSDN Git Service

PR 21582
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Jun 2005 18:26:07 +0000 (18:26 +0000)
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Jun 2005 18:26:07 +0000 (18:26 +0000)
* tree-vrp.c (nonnull_arg_p): New.
(get_value_range): Call it.

testsuite/ChangeLog

PR 21582
* gcc.dg/tree-ssa/pr21582.c: New test.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr21582.c [new file with mode: 0644]
gcc/tree-vrp.c

index fa38950..5182b34 100644 (file)
@@ -1,3 +1,9 @@
+2005-06-02  Diego Novillo  <dnovillo@redhat.com>
+
+       PR 21582
+       * tree-vrp.c (nonnull_arg_p): New.
+       (get_value_range): Call it.
+
 2005-06-02  Eric Christopher  <echristo@redhat.com>
 
        * config/mips/mips.h (processor_type): Remove PROCESSOR_DEFAULT,
index 224ed08..5d508e5 100644 (file)
@@ -1,3 +1,8 @@
+2005-06-02  Diego Novillo  <dnovillo@redhat.com>
+
+       PR 21582
+       * gcc.dg/tree-ssa/pr21582.c: New test.
+
 2005-06-02  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/21280
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21582.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21582.c
new file mode 100644 (file)
index 0000000..eee5d94
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do link }  */
+/* { dg-options "-O2 -fdump-tree-vrp" }  */
+
+static inline void do_thing(char *s, int *p, char *q)
+{
+       /* This should be folded away.  */
+        if (s == 0 || q == 0)
+                link_error ();
+
+       /* This should not be folded as 'p' is not marked nonnull.  */
+       if (p)
+               *p = 3;
+}
+
+void __attribute__((nonnull (1, 3))) do_other_thing(char *s, int *p, char *q)
+{
+        do_thing(s, p, q);
+}
+
+int i;
+
+main()
+{
+  do_other_thing ("xxx", &i, "yyy");
+}
+
+/* { dg-final { scan-tree-dump-times "Folding predicate p_.*" 0 "vrp" } } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */
index f712cb3..e6087a5 100644 (file)
@@ -165,6 +165,50 @@ expr_computes_nonzero (tree expr)
 }
 
 
+/* Return true if ARG is marked with the nonnull attribute in the
+   current function signature.  */
+
+static bool
+nonnull_arg_p (tree arg)
+{
+  tree t, attrs, fntype;
+  unsigned HOST_WIDE_INT arg_num;
+
+  gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (arg)));
+
+  fntype = TREE_TYPE (current_function_decl);
+  attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype));
+
+  /* If "nonnull" wasn't specified, we know nothing about the argument.  */
+  if (attrs == NULL_TREE)
+    return false;
+
+  /* If "nonnull" applies to all the arguments, then ARG is non-null.  */
+  if (TREE_VALUE (attrs) == NULL_TREE)
+    return true;
+
+  /* Get the position number for ARG in the function signature.  */
+  for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
+       t;
+       t = TREE_CHAIN (t), arg_num++)
+    {
+      if (t == arg)
+       break;
+    }
+
+  gcc_assert (t == arg);
+
+  /* Now see if ARG_NUM is mentioned in the nonnull list.  */
+  for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
+    {
+      if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
+       return true;
+    }
+
+  return false;
+}
+
+
 /* Set value range VR to {T, MIN, MAX, EQUIV}.  */
 
 static void
@@ -291,7 +335,17 @@ get_value_range (tree var)
      in VAR's type.  */
   sym = SSA_NAME_VAR (var);
   if (var == var_ann (sym)->default_def)
-    set_value_range_to_varying (vr);
+    {
+      /* Try to use the "nonnull" attribute to create ~[0, 0]
+        anti-ranges for pointers.  Note that this is only valid with
+        default definitions of PARM_DECLs.  */
+      if (TREE_CODE (sym) == PARM_DECL
+         && POINTER_TYPE_P (TREE_TYPE (sym))
+         && nonnull_arg_p (sym))
+       set_value_range_to_nonnull (vr, TREE_TYPE (sym));
+      else
+       set_value_range_to_varying (vr);
+    }
 
   return vr;
 }