diff options
author | Diego Novillo <dnovillo@redhat.com> | 2005-06-02 18:26:07 +0000 |
---|---|---|
committer | Diego Novillo <dnovillo@gcc.gnu.org> | 2005-06-02 14:26:07 -0400 |
commit | 462508dd7e13be8c480f49a684d31b19ac972794 (patch) | |
tree | c4ac2e10f438528f084722813917ea4a3f919688 /gcc/tree-vrp.c | |
parent | 423ceeadf1fe2c682f75e11e6d860bcdea1879fa (diff) | |
download | gcc-462508dd7e13be8c480f49a684d31b19ac972794.zip gcc-462508dd7e13be8c480f49a684d31b19ac972794.tar.gz gcc-462508dd7e13be8c480f49a684d31b19ac972794.tar.bz2 |
re PR tree-optimization/21582 ((optimisation) VRP pass could/should use non-null function attribute)
PR 21582
* tree-vrp.c (nonnull_arg_p): New.
(get_value_range): Call it.
testsuite/ChangeLog
PR 21582
* gcc.dg/tree-ssa/pr21582.c: New test.
From-SVN: r100505
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f712cb3..e6087a5 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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; } |