aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/call.c220
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/init.c63
-rw-r--r--gcc/cp/typeck.c35
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/16077.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.warn/impint2.C2
8 files changed, 199 insertions, 146 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 93d3f22..4595203 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,7 +1,22 @@
+2003-03-10 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (perform_overload_resolution): New function.
+ (build_new_function_call): Use it.
+ (build_operator_new_call): Likewise.
+ (add_candidates): Add explicit_targs and template_only parameters.
+ (build_new_op): Adjust accordingly.
+ * cp-tree.h (build_operator_new_call): New function.
+ (build_function_call_real): Remove.
+ (build_function_call_maybe): Likewise.
+ * init.c (build_new_1): Use build_operator_new_call.
+ * typeck.c (build_function_call_real): Rename to ...
+ (build_function_call): ... this.
+
2003-03-10 Devang Patel <dpatel@apple.com>
PR c++/9394
* g++spec.c (lang_specific_driver): Use DEFAULT_WORD_SWTCH_TAKES_ARG.
+
2003-03-10 Jason Merrill <jason@redhat.com>
PR c++/9798
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4609762..ed9227f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -104,7 +104,7 @@ static tree conditional_conversion (tree, tree);
static char *name_as_c_string (tree, tree, bool *);
static tree call_builtin_trap (void);
static tree prep_operand (tree);
-static void add_candidates (tree, tree, tree, tree,
+static void add_candidates (tree, tree, tree, bool, tree, tree,
int, struct z_candidate **);
static tree merge_conversion_sequences (tree, tree);
@@ -2754,16 +2754,31 @@ resolve_args (tree args)
return args;
}
-/* Return an expression for a call to FN (a namespace-scope function,
- or a static member function) with the ARGS. */
-
-tree
-build_new_function_call (tree fn, tree args)
+/* Perform overload resolution on FN, which is called with the ARGS.
+
+ Return the candidate function selected by overload resolution, or
+ NULL if the event that overload resolution failed. In the case
+ that overload resolution fails, *CANDIDATES will be the set of
+ candidates considered, and ANY_VIABLE_P will be set to true or
+ false to indicate whether or not any of the candidates were
+ viable.
+
+ The ARGS should already have gone through RESOLVE_ARGS before this
+ function is called. */
+
+static struct z_candidate *
+perform_overload_resolution (tree fn,
+ tree args,
+ struct z_candidate **candidates,
+ bool *any_viable_p)
{
- struct z_candidate *candidates = 0, *cand;
+ struct z_candidate *cand;
tree explicit_targs = NULL_TREE;
int template_only = 0;
+ *candidates = NULL;
+ *any_viable_p = true;
+
/* Check FN and ARGS. */
my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL
|| TREE_CODE (fn) == TEMPLATE_DECL
@@ -2780,63 +2795,146 @@ build_new_function_call (tree fn, tree args)
template_only = 1;
}
- if (really_overloaded_fn (fn)
- || TREE_CODE (fn) == TEMPLATE_DECL)
+ /* Add the various candidate functions. */
+ add_candidates (fn, args, explicit_targs, template_only,
+ /*conversion_path=*/NULL_TREE,
+ /*access_path=*/NULL_TREE,
+ LOOKUP_NORMAL,
+ candidates);
+
+ if (! any_viable (*candidates))
{
- tree t1;
+ *any_viable_p = false;
+ return NULL;
+ }
- args = resolve_args (args);
+ *candidates = splice_viable (*candidates);
+ cand = tourney (*candidates);
- if (args == error_mark_node)
- return error_mark_node;
+ return cand;
+}
- for (t1 = fn; t1; t1 = OVL_NEXT (t1))
- {
- tree t = OVL_CURRENT (t1);
+/* Return an expression for a call to FN (a namespace-scope function,
+ or a static member function) with the ARGS. */
+
+tree
+build_new_function_call (tree fn, tree args)
+{
+ struct z_candidate *candidates, *cand;
+ bool any_viable_p;
- my_friendly_assert (!DECL_FUNCTION_MEMBER_P (t), 20020913);
+ args = resolve_args (args);
+ if (args == error_mark_node)
+ return error_mark_node;
- if (TREE_CODE (t) == TEMPLATE_DECL)
- add_template_candidate
- (&candidates, t, NULL_TREE, explicit_targs, args,
- NULL_TREE, /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE,
- LOOKUP_NORMAL, DEDUCE_CALL);
- else if (! template_only)
- add_function_candidate
- (&candidates, t, NULL_TREE, args,
- /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE, LOOKUP_NORMAL);
- }
+ cand = perform_overload_resolution (fn, args, &candidates, &any_viable_p);
- if (! any_viable (candidates))
- {
- if (candidates && ! candidates->next)
- return build_function_call (candidates->fn, args);
- error ("no matching function for call to `%D(%A)'",
- DECL_NAME (OVL_CURRENT (fn)), args);
- if (candidates)
- print_z_candidates (candidates);
- return error_mark_node;
- }
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
+ if (!cand)
+ {
+ if (!any_viable_p && candidates && ! candidates->next)
+ return build_function_call (candidates->fn, args);
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ fn = TREE_OPERAND (fn, 0);
+ if (!any_viable_p)
+ error ("no matching function for call to `%D(%A)'",
+ DECL_NAME (OVL_CURRENT (fn)), args);
+ else
+ error ("call of overloaded `%D(%A)' is ambiguous",
+ DECL_NAME (OVL_FUNCTION (fn)), args);
+ if (candidates)
+ print_z_candidates (candidates);
+ return error_mark_node;
+ }
- if (cand == 0)
- {
- error ("call of overloaded `%D(%A)' is ambiguous",
- DECL_NAME (OVL_FUNCTION (fn)), args);
- print_z_candidates (candidates);
- return error_mark_node;
- }
+ return build_over_call (cand, LOOKUP_NORMAL);
+}
- return build_over_call (cand, LOOKUP_NORMAL);
- }
+/* Build a call to a global operator new. FNNAME is the name of the
+ operator (either "operator new" or "operator new[]") and ARGS are
+ the arguments provided. *SIZE points to the total number of bytes
+ required by the allocation, and is updated if that is changed here.
+ *COOKIE_SIZE is non-NULL if a cookie should be used. If this
+ function determins that no cookie should be used, after all,
+ *COOKIE_SIZE is set to NULL_TREE. */
- /* This is not really overloaded. */
- fn = OVL_CURRENT (fn);
+tree
+build_operator_new_call (tree fnname, tree args, tree *size, tree *cookie_size)
+{
+ tree fns;
+ struct z_candidate *candidates;
+ struct z_candidate *cand;
+ bool any_viable_p;
+
+ args = tree_cons (NULL_TREE, *size, args);
+ args = resolve_args (args);
+ if (args == error_mark_node)
+ return args;
+
+ fns = lookup_function_nonclass (fnname, args);
+
+ /* Figure out what function is being called. */
+ cand = perform_overload_resolution (fns, args, &candidates, &any_viable_p);
+
+ /* If no suitable function could be found, issue an error message
+ and give up. */
+ if (!cand)
+ {
+ if (!any_viable_p)
+ error ("no matching function for call to `%D(%A)'",
+ DECL_NAME (OVL_CURRENT (fns)), args);
+ else
+ error ("call of overlopaded `%D(%A)' is ambiguous",
+ DECL_NAME (OVL_FUNCTION (fns)), args);
+ if (candidates)
+ print_z_candidates (candidates);
+ return error_mark_node;
+ }
- return build_function_call (fn, args);
+ /* If a cookie is required, add some extra space. Whether
+ or not a cookie is required cannot be determined until
+ after we know which function was called. */
+ if (*cookie_size)
+ {
+ bool use_cookie = true;
+ if (!abi_version_at_least (2))
+ {
+ tree placement = TREE_CHAIN (args);
+ /* In G++ 3.2, the check was implemented incorrectly; it
+ looked at the placement expression, rather than the
+ type of the function. */
+ if (placement && !TREE_CHAIN (placement)
+ && same_type_p (TREE_TYPE (TREE_VALUE (placement)),
+ ptr_type_node))
+ use_cookie = false;
+ }
+ else
+ {
+ tree arg_types;
+
+ arg_types = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+ /* Skip the size_t parameter. */
+ arg_types = TREE_CHAIN (arg_types);
+ /* Check the remaining parameters (if any). */
+ if (arg_types
+ && TREE_CHAIN (arg_types) == void_list_node
+ && same_type_p (TREE_VALUE (arg_types),
+ ptr_type_node))
+ use_cookie = false;
+ }
+ /* If we need a cookie, adjust the number of bytes allocated. */
+ if (use_cookie)
+ {
+ /* Update the total size. */
+ *size = size_binop (PLUS_EXPR, *size, *cookie_size);
+ /* Update the argument list to reflect the adjusted size. */
+ TREE_VALUE (args) = *size;
+ }
+ else
+ *cookie_size = NULL_TREE;
+ }
+
+ /* Build the CALL_EXPR. */
+ return build_over_call (cand, LOOKUP_NORMAL);
}
static tree
@@ -3396,11 +3494,14 @@ prep_operand (tree operand)
/* Add each of the viable functions in FNS (a FUNCTION_DECL or
OVERLOAD) to the CANDIDATES, returning an updated list of
CANDIDATES. The ARGS are the arguments provided to the call,
- without any implicit object parameter. CONVERSION_PATH,
+ without any implicit object parameter. The EXPLICIT_TARGS are
+ explicit template arguments provided. TEMPLATE_ONLY is true if
+ only template fucntions should be considered. CONVERSION_PATH,
ACCESS_PATH, and FLAGS are as for add_function_candidate. */
static void
-add_candidates (tree fns, tree args,
+add_candidates (tree fns, tree args,
+ tree explicit_targs, bool template_only,
tree conversion_path, tree access_path,
int flags,
struct z_candidate **candidates)
@@ -3419,7 +3520,7 @@ add_candidates (tree fns, tree args,
fn = OVL_CURRENT (fns);
/* Figure out which set of arguments to use. */
- if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
{
/* If this function is a non-static member, prepend the implicit
object parameter. */
@@ -3437,14 +3538,14 @@ add_candidates (tree fns, tree args,
add_template_candidate (candidates,
fn,
ctype,
- NULL_TREE,
+ explicit_targs,
fn_args,
NULL_TREE,
access_path,
conversion_path,
flags,
DEDUCE_CALL);
- else
+ else if (!template_only)
add_function_candidate (candidates,
fn,
ctype,
@@ -3527,7 +3628,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
/* Add namespace-scope operators to the list of functions to
consider. */
add_candidates (lookup_function_nonclass (fnname, arglist),
- arglist, NULL_TREE, NULL_TREE,
+ arglist, NULL_TREE, false, NULL_TREE, NULL_TREE,
flags, &candidates);
/* Add class-member operators to the candidate set. */
if (CLASS_TYPE_P (TREE_TYPE (arg1)))
@@ -3539,6 +3640,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
return fns;
if (fns)
add_candidates (BASELINK_FUNCTIONS (fns), arglist,
+ NULL_TREE, false,
BASELINK_BINFO (fns),
TYPE_BINFO (TREE_TYPE (arg1)),
flags, &candidates);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6908291..a45e546 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3564,6 +3564,7 @@ extern tree type_decays_to (tree);
extern tree resolve_scoped_fn_name (tree, tree);
extern tree build_user_type_conversion (tree, tree, int);
extern tree build_new_function_call (tree, tree);
+extern tree build_operator_new_call (tree, tree, tree *, tree *);
extern tree build_new_method_call (tree, tree, tree, tree, int);
extern tree build_special_member_call (tree, tree, tree, tree, int);
extern tree build_new_op (enum tree_code, int, tree, tree, tree);
@@ -4324,8 +4325,6 @@ extern tree build_x_indirect_ref (tree, const char *);
extern tree build_indirect_ref (tree, const char *);
extern tree build_array_ref (tree, tree);
extern tree get_member_function_from_ptrfunc (tree *, tree);
-extern tree build_function_call_real (tree, tree, int, int);
-extern tree build_function_call_maybe (tree, tree);
extern tree convert_arguments (tree, tree, tree, int);
extern tree build_x_binary_op (enum tree_code, tree, tree);
extern tree build_x_unary_op (enum tree_code, tree);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index e7cba7a..99812c6 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2167,7 +2167,6 @@ build_new_1 (exp)
/* Nonzero if the user wrote `::new' rather than just `new'. */
int globally_qualified_p;
int use_java_new = 0;
- bool check_cookie = false;
/* If non-NULL, the number of extra bytes to allocate at the
beginning of the storage allocated for an array-new expression in
order to store the number of elements. */
@@ -2272,14 +2271,14 @@ build_new_1 (exp)
else
{
/* Use a global operator new. */
- /* Create the argument list. */
- args = tree_cons (NULL_TREE, size, placement);
- /* Call the function. */
- alloc_call
- = build_new_function_call (lookup_function_nonclass (fnname, args),
- args);
- /* We may need to add a cookie. */
- check_cookie = true;
+ /* See if a cookie might be required. */
+ if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
+ cookie_size = get_cookie_size (true_type);
+ else
+ cookie_size = NULL_TREE;
+
+ alloc_call = build_operator_new_call (fnname, placement,
+ &size, &cookie_size);
}
}
@@ -2295,52 +2294,6 @@ build_new_1 (exp)
alloc_fn = get_callee_fndecl (t);
my_friendly_assert (alloc_fn != NULL_TREE, 20020325);
- /* If we postponed deciding whether or not to use a cookie until
- after we knew what function was being called, that time is
- now. */
- if (check_cookie)
- {
- /* If a cookie is required, add some extra space. Whether
- or not a cookie is required cannot be determined until
- after we know which function was called. */
- if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
- {
- bool use_cookie = true;
- if (!abi_version_at_least (2))
- {
- /* In G++ 3.2, the check was implemented incorrectly; it
- looked at the placement expression, rather than the
- type of the function. */
- if (placement && !TREE_CHAIN (placement)
- && same_type_p (TREE_TYPE (TREE_VALUE (placement)),
- ptr_type_node))
- use_cookie = false;
- }
- else
- {
- tree arg_types;
-
- arg_types = TYPE_ARG_TYPES (TREE_TYPE (alloc_fn));
- /* Skip the size_t parameter. */
- arg_types = TREE_CHAIN (arg_types);
- /* Check the remaining parameters (if any). */
- if (arg_types
- && !TREE_CHAIN (arg_types)
- && same_type_p (TREE_TYPE (TREE_VALUE (arg_types)),
- ptr_type_node))
- use_cookie = false;
- }
- /* If we need a cookie, adjust the number of bytes allocated. */
- if (use_cookie)
- {
- cookie_size = get_cookie_size (true_type);
- size = size_binop (PLUS_EXPR, size, cookie_size);
- /* Update the argument list to reflect the adjusted size. */
- TREE_VALUE (args) = cookie_size;
- }
- }
- }
-
/* Now, check to see if this function is actually a placement
allocation function. This can happen even when PLACEMENT is NULL
because we might have something like:
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 8c8e531..0cbff77 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2655,9 +2655,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
}
tree
-build_function_call_real (function, params, require_complete, flags)
+build_function_call (function, params)
tree function, params;
- int require_complete, flags;
{
register tree fntype, fndecl;
register tree value_type;
@@ -2731,20 +2730,10 @@ build_function_call_real (function, params, require_complete, flags)
/* Convert the parameters to the types declared in the
function prototype, or apply default promotions. */
- if (flags & LOOKUP_COMPLAIN)
- coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
- params, fndecl, LOOKUP_NORMAL);
- else
- coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
- params, fndecl, 0);
-
+ coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
+ params, fndecl, LOOKUP_NORMAL);
if (coerced_params == error_mark_node)
- {
- if (flags & LOOKUP_SPECULATIVELY)
- return NULL_TREE;
- else
- return error_mark_node;
- }
+ return error_mark_node;
/* Check for errors in format strings. */
@@ -2770,23 +2759,13 @@ build_function_call_real (function, params, require_complete, flags)
result = fold (build_call (function, coerced_params));
value_type = TREE_TYPE (result);
- if (require_complete)
- {
- if (TREE_CODE (value_type) == VOID_TYPE)
- return result;
- result = require_complete_type (result);
- }
+ if (TREE_CODE (value_type) == VOID_TYPE)
+ return result;
+ result = require_complete_type (result);
if (IS_AGGR_TYPE (value_type))
result = build_cplus_new (value_type, result);
return convert_from_reference (result);
}
-
-tree
-build_function_call (function, params)
- tree function, params;
-{
- return build_function_call_real (function, params, 1, LOOKUP_NORMAL);
-}
/* Convert the actual parameter expressions in the list VALUES
to the types in the list TYPELIST.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 233d4c1..705abb7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-03-10 Mark Mitchell <mark@codesourcery.com>
+
+ * g++.old-deja/g++.benjamin/16077.C: Adjust warnings.
+ * g++.old-deja/g++.warn/impint2.C: Likewise.
+
2003-03-10 Devang Patel <dpatel@apple.com>
* g++.dg/cpp/c++_cmd_1.C: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/16077.C b/gcc/testsuite/g++.old-deja/g++.benjamin/16077.C
index f38154e..3bed736 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/16077.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/16077.C
@@ -17,7 +17,7 @@ public:
operator colombia();
};
-void peace(const colombia&); // WARNING - // WARNING -
+void peace(const colombia&);
void foo(nicaragua& b) {
peace(b); // WARNING - // WARNING -
diff --git a/gcc/testsuite/g++.old-deja/g++.warn/impint2.C b/gcc/testsuite/g++.old-deja/g++.warn/impint2.C
index 73e706e..a522ffc 100644
--- a/gcc/testsuite/g++.old-deja/g++.warn/impint2.C
+++ b/gcc/testsuite/g++.old-deja/g++.warn/impint2.C
@@ -13,7 +13,7 @@ struct X
X (int const &, int const &);
};
-void foo (int const &); // WARNING - in passing
+void foo (int const &);
void wibble (int const &);
void wibble (int const &, int const &);
void punk (int const & = 3.5f); // WARNING - in passing