diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 63 |
1 files changed, 63 insertions, 0 deletions
@@ -13571,4 +13571,67 @@ verify_type (const_tree t) } } + +/* Return true if ARG is marked with the nonnull attribute in the + current function signature. */ + +bool +nonnull_arg_p (const_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))); + + /* The static chain decl is always non null. */ + if (arg == cfun->static_chain_decl) + return true; + + /* THIS argument of method is always non-NULL. */ + if (TREE_CODE (TREE_TYPE (cfun->decl)) == METHOD_TYPE + && arg == DECL_ARGUMENTS (cfun->decl) + && flag_delete_null_pointer_checks) + return true; + + /* Values passed by reference are always non-NULL. */ + if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE + && flag_delete_null_pointer_checks) + return true; + + fntype = TREE_TYPE (cfun->decl); + for (attrs = TYPE_ATTRIBUTES (fntype); attrs; attrs = TREE_CHAIN (attrs)) + { + attrs = lookup_attribute ("nonnull", attrs); + + /* 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 (cfun->decl); + t; + t = DECL_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; +} + + #include "gt-tree.h" |