summaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorsandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-28 19:21:20 +0000
committersandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>2007-02-28 19:21:20 +0000
commitd01f58f916ac4e68183fa9c4a92c33582f546b44 (patch)
tree34dad42b40269284ec633fd80ce8a06342ba7ea3 /gcc/c-common.c
parent5331f35a8778193583ee027a3a01b417e3284643 (diff)
downloadgcc-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.c123
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