diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -14313,6 +14313,56 @@ combined_fn_name (combined_fn fn) return internal_fn_name (as_internal_fn (fn)); } +/* Return a bitmap with a bit set corresponding to each argument in + a function call type FNTYPE declared with attribute nonnull, + or null if none of the function's argument are nonnull. The caller + must free the bitmap. */ + +bitmap +get_nonnull_args (const_tree fntype) +{ + if (fntype == NULL_TREE) + return NULL; + + tree attrs = TYPE_ATTRIBUTES (fntype); + if (!attrs) + return NULL; + + bitmap argmap = NULL; + + /* A function declaration can specify multiple attribute nonnull, + each with zero or more arguments. The loop below creates a bitmap + representing a union of all the arguments. An empty (but non-null) + bitmap means that all arguments have been declaraed nonnull. */ + for ( ; attrs; attrs = TREE_CHAIN (attrs)) + { + attrs = lookup_attribute ("nonnull", attrs); + if (!attrs) + break; + + if (!argmap) + argmap = BITMAP_ALLOC (NULL); + + if (!TREE_VALUE (attrs)) + { + /* Clear the bitmap in case a previous attribute nonnull + set it and this one overrides it for all arguments. */ + bitmap_clear (argmap); + return argmap; + } + + /* Iterate over the indices of the format arguments declared nonnull + and set a bit for each. */ + for (tree idx = TREE_VALUE (attrs); idx; idx = TREE_CHAIN (idx)) + { + unsigned int val = TREE_INT_CST_LOW (TREE_VALUE (idx)) - 1; + bitmap_set_bit (argmap, val); + } + } + + return argmap; +} + #if CHECKING_P namespace selftest { |