builtins.c (fold_builtin_call_list, [...]): Delete, and replace with...
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. From-SVN: r122411
This commit is contained in:
parent
76bf4853ce
commit
94a0dd7b59
|
@ -1,3 +1,25 @@
|
||||||
|
2007-02-28 Sandra Loosemore <sandra@codesourcery.com>
|
||||||
|
|
||||||
|
* builtins.c (fold_builtin_call_list, fold_builtin_call_valist):
|
||||||
|
Delete, and replace with...
|
||||||
|
(fold_builtin_call_array): This. Update callers to use it.
|
||||||
|
* 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.
|
||||||
|
* tree.h: Update declarations to reflect above changes.
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
* c-format.c: (check_function_format): Pass arguments in an
|
||||||
|
array instead of a list.
|
||||||
|
* c-common.c (check_function_nonnull): Likewise.
|
||||||
|
(check_function_sentinel): Likewise.
|
||||||
|
(check_function_arguments): Likewise.
|
||||||
|
* c-common.h: Update declarations to reflect above changes.
|
||||||
|
|
||||||
2007-02-28 Jan Hubicka <jh@suse.cz>
|
2007-02-28 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
* predict.def (PRED_TREE_EARLY_RETURN, PRED_CONST_RETURN,
|
* predict.def (PRED_TREE_EARLY_RETURN, PRED_CONST_RETURN,
|
||||||
|
|
|
@ -10124,56 +10124,13 @@ build_function_call_expr (tree fndecl, tree arglist)
|
||||||
{
|
{
|
||||||
tree fntype = TREE_TYPE (fndecl);
|
tree fntype = TREE_TYPE (fndecl);
|
||||||
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
|
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
|
||||||
return fold_builtin_call_list (TREE_TYPE (fntype), fn, arglist);
|
int n = list_length (arglist);
|
||||||
}
|
tree *argarray = (tree *) alloca (n * sizeof (tree));
|
||||||
|
int i;
|
||||||
/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
|
|
||||||
ARGLIST is a TREE_LIST of arguments. */
|
for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
|
||||||
|
argarray[i] = TREE_VALUE (arglist);
|
||||||
tree
|
return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
|
||||||
fold_builtin_call_list (tree type, tree fn, tree arglist)
|
|
||||||
{
|
|
||||||
tree ret = NULL_TREE;
|
|
||||||
if (TREE_CODE (fn) == ADDR_EXPR)
|
|
||||||
{
|
|
||||||
tree fndecl = TREE_OPERAND (fn, 0);
|
|
||||||
if (TREE_CODE (fndecl) == FUNCTION_DECL
|
|
||||||
&& DECL_BUILT_IN (fndecl))
|
|
||||||
{
|
|
||||||
/* FIXME: Don't use a list in this interface. */
|
|
||||||
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
|
|
||||||
{
|
|
||||||
ret = targetm.fold_builtin (fndecl, arglist, false);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tree tail = arglist;
|
|
||||||
tree args[MAX_ARGS_TO_FOLD_BUILTIN];
|
|
||||||
int nargs;
|
|
||||||
tree exp;
|
|
||||||
|
|
||||||
for (nargs = 0; nargs < MAX_ARGS_TO_FOLD_BUILTIN; nargs++)
|
|
||||||
{
|
|
||||||
if (!tail)
|
|
||||||
break;
|
|
||||||
args[nargs] = TREE_VALUE (tail);
|
|
||||||
tail = TREE_CHAIN (tail);
|
|
||||||
}
|
|
||||||
if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
|
|
||||||
{
|
|
||||||
ret = fold_builtin_n (fndecl, args, nargs, false);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
exp = build_call_list (type, fn, arglist);
|
|
||||||
ret = fold_builtin_varargs (fndecl, exp, false);
|
|
||||||
return ret ? ret : exp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return build_call_list (type, fn, arglist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Conveniently construct a function call expression. FNDECL names the
|
/* Conveniently construct a function call expression. FNDECL names the
|
||||||
|
@ -10184,24 +10141,26 @@ tree
|
||||||
build_call_expr (tree fndecl, int n, ...)
|
build_call_expr (tree fndecl, int n, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
tree ret;
|
|
||||||
tree fntype = TREE_TYPE (fndecl);
|
tree fntype = TREE_TYPE (fndecl);
|
||||||
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
|
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
|
||||||
|
tree *argarray = (tree *) alloca (n * sizeof (tree));
|
||||||
|
int i;
|
||||||
|
|
||||||
va_start (ap, n);
|
va_start (ap, n);
|
||||||
ret = fold_builtin_call_valist (TREE_TYPE (fntype), fn, n, ap);
|
for (i = 0; i < n; i++)
|
||||||
|
argarray[i] = va_arg (ap, tree);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
return ret;
|
return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
|
/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
|
||||||
N arguments are passed in the va_list AP. */
|
N arguments are passed in the array ARGARRAY. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
fold_builtin_call_valist (tree type,
|
fold_builtin_call_array (tree type,
|
||||||
tree fn,
|
tree fn,
|
||||||
int n,
|
int n,
|
||||||
va_list ap)
|
tree *argarray)
|
||||||
{
|
{
|
||||||
tree ret = NULL_TREE;
|
tree ret = NULL_TREE;
|
||||||
int i;
|
int i;
|
||||||
|
@ -10216,15 +10175,8 @@ fold_builtin_call_valist (tree type,
|
||||||
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
|
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
|
||||||
{
|
{
|
||||||
tree arglist = NULL_TREE;
|
tree arglist = NULL_TREE;
|
||||||
va_list ap0;
|
for (i = n - 1; i >= 0; i--)
|
||||||
va_copy (ap0, ap);
|
arglist = tree_cons (NULL_TREE, argarray[i], arglist);
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
tree arg = va_arg (ap0, tree);
|
|
||||||
arglist = tree_cons (NULL_TREE, arg, arglist);
|
|
||||||
}
|
|
||||||
va_end (ap0);
|
|
||||||
arglist = nreverse (arglist);
|
|
||||||
ret = targetm.fold_builtin (fndecl, arglist, false);
|
ret = targetm.fold_builtin (fndecl, arglist, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -10233,25 +10185,19 @@ fold_builtin_call_valist (tree type,
|
||||||
{
|
{
|
||||||
/* First try the transformations that don't require consing up
|
/* First try the transformations that don't require consing up
|
||||||
an exp. */
|
an exp. */
|
||||||
tree args[MAX_ARGS_TO_FOLD_BUILTIN];
|
ret = fold_builtin_n (fndecl, argarray, n, false);
|
||||||
va_list ap0;
|
|
||||||
va_copy (ap0, ap);
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
args[i] = va_arg (ap0, tree);
|
|
||||||
va_end (ap0);
|
|
||||||
ret = fold_builtin_n (fndecl, args, n, false);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we got this far, we need to build an exp. */
|
/* If we got this far, we need to build an exp. */
|
||||||
exp = build_call_valist (type, fn, n, ap);
|
exp = build_call_array (type, fn, n, argarray);
|
||||||
ret = fold_builtin_varargs (fndecl, exp, false);
|
ret = fold_builtin_varargs (fndecl, exp, false);
|
||||||
return ret ? ret : exp;
|
return ret ? ret : exp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return build_call_valist (type, fn, n, ap);
|
return build_call_array (type, fn, n, argarray);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct a new CALL_EXPR using the tail of the argument list of EXP
|
/* Construct a new CALL_EXPR using the tail of the argument list of EXP
|
||||||
|
|
127
gcc/c-common.c
127
gcc/c-common.c
|
@ -554,7 +554,7 @@ static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
|
||||||
bool *);
|
bool *);
|
||||||
static tree handle_sentinel_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 void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
|
||||||
static bool nonnull_check_p (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 *);
|
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
|
/* 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
|
static void
|
||||||
check_function_nonnull (tree attrs, tree params)
|
check_function_nonnull (tree attrs, int nargs, tree *argarray)
|
||||||
{
|
{
|
||||||
tree a, args, param;
|
tree a, args;
|
||||||
int param_num;
|
int i;
|
||||||
|
|
||||||
for (a = attrs; a; a = TREE_CHAIN (a))
|
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,
|
should check for non-null, do it. If the attribute has no args,
|
||||||
then every pointer argument is checked (in which case the check
|
then every pointer argument is checked (in which case the check
|
||||||
for pointer type is done in check_nonnull_arg). */
|
for pointer type is done in check_nonnull_arg). */
|
||||||
for (param = params, param_num = 1; ;
|
for (i = 0; i < nargs; i++)
|
||||||
param_num++, param = TREE_CHAIN (param))
|
|
||||||
{
|
{
|
||||||
if (!param)
|
if (!args || nonnull_check_p (args, i + 1))
|
||||||
break;
|
|
||||||
if (!args || nonnull_check_p (args, param_num))
|
|
||||||
check_function_arguments_recurse (check_nonnull_arg, NULL,
|
check_function_arguments_recurse (check_nonnull_arg, NULL,
|
||||||
TREE_VALUE (param),
|
argarray[i],
|
||||||
param_num);
|
i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the Nth argument of a function call (counting backwards
|
/* 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
|
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);
|
tree attr = lookup_attribute ("sentinel", attrs);
|
||||||
|
|
||||||
if (attr)
|
if (attr)
|
||||||
{
|
{
|
||||||
|
int len = 0;
|
||||||
|
int pos = 0;
|
||||||
|
tree sentinel;
|
||||||
|
|
||||||
/* Skip over the named arguments. */
|
/* Skip over the named arguments. */
|
||||||
while (typelist && params)
|
while (typelist && len < nargs)
|
||||||
{
|
|
||||||
typelist = TREE_CHAIN (typelist);
|
|
||||||
params = TREE_CHAIN (params);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typelist || !params)
|
|
||||||
warning (OPT_Wformat,
|
|
||||||
"not enough variable arguments to fit a sentinel");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
tree sentinel, end;
|
typelist = TREE_CHAIN (typelist);
|
||||||
unsigned pos = 0;
|
len++;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now advance both until we find the last parameter. */
|
|
||||||
while (TREE_CHAIN (end))
|
|
||||||
{
|
|
||||||
end = TREE_CHAIN (end);
|
|
||||||
sentinel = TREE_CHAIN (sentinel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TREE_VALUE (attr))
|
||||||
|
{
|
||||||
|
tree p = TREE_VALUE (TREE_VALUE (attr));
|
||||||
|
pos = TREE_INT_CST_LOW (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
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
|
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
|
/* 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. */
|
non-null. We also need to do this if format checking is enabled. */
|
||||||
|
|
||||||
if (warn_nonnull)
|
if (warn_nonnull)
|
||||||
check_function_nonnull (attrs, params);
|
check_function_nonnull (attrs, nargs, argarray);
|
||||||
|
|
||||||
/* Check for errors in format strings. */
|
/* Check for errors in format strings. */
|
||||||
|
|
||||||
if (warn_format || warn_missing_format_attribute)
|
if (warn_format || warn_missing_format_attribute)
|
||||||
check_function_format (attrs, params);
|
check_function_format (attrs, nargs, argarray);
|
||||||
|
|
||||||
if (warn_format)
|
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
|
/* Generic argument checking recursion routine. PARAM is the argument to
|
||||||
|
|
|
@ -640,13 +640,13 @@ extern void finish_fname_decls (void);
|
||||||
extern const char *fname_as_string (int);
|
extern const char *fname_as_string (int);
|
||||||
extern tree fname_decl (unsigned, tree);
|
extern tree fname_decl (unsigned, tree);
|
||||||
|
|
||||||
extern void check_function_arguments (tree, tree, tree);
|
extern void check_function_arguments (tree, int, tree *, tree);
|
||||||
extern void check_function_arguments_recurse (void (*)
|
extern void check_function_arguments_recurse (void (*)
|
||||||
(void *, tree,
|
(void *, tree,
|
||||||
unsigned HOST_WIDE_INT),
|
unsigned HOST_WIDE_INT),
|
||||||
void *, tree,
|
void *, tree,
|
||||||
unsigned HOST_WIDE_INT);
|
unsigned HOST_WIDE_INT);
|
||||||
extern void check_function_format (tree, tree);
|
extern void check_function_format (tree, int, tree *);
|
||||||
extern void set_Wformat (int);
|
extern void set_Wformat (int);
|
||||||
extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
|
extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
|
||||||
extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
|
extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
|
||||||
|
|
|
@ -851,13 +851,14 @@ decode_format_type (const char *s)
|
||||||
|
|
||||||
|
|
||||||
/* Check the argument list of a call to printf, scanf, etc.
|
/* Check the argument list of a call to printf, scanf, etc.
|
||||||
ATTRS are the attributes on the function type.
|
ATTRS are the attributes on the function type. There are NARGS argument
|
||||||
PARAMS is the list of argument values. Also, if -Wmissing-format-attribute,
|
values in the array ARGARRAY.
|
||||||
|
Also, if -Wmissing-format-attribute,
|
||||||
warn for calls to vprintf or vscanf in functions with no such format
|
warn for calls to vprintf or vscanf in functions with no such format
|
||||||
attribute themselves. */
|
attribute themselves. */
|
||||||
|
|
||||||
void
|
void
|
||||||
check_function_format (tree attrs, tree params)
|
check_function_format (tree attrs, int nargs, tree *argarray)
|
||||||
{
|
{
|
||||||
tree a;
|
tree a;
|
||||||
|
|
||||||
|
@ -870,7 +871,16 @@ check_function_format (tree attrs, tree params)
|
||||||
function_format_info info;
|
function_format_info info;
|
||||||
decode_format_attr (TREE_VALUE (a), &info, 1);
|
decode_format_attr (TREE_VALUE (a), &info, 1);
|
||||||
if (warn_format)
|
if (warn_format)
|
||||||
check_format_info (&info, params);
|
{
|
||||||
|
/* FIXME: Rewrite all the internal functions in this file
|
||||||
|
to use the ARGARRAY directly instead of constructing this
|
||||||
|
temporary list. */
|
||||||
|
tree params = NULL_TREE;
|
||||||
|
int i;
|
||||||
|
for (i = nargs - 1; i >= 0; i--)
|
||||||
|
params = tree_cons (NULL_TREE, argarray[i], params);
|
||||||
|
check_format_info (&info, params);
|
||||||
|
}
|
||||||
if (warn_missing_format_attribute && info.first_arg_num == 0
|
if (warn_missing_format_attribute && info.first_arg_num == 0
|
||||||
&& (format_types[info.format_type].flags
|
&& (format_types[info.format_type].flags
|
||||||
& (int) FMT_FLAG_ARG_CONVERT))
|
& (int) FMT_FLAG_ARG_CONVERT))
|
||||||
|
|
|
@ -83,7 +83,7 @@ static int function_types_compatible_p (tree, tree);
|
||||||
static int type_lists_compatible_p (tree, tree);
|
static int type_lists_compatible_p (tree, tree);
|
||||||
static tree decl_constant_value_for_broken_optimization (tree);
|
static tree decl_constant_value_for_broken_optimization (tree);
|
||||||
static tree lookup_field (tree, tree);
|
static tree lookup_field (tree, tree);
|
||||||
static tree convert_arguments (tree, tree, tree, tree);
|
static int convert_arguments (int, tree *, tree, tree, tree, tree);
|
||||||
static tree pointer_diff (tree, tree);
|
static tree pointer_diff (tree, tree);
|
||||||
static tree convert_for_assignment (tree, tree, enum impl_conv, tree, tree,
|
static tree convert_for_assignment (tree, tree, enum impl_conv, tree, tree,
|
||||||
int);
|
int);
|
||||||
|
@ -2228,9 +2228,11 @@ tree
|
||||||
build_function_call (tree function, tree params)
|
build_function_call (tree function, tree params)
|
||||||
{
|
{
|
||||||
tree fntype, fundecl = 0;
|
tree fntype, fundecl = 0;
|
||||||
tree coerced_params;
|
|
||||||
tree name = NULL_TREE, result;
|
tree name = NULL_TREE, result;
|
||||||
tree tem;
|
tree tem;
|
||||||
|
int nargs;
|
||||||
|
tree *argarray;
|
||||||
|
|
||||||
|
|
||||||
/* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
|
/* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
|
||||||
STRIP_TYPE_NOPS (function);
|
STRIP_TYPE_NOPS (function);
|
||||||
|
@ -2317,30 +2319,30 @@ build_function_call (tree function, tree params)
|
||||||
/* Convert the parameters to the types declared in the
|
/* Convert the parameters to the types declared in the
|
||||||
function prototype, or apply default promotions. */
|
function prototype, or apply default promotions. */
|
||||||
|
|
||||||
coerced_params
|
nargs = list_length (params);
|
||||||
= convert_arguments (TYPE_ARG_TYPES (fntype), params, function, fundecl);
|
argarray = (tree *) alloca (nargs * sizeof (tree));
|
||||||
|
nargs = convert_arguments (nargs, argarray, TYPE_ARG_TYPES (fntype),
|
||||||
if (coerced_params == error_mark_node)
|
params, function, fundecl);
|
||||||
|
if (nargs < 0)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
|
|
||||||
/* Check that the arguments to the function are valid. */
|
/* Check that the arguments to the function are valid. */
|
||||||
|
|
||||||
check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params,
|
check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
|
||||||
TYPE_ARG_TYPES (fntype));
|
TYPE_ARG_TYPES (fntype));
|
||||||
|
|
||||||
if (require_constant_value)
|
if (require_constant_value)
|
||||||
{
|
{
|
||||||
result = fold_build_call_list_initializer (TREE_TYPE (fntype),
|
result = fold_build_call_array_initializer (TREE_TYPE (fntype),
|
||||||
function,
|
function, nargs, argarray);
|
||||||
coerced_params);
|
|
||||||
if (TREE_CONSTANT (result)
|
if (TREE_CONSTANT (result)
|
||||||
&& (name == NULL_TREE
|
&& (name == NULL_TREE
|
||||||
|| strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
|
|| strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
|
||||||
pedwarn_init ("initializer element is not constant");
|
pedwarn_init ("initializer element is not constant");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = fold_build_call_list (TREE_TYPE (fntype),
|
result = fold_build_call_array (TREE_TYPE (fntype),
|
||||||
function, coerced_params);
|
function, nargs, argarray);
|
||||||
|
|
||||||
if (VOID_TYPE_P (TREE_TYPE (result)))
|
if (VOID_TYPE_P (TREE_TYPE (result)))
|
||||||
return result;
|
return result;
|
||||||
|
@ -2348,9 +2350,8 @@ build_function_call (tree function, tree params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the argument expressions in the list VALUES
|
/* Convert the argument expressions in the list VALUES
|
||||||
to the types in the list TYPELIST. The result is a list of converted
|
to the types in the list TYPELIST. The resulting arguments are
|
||||||
argument expressions, unless there are too few arguments in which
|
stored in the array ARGARRAY which has size NARGS.
|
||||||
case it is error_mark_node.
|
|
||||||
|
|
||||||
If TYPELIST is exhausted, or when an element has NULL as its type,
|
If TYPELIST is exhausted, or when an element has NULL as its type,
|
||||||
perform the default conversions.
|
perform the default conversions.
|
||||||
|
@ -2364,14 +2365,17 @@ build_function_call (tree function, tree params)
|
||||||
|
|
||||||
This is also where warnings about wrong number of args are generated.
|
This is also where warnings about wrong number of args are generated.
|
||||||
|
|
||||||
Both VALUES and the returned value are chains of TREE_LIST nodes
|
VALUES is a chain of TREE_LIST nodes with the elements of the list
|
||||||
with the elements of the list in the TREE_VALUE slots of those nodes. */
|
in the TREE_VALUE slots of those nodes.
|
||||||
|
|
||||||
static tree
|
Returns the actual number of arguments processed (which may be less
|
||||||
convert_arguments (tree typelist, tree values, tree function, tree fundecl)
|
than NARGS in some error situations), or -1 on failure. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
convert_arguments (int nargs, tree *argarray,
|
||||||
|
tree typelist, tree values, tree function, tree fundecl)
|
||||||
{
|
{
|
||||||
tree typetail, valtail;
|
tree typetail, valtail;
|
||||||
tree result = NULL;
|
|
||||||
int parmnum;
|
int parmnum;
|
||||||
tree selector;
|
tree selector;
|
||||||
|
|
||||||
|
@ -2385,7 +2389,7 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
|
||||||
selector = objc_message_selector ();
|
selector = objc_message_selector ();
|
||||||
|
|
||||||
/* Scan the given expressions and types, producing individual
|
/* Scan the given expressions and types, producing individual
|
||||||
converted arguments and pushing them on RESULT in reverse order. */
|
converted arguments and storing them in ARGARRAY. */
|
||||||
|
|
||||||
for (valtail = values, typetail = typelist, parmnum = 0;
|
for (valtail = values, typetail = typelist, parmnum = 0;
|
||||||
valtail;
|
valtail;
|
||||||
|
@ -2400,7 +2404,7 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
|
||||||
if (type == void_type_node)
|
if (type == void_type_node)
|
||||||
{
|
{
|
||||||
error ("too many arguments to function %qE", function);
|
error ("too many arguments to function %qE", function);
|
||||||
break;
|
return parmnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selector && argnum > 2)
|
if (selector && argnum > 2)
|
||||||
|
@ -2558,35 +2562,37 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
|
||||||
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
|
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
|
||||||
parmval = default_conversion (parmval);
|
parmval = default_conversion (parmval);
|
||||||
}
|
}
|
||||||
result = tree_cons (NULL_TREE, parmval, result);
|
argarray[parmnum] = parmval;
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
|
else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
|
||||||
&& (TYPE_PRECISION (TREE_TYPE (val))
|
&& (TYPE_PRECISION (TREE_TYPE (val))
|
||||||
< TYPE_PRECISION (double_type_node))
|
< TYPE_PRECISION (double_type_node))
|
||||||
&& !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (val))))
|
&& !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (val))))
|
||||||
/* Convert `float' to `double'. */
|
/* Convert `float' to `double'. */
|
||||||
result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
|
argarray[parmnum] = convert (double_type_node, val);
|
||||||
else if ((invalid_func_diag =
|
else if ((invalid_func_diag =
|
||||||
targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val)))
|
targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val)))
|
||||||
{
|
{
|
||||||
error (invalid_func_diag);
|
error (invalid_func_diag);
|
||||||
return error_mark_node;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Convert `short' and `char' to full-size `int'. */
|
/* Convert `short' and `char' to full-size `int'. */
|
||||||
result = tree_cons (NULL_TREE, default_conversion (val), result);
|
argarray[parmnum] = default_conversion (val);
|
||||||
|
|
||||||
if (typetail)
|
if (typetail)
|
||||||
typetail = TREE_CHAIN (typetail);
|
typetail = TREE_CHAIN (typetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gcc_assert (parmnum == nargs);
|
||||||
|
|
||||||
if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
|
if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
|
||||||
{
|
{
|
||||||
error ("too few arguments to function %qE", function);
|
error ("too few arguments to function %qE", function);
|
||||||
return error_mark_node;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nreverse (result);
|
return parmnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the entry point used by the parser to build unary operators
|
/* This is the entry point used by the parser to build unary operators
|
||||||
|
|
|
@ -1,3 +1,30 @@
|
||||||
|
2007-02-28 Sandra Loosemore <sandra@codesourcery.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
* 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.
|
||||||
|
* tree.h: Update declarations to reflect above changes.
|
||||||
|
* method.c (use_thunk): Use a stack-allocated array to hold
|
||||||
|
the arguments instead of a list.
|
||||||
|
* rtti.c (throw_bad_cast): Update call to cxx_call.
|
||||||
|
(throw_bad_typeid): Likewise.
|
||||||
|
(build_dynamic_cast_1): Likewise.
|
||||||
|
* init.c (build_builtin_delete_call): Use build_call_n.
|
||||||
|
* decl.c (expand_static_init): Likewise.
|
||||||
|
* except.c (cp_protect_cleanup_actions): Likewise.
|
||||||
|
* cp-gimplify.c (genericize_eh_spec_block): Likewise.
|
||||||
|
(gimplify_must_not_throw_expr): Likewise.
|
||||||
|
(cxx_omp_apply_fn): Use build_call_a.
|
||||||
|
|
||||||
2007-02-26 Mark Mitchell <mark@codesourcery.com>
|
2007-02-26 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
* semantics.c (expand_or_defer_fn): Call c_record_cdtor_fn.
|
* semantics.c (expand_or_defer_fn): Call c_record_cdtor_fn.
|
||||||
|
|
172
gcc/cp/call.c
172
gcc/cp/call.c
|
@ -269,17 +269,38 @@ build_addr_func (tree function)
|
||||||
|
|
||||||
/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or
|
/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or
|
||||||
POINTER_TYPE to those. Note, pointer to member function types
|
POINTER_TYPE to those. Note, pointer to member function types
|
||||||
(TYPE_PTRMEMFUNC_P) must be handled by our callers. */
|
(TYPE_PTRMEMFUNC_P) must be handled by our callers. There are
|
||||||
|
two variants. build_call_a is the primitive taking an array of
|
||||||
|
arguments, while build_call_n is a wrapper that handles varargs. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
build_call (tree function, tree parms)
|
build_call_n (tree function, int n, ...)
|
||||||
|
{
|
||||||
|
if (n == 0)
|
||||||
|
return build_call_a (function, 0, NULL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tree *argarray = (tree *) alloca (n * sizeof (tree));
|
||||||
|
va_list ap;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
va_start (ap, n);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
argarray[i] = va_arg (ap, tree);
|
||||||
|
va_end (ap);
|
||||||
|
return build_call_a (function, n, argarray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tree
|
||||||
|
build_call_a (tree function, int n, tree *argarray)
|
||||||
{
|
{
|
||||||
int is_constructor = 0;
|
int is_constructor = 0;
|
||||||
int nothrow;
|
int nothrow;
|
||||||
tree tmp;
|
|
||||||
tree decl;
|
tree decl;
|
||||||
tree result_type;
|
tree result_type;
|
||||||
tree fntype;
|
tree fntype;
|
||||||
|
int i;
|
||||||
|
|
||||||
function = build_addr_func (function);
|
function = build_addr_func (function);
|
||||||
|
|
||||||
|
@ -327,16 +348,16 @@ build_call (tree function, tree parms)
|
||||||
for tags in STL, which are used to control overload resolution.
|
for tags in STL, which are used to control overload resolution.
|
||||||
We don't need to handle other cases of copying empty classes. */
|
We don't need to handle other cases of copying empty classes. */
|
||||||
if (! decl || ! DECL_BUILT_IN (decl))
|
if (! decl || ! DECL_BUILT_IN (decl))
|
||||||
for (tmp = parms; tmp; tmp = TREE_CHAIN (tmp))
|
for (i = 0; i < n; i++)
|
||||||
if (is_empty_class (TREE_TYPE (TREE_VALUE (tmp)))
|
if (is_empty_class (TREE_TYPE (argarray[i]))
|
||||||
&& ! TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (tmp))))
|
&& ! TREE_ADDRESSABLE (TREE_TYPE (argarray[i])))
|
||||||
{
|
{
|
||||||
tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (TREE_VALUE (tmp)));
|
tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (argarray[i]));
|
||||||
TREE_VALUE (tmp) = build2 (COMPOUND_EXPR, TREE_TYPE (t),
|
argarray[i] = build2 (COMPOUND_EXPR, TREE_TYPE (t),
|
||||||
TREE_VALUE (tmp), t);
|
argarray[i], t);
|
||||||
}
|
}
|
||||||
|
|
||||||
function = build_call_list (result_type, function, parms);
|
function = build_call_array (result_type, function, n, argarray);
|
||||||
TREE_HAS_CONSTRUCTOR (function) = is_constructor;
|
TREE_HAS_CONSTRUCTOR (function) = is_constructor;
|
||||||
TREE_NOTHROW (function) = nothrow;
|
TREE_NOTHROW (function) = nothrow;
|
||||||
|
|
||||||
|
@ -4005,7 +4026,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
|
||||||
tree alloc_fn)
|
tree alloc_fn)
|
||||||
{
|
{
|
||||||
tree fn = NULL_TREE;
|
tree fn = NULL_TREE;
|
||||||
tree fns, fnname, argtypes, args, type;
|
tree fns, fnname, argtypes, type;
|
||||||
int pass;
|
int pass;
|
||||||
|
|
||||||
if (addr == error_mark_node)
|
if (addr == error_mark_node)
|
||||||
|
@ -4036,25 +4057,22 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
|
||||||
if (fns == NULL_TREE)
|
if (fns == NULL_TREE)
|
||||||
fns = lookup_name_nonclass (fnname);
|
fns = lookup_name_nonclass (fnname);
|
||||||
|
|
||||||
|
/* Strip const and volatile from addr. */
|
||||||
|
addr = cp_convert (ptr_type_node, addr);
|
||||||
|
|
||||||
if (placement)
|
if (placement)
|
||||||
{
|
{
|
||||||
/* Get the parameter types for the allocation function that is
|
/* Get the parameter types for the allocation function that is
|
||||||
being called. */
|
being called. */
|
||||||
gcc_assert (alloc_fn != NULL_TREE);
|
gcc_assert (alloc_fn != NULL_TREE);
|
||||||
argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
|
argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
|
||||||
/* Also the second argument. */
|
|
||||||
args = TREE_CHAIN (TREE_OPERAND (placement, 1));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* First try it without the size argument. */
|
/* First try it without the size argument. */
|
||||||
argtypes = void_list_node;
|
argtypes = void_list_node;
|
||||||
args = NULL_TREE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strip const and volatile from addr. */
|
|
||||||
addr = cp_convert (ptr_type_node, addr);
|
|
||||||
|
|
||||||
/* We make two tries at finding a matching `operator delete'. On
|
/* We make two tries at finding a matching `operator delete'. On
|
||||||
the first pass, we look for a one-operator (or placement)
|
the first pass, we look for a one-operator (or placement)
|
||||||
operator delete. If we're not doing placement delete, then on
|
operator delete. If we're not doing placement delete, then on
|
||||||
|
@ -4113,21 +4131,29 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
|
||||||
if (DECL_CLASS_SCOPE_P (fn))
|
if (DECL_CLASS_SCOPE_P (fn))
|
||||||
perform_or_defer_access_check (TYPE_BINFO (type), fn, fn);
|
perform_or_defer_access_check (TYPE_BINFO (type), fn, fn);
|
||||||
|
|
||||||
if (pass == 0)
|
|
||||||
args = tree_cons (NULL_TREE, addr, args);
|
|
||||||
else
|
|
||||||
args = tree_cons (NULL_TREE, addr,
|
|
||||||
build_tree_list (NULL_TREE, size));
|
|
||||||
|
|
||||||
if (placement)
|
if (placement)
|
||||||
{
|
{
|
||||||
/* The placement args might not be suitable for overload
|
/* The placement args might not be suitable for overload
|
||||||
resolution at this point, so build the call directly. */
|
resolution at this point, so build the call directly. */
|
||||||
|
int nargs = call_expr_nargs (placement);
|
||||||
|
tree *argarray = (tree *) alloca (nargs * sizeof (tree));
|
||||||
|
int i;
|
||||||
|
argarray[0] = addr;
|
||||||
|
for (i = 1; i < nargs; i++)
|
||||||
|
argarray[i] = CALL_EXPR_ARG (placement, i);
|
||||||
mark_used (fn);
|
mark_used (fn);
|
||||||
return build_cxx_call (fn, args);
|
return build_cxx_call (fn, nargs, argarray);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return build_function_call (fn, args);
|
{
|
||||||
|
tree args;
|
||||||
|
if (pass == 0)
|
||||||
|
args = tree_cons (NULL_TREE, addr, NULL_TREE);
|
||||||
|
else
|
||||||
|
args = tree_cons (NULL_TREE, addr,
|
||||||
|
build_tree_list (NULL_TREE, size));
|
||||||
|
return build_function_call (fn, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are doing placement delete we do nothing if we don't find a
|
/* If we are doing placement delete we do nothing if we don't find a
|
||||||
|
@ -4494,7 +4520,7 @@ call_builtin_trap (void)
|
||||||
tree fn = implicit_built_in_decls[BUILT_IN_TRAP];
|
tree fn = implicit_built_in_decls[BUILT_IN_TRAP];
|
||||||
|
|
||||||
gcc_assert (fn != NULL);
|
gcc_assert (fn != NULL);
|
||||||
fn = build_call (fn, NULL_TREE);
|
fn = build_call_n (fn, 0);
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4725,11 +4751,14 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
tree args = cand->args;
|
tree args = cand->args;
|
||||||
conversion **convs = cand->convs;
|
conversion **convs = cand->convs;
|
||||||
conversion *conv;
|
conversion *conv;
|
||||||
tree converted_args = NULL_TREE;
|
|
||||||
tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||||
|
int parmlen;
|
||||||
tree arg, val;
|
tree arg, val;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
int is_method = 0;
|
int is_method = 0;
|
||||||
|
int nargs;
|
||||||
|
tree *argarray;
|
||||||
|
|
||||||
/* In a template, there is no need to perform all of the work that
|
/* In a template, there is no need to perform all of the work that
|
||||||
is normally done. We are only interested in the type of the call
|
is normally done. We are only interested in the type of the call
|
||||||
|
@ -4795,11 +4824,18 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
args = build_tree_list (NULL_TREE, args);
|
args = build_tree_list (NULL_TREE, args);
|
||||||
arg = args;
|
arg = args;
|
||||||
|
|
||||||
|
/* Find maximum size of vector to hold converted arguments. */
|
||||||
|
parmlen = list_length (parm);
|
||||||
|
nargs = list_length (args);
|
||||||
|
if (parmlen > nargs)
|
||||||
|
nargs = parmlen;
|
||||||
|
argarray = (tree *) alloca (nargs * sizeof (tree));
|
||||||
|
|
||||||
/* The implicit parameters to a constructor are not considered by overload
|
/* The implicit parameters to a constructor are not considered by overload
|
||||||
resolution, and must be of the proper type. */
|
resolution, and must be of the proper type. */
|
||||||
if (DECL_CONSTRUCTOR_P (fn))
|
if (DECL_CONSTRUCTOR_P (fn))
|
||||||
{
|
{
|
||||||
converted_args = tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args);
|
argarray[j++] = TREE_VALUE (arg);
|
||||||
arg = TREE_CHAIN (arg);
|
arg = TREE_CHAIN (arg);
|
||||||
parm = TREE_CHAIN (parm);
|
parm = TREE_CHAIN (parm);
|
||||||
/* We should never try to call the abstract constructor. */
|
/* We should never try to call the abstract constructor. */
|
||||||
|
@ -4807,8 +4843,7 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
|
|
||||||
if (DECL_HAS_VTT_PARM_P (fn))
|
if (DECL_HAS_VTT_PARM_P (fn))
|
||||||
{
|
{
|
||||||
converted_args = tree_cons
|
argarray[j++] = TREE_VALUE (arg);
|
||||||
(NULL_TREE, TREE_VALUE (arg), converted_args);
|
|
||||||
arg = TREE_CHAIN (arg);
|
arg = TREE_CHAIN (arg);
|
||||||
parm = TREE_CHAIN (parm);
|
parm = TREE_CHAIN (parm);
|
||||||
}
|
}
|
||||||
|
@ -4852,7 +4887,7 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
converted_arg = build_base_path (PLUS_EXPR, converted_arg,
|
converted_arg = build_base_path (PLUS_EXPR, converted_arg,
|
||||||
base_binfo, 1);
|
base_binfo, 1);
|
||||||
|
|
||||||
converted_args = tree_cons (NULL_TREE, converted_arg, converted_args);
|
argarray[j++] = converted_arg;
|
||||||
parm = TREE_CHAIN (parm);
|
parm = TREE_CHAIN (parm);
|
||||||
arg = TREE_CHAIN (arg);
|
arg = TREE_CHAIN (arg);
|
||||||
++i;
|
++i;
|
||||||
|
@ -4875,18 +4910,14 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
(conv, TREE_VALUE (arg), fn, i - is_method);
|
(conv, TREE_VALUE (arg), fn, i - is_method);
|
||||||
|
|
||||||
val = convert_for_arg_passing (type, val);
|
val = convert_for_arg_passing (type, val);
|
||||||
converted_args = tree_cons (NULL_TREE, val, converted_args);
|
argarray[j++] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default arguments */
|
/* Default arguments */
|
||||||
for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++)
|
for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++)
|
||||||
converted_args
|
argarray[j++] = convert_default_arg (TREE_VALUE (parm),
|
||||||
= tree_cons (NULL_TREE,
|
TREE_PURPOSE (parm),
|
||||||
convert_default_arg (TREE_VALUE (parm),
|
fn, i - is_method);
|
||||||
TREE_PURPOSE (parm),
|
|
||||||
fn, i - is_method),
|
|
||||||
converted_args);
|
|
||||||
|
|
||||||
/* Ellipsis */
|
/* Ellipsis */
|
||||||
for (; arg; arg = TREE_CHAIN (arg))
|
for (; arg; arg = TREE_CHAIN (arg))
|
||||||
{
|
{
|
||||||
|
@ -4895,13 +4926,14 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
/* Do no conversions for magic varargs. */;
|
/* Do no conversions for magic varargs. */;
|
||||||
else
|
else
|
||||||
a = convert_arg_to_ellipsis (a);
|
a = convert_arg_to_ellipsis (a);
|
||||||
converted_args = tree_cons (NULL_TREE, a, converted_args);
|
argarray[j++] = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
converted_args = nreverse (converted_args);
|
gcc_assert (j <= nargs);
|
||||||
|
nargs = j;
|
||||||
|
|
||||||
check_function_arguments (TYPE_ATTRIBUTES (TREE_TYPE (fn)),
|
check_function_arguments (TYPE_ATTRIBUTES (TREE_TYPE (fn)),
|
||||||
converted_args, TYPE_ARG_TYPES (TREE_TYPE (fn)));
|
nargs, argarray, TYPE_ARG_TYPES (TREE_TYPE (fn)));
|
||||||
|
|
||||||
/* Avoid actually calling copy constructors and copy assignment operators,
|
/* Avoid actually calling copy constructors and copy assignment operators,
|
||||||
if possible. */
|
if possible. */
|
||||||
|
@ -4911,8 +4943,7 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
else if (cand->num_convs == 1 && DECL_COPY_CONSTRUCTOR_P (fn))
|
else if (cand->num_convs == 1 && DECL_COPY_CONSTRUCTOR_P (fn))
|
||||||
{
|
{
|
||||||
tree targ;
|
tree targ;
|
||||||
arg = skip_artificial_parms_for (fn, converted_args);
|
arg = argarray[num_artificial_parms_for (fn)];
|
||||||
arg = TREE_VALUE (arg);
|
|
||||||
|
|
||||||
/* Pull out the real argument, disregarding const-correctness. */
|
/* Pull out the real argument, disregarding const-correctness. */
|
||||||
targ = arg;
|
targ = arg;
|
||||||
|
@ -4967,11 +4998,11 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
&& TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
|
&& TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
|
||||||
{
|
{
|
||||||
tree to = stabilize_reference
|
tree to = stabilize_reference
|
||||||
(build_indirect_ref (TREE_VALUE (converted_args), 0));
|
(build_indirect_ref (argarray[0], 0));
|
||||||
tree type = TREE_TYPE (to);
|
tree type = TREE_TYPE (to);
|
||||||
tree as_base = CLASSTYPE_AS_BASE (type);
|
tree as_base = CLASSTYPE_AS_BASE (type);
|
||||||
|
|
||||||
arg = TREE_VALUE (TREE_CHAIN (converted_args));
|
arg = argarray[1];
|
||||||
if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
|
if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
|
||||||
{
|
{
|
||||||
arg = build_indirect_ref (arg, 0);
|
arg = build_indirect_ref (arg, 0);
|
||||||
|
@ -4981,17 +5012,16 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
{
|
{
|
||||||
/* We must only copy the non-tail padding parts.
|
/* We must only copy the non-tail padding parts.
|
||||||
Use __builtin_memcpy for the bitwise copy. */
|
Use __builtin_memcpy for the bitwise copy. */
|
||||||
|
|
||||||
|
tree arg0, arg1, arg2, t;
|
||||||
|
|
||||||
tree args, t;
|
arg2 = TYPE_SIZE_UNIT (as_base);
|
||||||
|
arg1 = arg;
|
||||||
args = tree_cons (NULL, TYPE_SIZE_UNIT (as_base), NULL);
|
arg0 = build_unary_op (ADDR_EXPR, to, 0);
|
||||||
args = tree_cons (NULL, arg, args);
|
|
||||||
t = build_unary_op (ADDR_EXPR, to, 0);
|
|
||||||
args = tree_cons (NULL, t, args);
|
|
||||||
t = implicit_built_in_decls[BUILT_IN_MEMCPY];
|
t = implicit_built_in_decls[BUILT_IN_MEMCPY];
|
||||||
t = build_call (t, args);
|
t = build_call_n (t, 3, arg0, arg1, arg2);
|
||||||
|
|
||||||
t = convert (TREE_TYPE (TREE_VALUE (args)), t);
|
t = convert (TREE_TYPE (arg0), t);
|
||||||
val = build_indirect_ref (t, 0);
|
val = build_indirect_ref (t, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5002,20 +5032,20 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
|
|
||||||
if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
|
if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
|
||||||
{
|
{
|
||||||
tree t, *p = &TREE_VALUE (converted_args);
|
tree t;
|
||||||
tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)),
|
tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (argarray[0])),
|
||||||
DECL_CONTEXT (fn),
|
DECL_CONTEXT (fn),
|
||||||
ba_any, NULL);
|
ba_any, NULL);
|
||||||
gcc_assert (binfo && binfo != error_mark_node);
|
gcc_assert (binfo && binfo != error_mark_node);
|
||||||
|
|
||||||
*p = build_base_path (PLUS_EXPR, *p, binfo, 1);
|
argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1);
|
||||||
if (TREE_SIDE_EFFECTS (*p))
|
if (TREE_SIDE_EFFECTS (argarray[0]))
|
||||||
*p = save_expr (*p);
|
argarray[0] = save_expr (argarray[0]);
|
||||||
t = build_pointer_type (TREE_TYPE (fn));
|
t = build_pointer_type (TREE_TYPE (fn));
|
||||||
if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
|
if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
|
||||||
fn = build_java_interface_fn_ref (fn, *p);
|
fn = build_java_interface_fn_ref (fn, argarray[0]);
|
||||||
else
|
else
|
||||||
fn = build_vfn_ref (*p, DECL_VINDEX (fn));
|
fn = build_vfn_ref (argarray[0], DECL_VINDEX (fn));
|
||||||
TREE_TYPE (fn) = t;
|
TREE_TYPE (fn) = t;
|
||||||
}
|
}
|
||||||
else if (DECL_INLINE (fn))
|
else if (DECL_INLINE (fn))
|
||||||
|
@ -5023,19 +5053,19 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
else
|
else
|
||||||
fn = build_addr_func (fn);
|
fn = build_addr_func (fn);
|
||||||
|
|
||||||
return build_cxx_call (fn, converted_args);
|
return build_cxx_call (fn, nargs, argarray);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build and return a call to FN, using ARGS. This function performs
|
/* Build and return a call to FN, using NARGS arguments in ARGARRAY.
|
||||||
no overload resolution, conversion, or other high-level
|
This function performs no overload resolution, conversion, or other
|
||||||
operations. */
|
high-level operations. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
build_cxx_call (tree fn, tree args)
|
build_cxx_call (tree fn, int nargs, tree *argarray)
|
||||||
{
|
{
|
||||||
tree fndecl;
|
tree fndecl;
|
||||||
|
|
||||||
fn = build_call (fn, args);
|
fn = build_call_a (fn, nargs, argarray);
|
||||||
|
|
||||||
/* If this call might throw an exception, note that fact. */
|
/* If this call might throw an exception, note that fact. */
|
||||||
fndecl = get_callee_fndecl (fn);
|
fndecl = get_callee_fndecl (fn);
|
||||||
|
@ -5069,7 +5099,7 @@ static GTY(()) tree java_iface_lookup_fn;
|
||||||
static tree
|
static tree
|
||||||
build_java_interface_fn_ref (tree fn, tree instance)
|
build_java_interface_fn_ref (tree fn, tree instance)
|
||||||
{
|
{
|
||||||
tree lookup_args, lookup_fn, method, idx;
|
tree lookup_fn, method, idx;
|
||||||
tree klass_ref, iface, iface_ref;
|
tree klass_ref, iface, iface_ref;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -5116,13 +5146,11 @@ build_java_interface_fn_ref (tree fn, tree instance)
|
||||||
}
|
}
|
||||||
idx = build_int_cst (NULL_TREE, i);
|
idx = build_int_cst (NULL_TREE, i);
|
||||||
|
|
||||||
lookup_args = tree_cons (NULL_TREE, klass_ref,
|
|
||||||
tree_cons (NULL_TREE, iface_ref,
|
|
||||||
build_tree_list (NULL_TREE, idx)));
|
|
||||||
lookup_fn = build1 (ADDR_EXPR,
|
lookup_fn = build1 (ADDR_EXPR,
|
||||||
build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
|
build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
|
||||||
java_iface_lookup_fn);
|
java_iface_lookup_fn);
|
||||||
return build_call_list (ptr_type_node, lookup_fn, lookup_args);
|
return build_call_nary (ptr_type_node, lookup_fn,
|
||||||
|
3, klass_ref, iface_ref, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the value to use for the in-charge parameter when making a
|
/* Returns the value to use for the in-charge parameter when making a
|
||||||
|
|
|
@ -146,9 +146,7 @@ genericize_eh_spec_block (tree *stmt_p)
|
||||||
{
|
{
|
||||||
tree body = EH_SPEC_STMTS (*stmt_p);
|
tree body = EH_SPEC_STMTS (*stmt_p);
|
||||||
tree allowed = EH_SPEC_RAISES (*stmt_p);
|
tree allowed = EH_SPEC_RAISES (*stmt_p);
|
||||||
tree failure = build_call (call_unexpected_node,
|
tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
|
||||||
tree_cons (NULL_TREE, build_exc_ptr (),
|
|
||||||
NULL_TREE));
|
|
||||||
gimplify_stmt (&body);
|
gimplify_stmt (&body);
|
||||||
|
|
||||||
*stmt_p = gimple_build_eh_filter (body, allowed, failure);
|
*stmt_p = gimple_build_eh_filter (body, allowed, failure);
|
||||||
|
@ -432,7 +430,7 @@ gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
|
||||||
gimplify_stmt (&body);
|
gimplify_stmt (&body);
|
||||||
|
|
||||||
stmt = gimple_build_eh_filter (body, NULL_TREE,
|
stmt = gimple_build_eh_filter (body, NULL_TREE,
|
||||||
build_call (terminate_node, NULL_TREE));
|
build_call_n (terminate_node, 0));
|
||||||
|
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
|
@ -766,11 +764,16 @@ static tree
|
||||||
cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
|
cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
|
||||||
{
|
{
|
||||||
tree defparm, parm;
|
tree defparm, parm;
|
||||||
int i;
|
int i = 0;
|
||||||
|
int nargs;
|
||||||
|
tree *argarray;
|
||||||
|
|
||||||
if (fn == NULL)
|
if (fn == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
nargs = list_length (DECL_ARGUMENTS (fn));
|
||||||
|
argarray = (tree *) alloca (nargs * sizeof (tree));
|
||||||
|
|
||||||
defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
|
defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
|
||||||
if (arg2)
|
if (arg2)
|
||||||
defparm = TREE_CHAIN (defparm);
|
defparm = TREE_CHAIN (defparm);
|
||||||
|
@ -817,16 +820,14 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
|
||||||
t = build1 (LABEL_EXPR, void_type_node, lab);
|
t = build1 (LABEL_EXPR, void_type_node, lab);
|
||||||
append_to_statement_list (t, &ret);
|
append_to_statement_list (t, &ret);
|
||||||
|
|
||||||
t = tree_cons (NULL, p1, NULL);
|
argarray[i++] = p1;
|
||||||
if (arg2)
|
if (arg2)
|
||||||
t = tree_cons (NULL, p2, t);
|
argarray[i++] = p2;
|
||||||
/* Handle default arguments. */
|
/* Handle default arguments. */
|
||||||
i = 1 + (arg2 != NULL);
|
for (parm = defparm; parm != void_list_node; parm = TREE_CHAIN (parm), i++)
|
||||||
for (parm = defparm; parm != void_list_node; parm = TREE_CHAIN (parm))
|
argarray[i] = convert_default_arg (TREE_VALUE (parm),
|
||||||
t = tree_cons (NULL, convert_default_arg (TREE_VALUE (parm),
|
TREE_PURPOSE (parm), fn, i);
|
||||||
TREE_PURPOSE (parm),
|
t = build_call_a (fn, i, argarray);
|
||||||
fn, i++), t);
|
|
||||||
t = build_call (fn, nreverse (t));
|
|
||||||
append_to_statement_list (t, &ret);
|
append_to_statement_list (t, &ret);
|
||||||
|
|
||||||
t = fold_convert (TREE_TYPE (p1), TYPE_SIZE_UNIT (inner_type));
|
t = fold_convert (TREE_TYPE (p1), TYPE_SIZE_UNIT (inner_type));
|
||||||
|
@ -850,16 +851,16 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree t = tree_cons (NULL, build_fold_addr_expr (arg1), NULL);
|
argarray[i++] = build_fold_addr_expr (arg1);
|
||||||
if (arg2)
|
if (arg2)
|
||||||
t = tree_cons (NULL, build_fold_addr_expr (arg2), t);
|
argarray[i++] = build_fold_addr_expr (arg2);
|
||||||
/* Handle default arguments. */
|
/* Handle default arguments. */
|
||||||
i = 1 + (arg2 != NULL);
|
for (parm = defparm; parm != void_list_node;
|
||||||
for (parm = defparm; parm != void_list_node; parm = TREE_CHAIN (parm))
|
parm = TREE_CHAIN (parm), i++)
|
||||||
t = tree_cons (NULL, convert_default_arg (TREE_VALUE (parm),
|
argarray[i] = convert_default_arg (TREE_VALUE (parm),
|
||||||
TREE_PURPOSE (parm),
|
TREE_PURPOSE (parm),
|
||||||
fn, i++), t);
|
fn, i);
|
||||||
return build_call (fn, nreverse (t));
|
return build_call_a (fn, i, argarray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3859,7 +3859,8 @@ extern bool check_dtor_name (tree, tree);
|
||||||
extern tree build_vfield_ref (tree, tree);
|
extern tree build_vfield_ref (tree, tree);
|
||||||
extern tree build_conditional_expr (tree, tree, tree);
|
extern tree build_conditional_expr (tree, tree, tree);
|
||||||
extern tree build_addr_func (tree);
|
extern tree build_addr_func (tree);
|
||||||
extern tree build_call (tree, tree);
|
extern tree build_call_a (tree, int, tree*);
|
||||||
|
extern tree build_call_n (tree, int, ...);
|
||||||
extern bool null_ptr_cst_p (tree);
|
extern bool null_ptr_cst_p (tree);
|
||||||
extern bool sufficient_parms_p (tree);
|
extern bool sufficient_parms_p (tree);
|
||||||
extern tree type_decays_to (tree);
|
extern tree type_decays_to (tree);
|
||||||
|
@ -3889,7 +3890,7 @@ extern tree strip_top_quals (tree);
|
||||||
extern tree perform_implicit_conversion (tree, tree);
|
extern tree perform_implicit_conversion (tree, tree);
|
||||||
extern tree perform_direct_initialization_if_possible (tree, tree, bool);
|
extern tree perform_direct_initialization_if_possible (tree, tree, bool);
|
||||||
extern tree in_charge_arg_for_name (tree);
|
extern tree in_charge_arg_for_name (tree);
|
||||||
extern tree build_cxx_call (tree, tree);
|
extern tree build_cxx_call (tree, int, tree *);
|
||||||
#ifdef ENABLE_CHECKING
|
#ifdef ENABLE_CHECKING
|
||||||
extern void validate_conversion_obstack (void);
|
extern void validate_conversion_obstack (void);
|
||||||
#endif /* ENABLE_CHECKING */
|
#endif /* ENABLE_CHECKING */
|
||||||
|
@ -4174,6 +4175,7 @@ extern void synthesize_method (tree);
|
||||||
extern tree lazily_declare_fn (special_function_kind,
|
extern tree lazily_declare_fn (special_function_kind,
|
||||||
tree);
|
tree);
|
||||||
extern tree skip_artificial_parms_for (tree, tree);
|
extern tree skip_artificial_parms_for (tree, tree);
|
||||||
|
extern int num_artificial_parms_for (tree);
|
||||||
extern tree make_alias_for (tree, tree);
|
extern tree make_alias_for (tree, tree);
|
||||||
|
|
||||||
/* In optimize.c */
|
/* In optimize.c */
|
||||||
|
|
|
@ -5641,7 +5641,7 @@ expand_static_init (tree decl, tree init)
|
||||||
/* Emit code to perform this initialization but once. */
|
/* Emit code to perform this initialization but once. */
|
||||||
tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
|
tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
|
||||||
tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
|
tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
|
||||||
tree guard, guard_addr, guard_addr_list;
|
tree guard, guard_addr;
|
||||||
tree acquire_fn, release_fn, abort_fn;
|
tree acquire_fn, release_fn, abort_fn;
|
||||||
tree flag, begin;
|
tree flag, begin;
|
||||||
|
|
||||||
|
@ -5693,7 +5693,6 @@ expand_static_init (tree decl, tree init)
|
||||||
if (flag_threadsafe_statics)
|
if (flag_threadsafe_statics)
|
||||||
{
|
{
|
||||||
guard_addr = build_address (guard);
|
guard_addr = build_address (guard);
|
||||||
guard_addr_list = build_tree_list (NULL_TREE, guard_addr);
|
|
||||||
|
|
||||||
acquire_fn = get_identifier ("__cxa_guard_acquire");
|
acquire_fn = get_identifier ("__cxa_guard_acquire");
|
||||||
release_fn = get_identifier ("__cxa_guard_release");
|
release_fn = get_identifier ("__cxa_guard_release");
|
||||||
|
@ -5715,7 +5714,7 @@ expand_static_init (tree decl, tree init)
|
||||||
}
|
}
|
||||||
|
|
||||||
inner_if_stmt = begin_if_stmt ();
|
inner_if_stmt = begin_if_stmt ();
|
||||||
finish_if_stmt_cond (build_call (acquire_fn, guard_addr_list),
|
finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
|
||||||
inner_if_stmt);
|
inner_if_stmt);
|
||||||
|
|
||||||
inner_then_clause = begin_compound_stmt (BCS_NO_SCOPE);
|
inner_then_clause = begin_compound_stmt (BCS_NO_SCOPE);
|
||||||
|
@ -5725,7 +5724,7 @@ expand_static_init (tree decl, tree init)
|
||||||
TARGET_EXPR_CLEANUP (begin)
|
TARGET_EXPR_CLEANUP (begin)
|
||||||
= build3 (COND_EXPR, void_type_node, flag,
|
= build3 (COND_EXPR, void_type_node, flag,
|
||||||
void_zero_node,
|
void_zero_node,
|
||||||
build_call (abort_fn, guard_addr_list));
|
build_call_n (abort_fn, 1, guard_addr));
|
||||||
CLEANUP_EH_ONLY (begin) = 1;
|
CLEANUP_EH_ONLY (begin) = 1;
|
||||||
|
|
||||||
/* Do the initialization itself. */
|
/* Do the initialization itself. */
|
||||||
|
@ -5733,7 +5732,7 @@ expand_static_init (tree decl, tree init)
|
||||||
init = add_stmt_to_compound
|
init = add_stmt_to_compound
|
||||||
(init, build2 (MODIFY_EXPR, void_type_node, flag, boolean_true_node));
|
(init, build2 (MODIFY_EXPR, void_type_node, flag, boolean_true_node));
|
||||||
init = add_stmt_to_compound
|
init = add_stmt_to_compound
|
||||||
(init, build_call (release_fn, guard_addr_list));
|
(init, build_call_n (release_fn, 1, guard_addr));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
init = add_stmt_to_compound (init, set_guard (guard));
|
init = add_stmt_to_compound (init, set_guard (guard));
|
||||||
|
|
|
@ -99,7 +99,7 @@ cp_protect_cleanup_actions (void)
|
||||||
|
|
||||||
When the destruction of an object during stack unwinding exits
|
When the destruction of an object during stack unwinding exits
|
||||||
using an exception ... void terminate(); is called. */
|
using an exception ... void terminate(); is called. */
|
||||||
return build_call (terminate_node, NULL_TREE);
|
return build_call_n (terminate_node, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
|
|
|
@ -1540,7 +1540,7 @@ static tree
|
||||||
build_builtin_delete_call (tree addr)
|
build_builtin_delete_call (tree addr)
|
||||||
{
|
{
|
||||||
mark_used (global_delete_fndecl);
|
mark_used (global_delete_fndecl);
|
||||||
return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
|
return build_call_n (global_delete_fndecl, 1, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build and return a NEW_EXPR. If NELTS is non-NULL, TYPE[NELTS] is
|
/* Build and return a NEW_EXPR. If NELTS is non-NULL, TYPE[NELTS] is
|
||||||
|
|
|
@ -452,6 +452,8 @@ use_thunk (tree thunk_fndecl, bool emit_p)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
tree *argarray = (tree *) alloca (list_length (a) * sizeof (tree));
|
||||||
/* If this is a covariant thunk, or we don't have the necessary
|
/* If this is a covariant thunk, or we don't have the necessary
|
||||||
code for efficient thunks, generate a thunk function that
|
code for efficient thunks, generate a thunk function that
|
||||||
just makes a call to the real function. Unfortunately, this
|
just makes a call to the real function. Unfortunately, this
|
||||||
|
@ -475,11 +477,10 @@ use_thunk (tree thunk_fndecl, bool emit_p)
|
||||||
fixed_offset, virtual_offset);
|
fixed_offset, virtual_offset);
|
||||||
|
|
||||||
/* Build up the call to the real function. */
|
/* Build up the call to the real function. */
|
||||||
t = tree_cons (NULL_TREE, t, NULL_TREE);
|
argarray[0] = t;
|
||||||
for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
|
for (i = 1, a = TREE_CHAIN (a); a; a = TREE_CHAIN (a), i++)
|
||||||
t = tree_cons (NULL_TREE, a, t);
|
argarray[i] = a;
|
||||||
t = nreverse (t);
|
t = build_call_a (alias, i, argarray);
|
||||||
t = build_call (alias, t);
|
|
||||||
CALL_FROM_THUNK_P (t) = 1;
|
CALL_FROM_THUNK_P (t) = 1;
|
||||||
|
|
||||||
if (VOID_TYPE_P (TREE_TYPE (t)))
|
if (VOID_TYPE_P (TREE_TYPE (t)))
|
||||||
|
@ -1191,4 +1192,25 @@ skip_artificial_parms_for (tree fn, tree list)
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given a FUNCTION_DECL FN and a chain LIST, return the number of
|
||||||
|
artificial parms in FN. */
|
||||||
|
|
||||||
|
int
|
||||||
|
num_artificial_parms_for (tree fn)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
|
||||||
|
count++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (DECL_HAS_IN_CHARGE_PARM_P (fn))
|
||||||
|
count++;
|
||||||
|
if (DECL_HAS_VTT_PARM_P (fn))
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "gt-cp-method.h"
|
#include "gt-cp-method.h"
|
||||||
|
|
|
@ -196,7 +196,7 @@ throw_bad_cast (void)
|
||||||
fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
|
fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
|
||||||
void_list_node));
|
void_list_node));
|
||||||
|
|
||||||
return build_cxx_call (fn, NULL_TREE);
|
return build_cxx_call (fn, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return an expression for "__cxa_bad_typeid()". The expression
|
/* Return an expression for "__cxa_bad_typeid()". The expression
|
||||||
|
@ -215,7 +215,7 @@ throw_bad_typeid (void)
|
||||||
fn = push_throw_library_fn (fn, t);
|
fn = push_throw_library_fn (fn, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return build_cxx_call (fn, NULL_TREE);
|
return build_cxx_call (fn, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return an lvalue expression whose type is "const std::type_info"
|
/* Return an lvalue expression whose type is "const std::type_info"
|
||||||
|
@ -588,7 +588,8 @@ build_dynamic_cast_1 (tree type, tree expr)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree retval;
|
tree retval;
|
||||||
tree result, td2, td3, elems;
|
tree result, td2, td3;
|
||||||
|
tree elems[4];
|
||||||
tree static_type, target_type, boff;
|
tree static_type, target_type, boff;
|
||||||
|
|
||||||
/* If we got here, we can't convert statically. Therefore,
|
/* If we got here, we can't convert statically. Therefore,
|
||||||
|
@ -646,11 +647,10 @@ build_dynamic_cast_1 (tree type, tree expr)
|
||||||
if (tc == REFERENCE_TYPE)
|
if (tc == REFERENCE_TYPE)
|
||||||
expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
|
expr1 = build_unary_op (ADDR_EXPR, expr1, 0);
|
||||||
|
|
||||||
elems = tree_cons
|
elems[0] = expr1;
|
||||||
(NULL_TREE, expr1, tree_cons
|
elems[1] = td3;
|
||||||
(NULL_TREE, td3, tree_cons
|
elems[2] = td2;
|
||||||
(NULL_TREE, td2, tree_cons
|
elems[3] = boff;
|
||||||
(NULL_TREE, boff, NULL_TREE))));
|
|
||||||
|
|
||||||
dcast_fn = dynamic_cast_node;
|
dcast_fn = dynamic_cast_node;
|
||||||
if (!dcast_fn)
|
if (!dcast_fn)
|
||||||
|
@ -680,7 +680,7 @@ build_dynamic_cast_1 (tree type, tree expr)
|
||||||
pop_nested_namespace (ns);
|
pop_nested_namespace (ns);
|
||||||
dynamic_cast_node = dcast_fn;
|
dynamic_cast_node = dcast_fn;
|
||||||
}
|
}
|
||||||
result = build_cxx_call (dcast_fn, elems);
|
result = build_cxx_call (dcast_fn, 4, elems);
|
||||||
|
|
||||||
if (tc == REFERENCE_TYPE)
|
if (tc == REFERENCE_TYPE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,7 +60,7 @@ static void casts_away_constness_r (tree *, tree *);
|
||||||
static bool casts_away_constness (tree, tree);
|
static bool casts_away_constness (tree, tree);
|
||||||
static void maybe_warn_about_returning_address_of_local (tree);
|
static void maybe_warn_about_returning_address_of_local (tree);
|
||||||
static tree lookup_destructor (tree, tree, tree);
|
static tree lookup_destructor (tree, tree, tree);
|
||||||
static tree convert_arguments (tree, tree, tree, int);
|
static int convert_arguments (int, tree *, tree, tree, tree, int);
|
||||||
|
|
||||||
/* Do `exp = require_complete_type (exp);' to make sure exp
|
/* Do `exp = require_complete_type (exp);' to make sure exp
|
||||||
does not have an incomplete type. (That includes void types.)
|
does not have an incomplete type. (That includes void types.)
|
||||||
|
@ -2670,10 +2670,12 @@ tree
|
||||||
build_function_call (tree function, tree params)
|
build_function_call (tree function, tree params)
|
||||||
{
|
{
|
||||||
tree fntype, fndecl;
|
tree fntype, fndecl;
|
||||||
tree coerced_params;
|
|
||||||
tree name = NULL_TREE;
|
tree name = NULL_TREE;
|
||||||
int is_method;
|
int is_method;
|
||||||
tree original = function;
|
tree original = function;
|
||||||
|
int nargs, parm_types_len;
|
||||||
|
tree *argarray;
|
||||||
|
tree parm_types;
|
||||||
|
|
||||||
/* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
|
/* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
|
||||||
expressions, like those used for ObjC messenger dispatches. */
|
expressions, like those used for ObjC messenger dispatches. */
|
||||||
|
@ -2739,22 +2741,29 @@ build_function_call (tree function, tree params)
|
||||||
|
|
||||||
/* fntype now gets the type of function pointed to. */
|
/* fntype now gets the type of function pointed to. */
|
||||||
fntype = TREE_TYPE (fntype);
|
fntype = TREE_TYPE (fntype);
|
||||||
|
parm_types = TYPE_ARG_TYPES (fntype);
|
||||||
|
|
||||||
|
/* Allocate storage for converted arguments. */
|
||||||
|
parm_types_len = list_length (parm_types);
|
||||||
|
nargs = list_length (params);
|
||||||
|
if (parm_types_len > nargs)
|
||||||
|
nargs = parm_types_len;
|
||||||
|
argarray = (tree *) alloca (nargs * sizeof (tree));
|
||||||
|
|
||||||
/* Convert the parameters to the types declared in the
|
/* Convert the parameters to the types declared in the
|
||||||
function prototype, or apply default promotions. */
|
function prototype, or apply default promotions. */
|
||||||
|
nargs = convert_arguments (nargs, argarray, parm_types,
|
||||||
coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
|
params, fndecl, LOOKUP_NORMAL);
|
||||||
params, fndecl, LOOKUP_NORMAL);
|
if (nargs < 0)
|
||||||
if (coerced_params == error_mark_node)
|
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
|
|
||||||
/* Check for errors in format strings and inappropriately
|
/* Check for errors in format strings and inappropriately
|
||||||
null parameters. */
|
null parameters. */
|
||||||
|
|
||||||
check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params,
|
check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
|
||||||
TYPE_ARG_TYPES (fntype));
|
parm_types);
|
||||||
|
|
||||||
return build_cxx_call (function, coerced_params);
|
return build_cxx_call (function, nargs, argarray);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the actual parameter expressions in the list VALUES
|
/* Convert the actual parameter expressions in the list VALUES
|
||||||
|
@ -2762,23 +2771,26 @@ build_function_call (tree function, tree params)
|
||||||
If parmdecls is exhausted, or when an element has NULL as its type,
|
If parmdecls is exhausted, or when an element has NULL as its type,
|
||||||
perform the default conversions.
|
perform the default conversions.
|
||||||
|
|
||||||
|
Store the converted arguments in ARGARRAY. NARGS is the size of this array.
|
||||||
|
|
||||||
NAME is an IDENTIFIER_NODE or 0. It is used only for error messages.
|
NAME is an IDENTIFIER_NODE or 0. It is used only for error messages.
|
||||||
|
|
||||||
This is also where warnings about wrong number of args are generated.
|
This is also where warnings about wrong number of args are generated.
|
||||||
|
|
||||||
Return a list of expressions for the parameters as converted.
|
Returns the actual number of arguments processed (which might be less
|
||||||
|
than NARGS), or -1 on error.
|
||||||
|
|
||||||
Both VALUES and the returned value are chains of TREE_LIST nodes
|
VALUES is a chain of TREE_LIST nodes with the elements of the list
|
||||||
with the elements of the list in the TREE_VALUE slots of those nodes.
|
in the TREE_VALUE slots of those nodes.
|
||||||
|
|
||||||
In C++, unspecified trailing parameters can be filled in with their
|
In C++, unspecified trailing parameters can be filled in with their
|
||||||
default arguments, if such were specified. Do so here. */
|
default arguments, if such were specified. Do so here. */
|
||||||
|
|
||||||
static tree
|
static int
|
||||||
convert_arguments (tree typelist, tree values, tree fndecl, int flags)
|
convert_arguments (int nargs, tree *argarray,
|
||||||
|
tree typelist, tree values, tree fndecl, int flags)
|
||||||
{
|
{
|
||||||
tree typetail, valtail;
|
tree typetail, valtail;
|
||||||
tree result = NULL_TREE;
|
|
||||||
const char *called_thing = 0;
|
const char *called_thing = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -2807,7 +2819,7 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
|
||||||
tree val = TREE_VALUE (valtail);
|
tree val = TREE_VALUE (valtail);
|
||||||
|
|
||||||
if (val == error_mark_node || type == error_mark_node)
|
if (val == error_mark_node || type == error_mark_node)
|
||||||
return error_mark_node;
|
return -1;
|
||||||
|
|
||||||
if (type == void_type_node)
|
if (type == void_type_node)
|
||||||
{
|
{
|
||||||
|
@ -2818,11 +2830,7 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error ("too many arguments to function");
|
error ("too many arguments to function");
|
||||||
/* In case anybody wants to know if this argument
|
return i;
|
||||||
list is valid. */
|
|
||||||
if (result)
|
|
||||||
TREE_TYPE (tree_last (result)) = error_mark_node;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
|
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
|
||||||
|
@ -2841,7 +2849,7 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val == error_mark_node)
|
if (val == error_mark_node)
|
||||||
return error_mark_node;
|
return -1;
|
||||||
|
|
||||||
if (type != 0)
|
if (type != 0)
|
||||||
{
|
{
|
||||||
|
@ -2866,9 +2874,9 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parmval == error_mark_node)
|
if (parmval == error_mark_node)
|
||||||
return error_mark_node;
|
return -1;
|
||||||
|
|
||||||
result = tree_cons (NULL_TREE, parmval, result);
|
argarray[i] = parmval;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2881,7 +2889,7 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
|
||||||
else
|
else
|
||||||
val = convert_arg_to_ellipsis (val);
|
val = convert_arg_to_ellipsis (val);
|
||||||
|
|
||||||
result = tree_cons (NULL_TREE, val, result);
|
argarray[i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typetail)
|
if (typetail)
|
||||||
|
@ -2902,9 +2910,9 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
|
||||||
fndecl, i);
|
fndecl, i);
|
||||||
|
|
||||||
if (parmval == error_mark_node)
|
if (parmval == error_mark_node)
|
||||||
return error_mark_node;
|
return -1;
|
||||||
|
|
||||||
result = tree_cons (0, parmval, result);
|
argarray[i] = parmval;
|
||||||
typetail = TREE_CHAIN (typetail);
|
typetail = TREE_CHAIN (typetail);
|
||||||
/* ends with `...'. */
|
/* ends with `...'. */
|
||||||
if (typetail == NULL_TREE)
|
if (typetail == NULL_TREE)
|
||||||
|
@ -2920,11 +2928,12 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error ("too few arguments to function");
|
error ("too few arguments to function");
|
||||||
return error_mark_node;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nreverse (result);
|
gcc_assert (i <= nargs);
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a binary-operation expression, after performing default
|
/* Build a binary-operation expression, after performing default
|
||||||
|
|
|
@ -12875,13 +12875,13 @@ fold_build3_stat (enum tree_code code, tree type, tree op0, tree op1, tree op2
|
||||||
return tem;
|
return tem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fold a CALL_EXPR expression of type TYPE with operands FN and ARGLIST
|
/* Fold a CALL_EXPR expression of type TYPE with operands FN and NARGS
|
||||||
and a null static chain.
|
arguments in ARGARRAY, and a null static chain.
|
||||||
Return a folded expression if successful. Otherwise, return a CALL_EXPR
|
Return a folded expression if successful. Otherwise, return a CALL_EXPR
|
||||||
of type TYPE from the given operands as constructed by build_call_list. */
|
of type TYPE from the given operands as constructed by build_call_array. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
fold_build_call_list (tree type, tree fn, tree arglist)
|
fold_build_call_array (tree type, tree fn, int nargs, tree *argarray)
|
||||||
{
|
{
|
||||||
tree tem;
|
tree tem;
|
||||||
#ifdef ENABLE_FOLD_CHECKING
|
#ifdef ENABLE_FOLD_CHECKING
|
||||||
|
@ -12891,6 +12891,7 @@ fold_build_call_list (tree type, tree fn, tree arglist)
|
||||||
checksum_after_arglist[16];
|
checksum_after_arglist[16];
|
||||||
struct md5_ctx ctx;
|
struct md5_ctx ctx;
|
||||||
htab_t ht;
|
htab_t ht;
|
||||||
|
int i;
|
||||||
|
|
||||||
ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
|
ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
|
||||||
md5_init_ctx (&ctx);
|
md5_init_ctx (&ctx);
|
||||||
|
@ -12899,12 +12900,13 @@ fold_build_call_list (tree type, tree fn, tree arglist)
|
||||||
htab_empty (ht);
|
htab_empty (ht);
|
||||||
|
|
||||||
md5_init_ctx (&ctx);
|
md5_init_ctx (&ctx);
|
||||||
fold_checksum_tree (arglist, &ctx, ht);
|
for (i = 0; i < nargs; i++)
|
||||||
|
fold_checksum_tree (argarray[i], &ctx, ht);
|
||||||
md5_finish_ctx (&ctx, checksum_before_arglist);
|
md5_finish_ctx (&ctx, checksum_before_arglist);
|
||||||
htab_empty (ht);
|
htab_empty (ht);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tem = fold_builtin_call_list (type, fn, arglist);
|
tem = fold_builtin_call_array (type, fn, nargs, argarray);
|
||||||
|
|
||||||
#ifdef ENABLE_FOLD_CHECKING
|
#ifdef ENABLE_FOLD_CHECKING
|
||||||
md5_init_ctx (&ctx);
|
md5_init_ctx (&ctx);
|
||||||
|
@ -12916,12 +12918,13 @@ fold_build_call_list (tree type, tree fn, tree arglist)
|
||||||
fold_check_failed (fn, tem);
|
fold_check_failed (fn, tem);
|
||||||
|
|
||||||
md5_init_ctx (&ctx);
|
md5_init_ctx (&ctx);
|
||||||
fold_checksum_tree (arglist, &ctx, ht);
|
for (i = 0; i < nargs; i++)
|
||||||
|
fold_checksum_tree (argarray[i], &ctx, ht);
|
||||||
md5_finish_ctx (&ctx, checksum_after_arglist);
|
md5_finish_ctx (&ctx, checksum_after_arglist);
|
||||||
htab_delete (ht);
|
htab_delete (ht);
|
||||||
|
|
||||||
if (memcmp (checksum_before_arglist, checksum_after_arglist, 16))
|
if (memcmp (checksum_before_arglist, checksum_after_arglist, 16))
|
||||||
fold_check_failed (arglist, tem);
|
fold_check_failed (NULL_TREE, tem);
|
||||||
#endif
|
#endif
|
||||||
return tem;
|
return tem;
|
||||||
}
|
}
|
||||||
|
@ -12987,12 +12990,13 @@ fold_build3_initializer (enum tree_code code, tree type, tree op0, tree op1,
|
||||||
}
|
}
|
||||||
|
|
||||||
tree
|
tree
|
||||||
fold_build_call_list_initializer (tree type, tree fn, tree arglist)
|
fold_build_call_array_initializer (tree type, tree fn,
|
||||||
|
int nargs, tree *argarray)
|
||||||
{
|
{
|
||||||
tree result;
|
tree result;
|
||||||
START_FOLD_INIT;
|
START_FOLD_INIT;
|
||||||
|
|
||||||
result = fold_build_call_list (type, fn, arglist);
|
result = fold_build_call_array (type, fn, nargs, argarray);
|
||||||
|
|
||||||
END_FOLD_INIT;
|
END_FOLD_INIT;
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -4397,8 +4397,8 @@ extern tree fold_build3_stat (enum tree_code, tree, tree, tree, tree MEM_STAT_DE
|
||||||
extern tree fold_build1_initializer (enum tree_code, tree, tree);
|
extern tree fold_build1_initializer (enum tree_code, tree, tree);
|
||||||
extern tree fold_build2_initializer (enum tree_code, tree, tree, tree);
|
extern tree fold_build2_initializer (enum tree_code, tree, tree, tree);
|
||||||
extern tree fold_build3_initializer (enum tree_code, tree, tree, tree, tree);
|
extern tree fold_build3_initializer (enum tree_code, tree, tree, tree, tree);
|
||||||
extern tree fold_build_call_list (tree, tree, tree);
|
extern tree fold_build_call_array (tree, tree, int, tree *);
|
||||||
extern tree fold_build_call_list_initializer (tree, tree, tree);
|
extern tree fold_build_call_array_initializer (tree, tree, int, tree *);
|
||||||
extern tree fold_convert (tree, tree);
|
extern tree fold_convert (tree, tree);
|
||||||
extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
|
extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
|
||||||
extern tree fold_ignored_result (tree);
|
extern tree fold_ignored_result (tree);
|
||||||
|
@ -4497,8 +4497,7 @@ extern bool fold_builtin_next_arg (tree, bool);
|
||||||
extern enum built_in_function builtin_mathfn_code (tree);
|
extern enum built_in_function builtin_mathfn_code (tree);
|
||||||
extern tree build_function_call_expr (tree, tree);
|
extern tree build_function_call_expr (tree, tree);
|
||||||
extern tree fold_build_call_expr (tree, tree, tree, tree);
|
extern tree fold_build_call_expr (tree, tree, tree, tree);
|
||||||
extern tree fold_builtin_call_list (tree, tree, tree);
|
extern tree fold_builtin_call_array (tree, tree, int, tree *);
|
||||||
extern tree fold_builtin_call_valist (tree, tree, int, va_list);
|
|
||||||
extern tree build_call_expr (tree, int, ...);
|
extern tree build_call_expr (tree, int, ...);
|
||||||
extern tree mathfn_built_in (tree, enum built_in_function fn);
|
extern tree mathfn_built_in (tree, enum built_in_function fn);
|
||||||
extern tree strip_float_extensions (tree);
|
extern tree strip_float_extensions (tree);
|
||||||
|
|
Loading…
Reference in New Issue