diff options
author | sandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-28 19:21:20 +0000 |
---|---|---|
committer | sandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-28 19:21:20 +0000 |
commit | d01f58f916ac4e68183fa9c4a92c33582f546b44 (patch) | |
tree | 34dad42b40269284ec633fd80ce8a06342ba7ea3 /gcc/c-common.c | |
parent | 5331f35a8778193583ee027a3a01b417e3284643 (diff) | |
download | gcc-d01f58f916ac4e68183fa9c4a92c33582f546b44.tar.gz |
2007-02-28 Sandra Loosemore <sandra@codesourcery.com>
* gcc/builtins.c (fold_builtin_call_list, fold_builtin_call_valist):
Delete, and replace with...
(fold_builtin_call_array): This. Update callers to use it.
* gcc/fold-const.c (fold_build_call_list): Delete, and replace with...
(fold_build_call_array): This.
(fold_build_call_list_initializer): Delete, and replace with...
(fold_build_call_array_initializer): This.
* gcc/tree.h: Update declarations to reflect above changes.
* gcc/c-typeck.c (build_function_call): Store converted arguments
in a stack-allocated array instead of building a list.
(convert_arguments): Store arguments in the array passed in as an
argument, and return the actual number of arguments.
* gcc/c-format.c: (check_function_format): Pass arguments in an
array instead of a list.
* gcc/c-common.c (check_function_nonnull): Likewise.
(check_function_sentinel): Likewise.
(check_function_arguments): Likewise.
* gcc/c-common.h: Update declarations to reflect above changes.
* gcc/cp/typeck.c (build_function_call): Store converted arguments
in a stack-allocated array instead of building a list.
(convert_arguments): Store arguments in the array passed in as an
argument, and return the actual number of arguments.
* gcc/cp/call.c (build_call): Delete, and replace with...
(build_call_n, build_call_a): New.
(build_op_delete_call): Rewrite to avoid constructing argument lists.
(build_over_call): Store converted arguments in a stack-allocated
array instead of building a list.
(build_cxx_call): Pass arguments in an array instead of as a list.
(build_java_interface_fn_ref): Rewrite to avoid constructing
argument lists.
* gcc/cp/tree.h: Update declarations to reflect above changes.
* gcc/cp/method.c (use_thunk): Use a stack-allocated array to hold
the arguments instead of a list.
* gcc/cp/rtti.c (throw_bad_cast): Update call to cxx_call.
(throw_bad_typeid): Likewise.
(build_dynamic_cast_1): Likewise.
* gcc/cp/init.c (build_builtin_delete_call): Use build_call_n.
* gcc/cp/decl.c (expand_static_init): Likewise.
* gcc/cp/except.c (cp_protect_cleanup_actions): Likewise.
* gcc/cp/cp-gimplify.c (genericize_eh_spec_block): Likewise.
(gimplify_must_not_throw_expr): Likewise.
(cxx_omp_apply_fn): Use build_call_a.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122411 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 123 |
1 files changed, 54 insertions, 69 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 8d321a292f5..6ea3800be8d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -554,7 +554,7 @@ static tree handle_warn_unused_result_attribute (tree *, tree, tree, int, bool *); static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); -static void check_function_nonnull (tree, tree); +static void check_function_nonnull (tree, int, tree *); static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT); static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *); @@ -5710,13 +5710,15 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), } /* Check the argument list of a function call for null in argument slots - that are marked as requiring a non-null pointer argument. */ + that are marked as requiring a non-null pointer argument. The NARGS + arguments are passed in the array ARGARRAY. +*/ static void -check_function_nonnull (tree attrs, tree params) +check_function_nonnull (tree attrs, int nargs, tree *argarray) { - tree a, args, param; - int param_num; + tree a, args; + int i; for (a = attrs; a; a = TREE_CHAIN (a)) { @@ -5728,85 +5730,65 @@ check_function_nonnull (tree attrs, tree params) should check for non-null, do it. If the attribute has no args, then every pointer argument is checked (in which case the check for pointer type is done in check_nonnull_arg). */ - for (param = params, param_num = 1; ; - param_num++, param = TREE_CHAIN (param)) + for (i = 0; i < nargs; i++) { - if (!param) - break; - if (!args || nonnull_check_p (args, param_num)) + if (!args || nonnull_check_p (args, i + 1)) check_function_arguments_recurse (check_nonnull_arg, NULL, - TREE_VALUE (param), - param_num); + argarray[i], + i + 1); } } } } /* Check that the Nth argument of a function call (counting backwards - from the end) is a (pointer)0. */ + from the end) is a (pointer)0. The NARGS arguments are passed in the + array ARGARRAY. */ static void -check_function_sentinel (tree attrs, tree params, tree typelist) +check_function_sentinel (tree attrs, int nargs, tree *argarray, tree typelist) { tree attr = lookup_attribute ("sentinel", attrs); if (attr) { - /* Skip over the named arguments. */ - while (typelist && params) - { - typelist = TREE_CHAIN (typelist); - params = TREE_CHAIN (params); - } + int len = 0; + int pos = 0; + tree sentinel; - if (typelist || !params) - warning (OPT_Wformat, - "not enough variable arguments to fit a sentinel"); - else + /* Skip over the named arguments. */ + while (typelist && len < nargs) { - tree sentinel, end; - unsigned pos = 0; - - if (TREE_VALUE (attr)) - { - tree p = TREE_VALUE (TREE_VALUE (attr)); - pos = TREE_INT_CST_LOW (p); - } - - sentinel = end = params; - - /* Advance `end' ahead of `sentinel' by `pos' positions. */ - while (pos > 0 && TREE_CHAIN (end)) - { - pos--; - end = TREE_CHAIN (end); - } - if (pos > 0) - { - warning (OPT_Wformat, - "not enough variable arguments to fit a sentinel"); - return; - } + typelist = TREE_CHAIN (typelist); + len++; + } - /* Now advance both until we find the last parameter. */ - while (TREE_CHAIN (end)) - { - end = TREE_CHAIN (end); - sentinel = TREE_CHAIN (sentinel); - } + if (TREE_VALUE (attr)) + { + tree p = TREE_VALUE (TREE_VALUE (attr)); + pos = TREE_INT_CST_LOW (p); + } - /* Validate the sentinel. */ - if ((!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel))) - || !integer_zerop (TREE_VALUE (sentinel))) - /* Although __null (in C++) is only an integer we allow it - nevertheless, as we are guaranteed that it's exactly - as wide as a pointer, and we don't want to force - users to cast the NULL they have written there. - We warn with -Wstrict-null-sentinel, though. */ - && (warn_strict_null_sentinel - || null_node != TREE_VALUE (sentinel))) - warning (OPT_Wformat, "missing sentinel in function call"); + /* The sentinel must be one of the varargs, i.e. + in position >= the number of fixed arguments. */ + if ((nargs - 1 - pos) < len) + { + warning (OPT_Wformat, + "not enough variable arguments to fit a sentinel"); + return; } + + /* Validate the sentinel. */ + sentinel = argarray[nargs - 1 - pos]; + if ((!POINTER_TYPE_P (TREE_TYPE (sentinel)) + || !integer_zerop (sentinel)) + /* Although __null (in C++) is only an integer we allow it + nevertheless, as we are guaranteed that it's exactly + as wide as a pointer, and we don't want to force + users to cast the NULL they have written there. + We warn with -Wstrict-null-sentinel, though. */ + && (warn_strict_null_sentinel || null_node != sentinel)) + warning (OPT_Wformat, "missing sentinel in function call"); } } @@ -5996,23 +5978,26 @@ handle_sentinel_attribute (tree *node, tree name, tree args, return NULL_TREE; } -/* Check for valid arguments being passed to a function. */ +/* Check for valid arguments being passed to a function. + ATTRS is a list of attributes. There are NARGS arguments in the array + ARGARRAY. TYPELIST is the list of argument types for the function. + */ void -check_function_arguments (tree attrs, tree params, tree typelist) +check_function_arguments (tree attrs, int nargs, tree *argarray, tree typelist) { /* Check for null being passed in a pointer argument that must be non-null. We also need to do this if format checking is enabled. */ if (warn_nonnull) - check_function_nonnull (attrs, params); + check_function_nonnull (attrs, nargs, argarray); /* Check for errors in format strings. */ if (warn_format || warn_missing_format_attribute) - check_function_format (attrs, params); + check_function_format (attrs, nargs, argarray); if (warn_format) - check_function_sentinel (attrs, params, typelist); + check_function_sentinel (attrs, nargs, argarray, typelist); } /* Generic argument checking recursion routine. PARAM is the argument to |