Commit b80f8ef3 by Mark Mitchell Committed by Mark Mitchell

re PR c++/7129 (ICE with min/max assignment operators (<?= and >?=))


	PR c++/7129
	* call.c (z_candidate): Add args.
	(convert_class_to_reference): Set it.
	(implicit_conversion): Tidy.
	(add_candidate): Add args parameter.
	(add_function_candidate): Adjust call to add_candidate.
	(add_conv_candidate): Likewise.
	(build_builtin_candidate): Likewise.
	(build_user_type_conversion_1): Eliminate wasteful tree_cons
	usage.
	(build_new_function_call): Likewise.
	(build_object_call): Likewise.
	(add_candidates): New function.
	(build_new_op): Use it.
	(covert_like_real): Adjust call to build_over_call.
	(build_over_call): Remove args parameter.
	* operators.def: Add <?= and >?=.

	PR c++/7129
	* testsuite/g++.dg/ext/max.C: New test.

From-SVN: r62370
parent b3a8389d
2003-02-03 Mark Mitchell <mark@codesourcery.com>
PR c++/7129
* call.c (z_candidate): Add args.
(convert_class_to_reference): Set it.
(implicit_conversion): Tidy.
(add_candidate): Add args parameter.
(add_function_candidate): Adjust call to add_candidate.
(add_conv_candidate): Likewise.
(build_builtin_candidate): Likewise.
(build_user_type_conversion_1): Eliminate wasteful tree_cons
usage.
(build_new_function_call): Likewise.
(build_object_call): Likewise.
(add_candidates): New function.
(build_new_op): Use it.
(covert_like_real): Adjust call to build_over_call.
(build_over_call): Remove args parameter.
* operators.def: Add <?= and >?=.
2003-02-01 Richard Sandiford <rsandifo@redhat.com> 2003-02-01 Richard Sandiford <rsandifo@redhat.com>
* typeck.c (build_indirect_ref): Don't check flag_volatile. * typeck.c (build_indirect_ref): Don't check flag_volatile.
......
...@@ -44,7 +44,7 @@ static struct z_candidate * tourney (struct z_candidate *); ...@@ -44,7 +44,7 @@ static struct z_candidate * tourney (struct z_candidate *);
static int equal_functions (tree, tree); static int equal_functions (tree, tree);
static int joust (struct z_candidate *, struct z_candidate *, bool); static int joust (struct z_candidate *, struct z_candidate *, bool);
static int compare_ics (tree, tree); static int compare_ics (tree, tree);
static tree build_over_call (struct z_candidate *, tree, int); static tree build_over_call (struct z_candidate *, int);
static tree build_java_interface_fn_ref (tree, tree); static tree build_java_interface_fn_ref (tree, tree);
#define convert_like(CONV, EXPR) \ #define convert_like(CONV, EXPR) \
convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0) convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0)
...@@ -92,7 +92,7 @@ static bool is_subseq (tree, tree); ...@@ -92,7 +92,7 @@ static bool is_subseq (tree, tree);
static tree maybe_handle_ref_bind (tree *); static tree maybe_handle_ref_bind (tree *);
static void maybe_handle_implicit_object (tree *); static void maybe_handle_implicit_object (tree *);
static struct z_candidate *add_candidate static struct z_candidate *add_candidate
(struct z_candidate *, tree, tree, tree, tree, int); (struct z_candidate *, tree, tree, tree, tree, tree, int);
static tree source_type (tree); static tree source_type (tree);
static void add_warning (struct z_candidate *, struct z_candidate *); static void add_warning (struct z_candidate *, struct z_candidate *);
static bool reference_related_p (tree, tree); static bool reference_related_p (tree, tree);
...@@ -104,6 +104,8 @@ static tree conditional_conversion (tree, tree); ...@@ -104,6 +104,8 @@ static tree conditional_conversion (tree, tree);
static char *name_as_c_string (tree, tree, bool *); static char *name_as_c_string (tree, tree, bool *);
static tree call_builtin_trap (void); static tree call_builtin_trap (void);
static tree prep_operand (tree); static tree prep_operand (tree);
static struct z_candidate *add_candidates (tree, tree, tree, tree,
int, struct z_candidate *);
tree tree
build_vfield_ref (tree datum, tree type) build_vfield_ref (tree datum, tree type)
...@@ -556,6 +558,8 @@ struct z_candidate GTY(()) { ...@@ -556,6 +558,8 @@ struct z_candidate GTY(()) {
/* The FUNCTION_DECL that will be called if this candidate is /* The FUNCTION_DECL that will be called if this candidate is
selected by overload resolution. */ selected by overload resolution. */
tree fn; tree fn;
/* The arguments to use when calling this function. */
tree args;
tree convs; tree convs;
tree second_conv; tree second_conv;
int viable; int viable;
...@@ -1034,6 +1038,12 @@ convert_class_to_reference (tree t, tree s, tree expr) ...@@ -1034,6 +1038,12 @@ convert_class_to_reference (tree t, tree s, tree expr)
if (!cand) if (!cand)
return NULL_TREE; return NULL_TREE;
/* Now that we know that this is the function we're going to use fix
the dummy first argument. */
cand->args = tree_cons (NULL_TREE,
build_this (expr),
TREE_CHAIN (cand->args));
conv = build1 (IDENTITY_CONV, s, expr); conv = build1 (IDENTITY_CONV, s, expr);
conv = build_conv (USER_CONV, TREE_TYPE (TREE_TYPE (cand->fn)), conv = build_conv (USER_CONV, TREE_TYPE (TREE_TYPE (cand->fn)),
conv); conv);
...@@ -1269,8 +1279,9 @@ implicit_conversion (tree to, tree from, tree expr, int flags) ...@@ -1269,8 +1279,9 @@ implicit_conversion (tree to, tree from, tree expr, int flags)
conv = standard_conversion (to, from, expr); conv = standard_conversion (to, from, expr);
if (conv) if (conv)
; return conv;
else if (expr != NULL_TREE
if (expr != NULL_TREE
&& (IS_AGGR_TYPE (from) && (IS_AGGR_TYPE (from)
|| IS_AGGR_TYPE (to)) || IS_AGGR_TYPE (to))
&& (flags & LOOKUP_NO_CONVERSION) == 0) && (flags & LOOKUP_NO_CONVERSION) == 0)
...@@ -1283,9 +1294,10 @@ implicit_conversion (tree to, tree from, tree expr, int flags) ...@@ -1283,9 +1294,10 @@ implicit_conversion (tree to, tree from, tree expr, int flags)
/* We used to try to bind a reference to a temporary here, but that /* We used to try to bind a reference to a temporary here, but that
is now handled by the recursive call to this function at the end is now handled by the recursive call to this function at the end
of reference_binding. */ of reference_binding. */
return conv;
} }
return conv; return NULL_TREE;
} }
/* Add a new entry to the list of candidates. Used by the add_*_candidate /* Add a new entry to the list of candidates. Used by the add_*_candidate
...@@ -1293,13 +1305,14 @@ implicit_conversion (tree to, tree from, tree expr, int flags) ...@@ -1293,13 +1305,14 @@ implicit_conversion (tree to, tree from, tree expr, int flags)
static struct z_candidate * static struct z_candidate *
add_candidate (struct z_candidate *candidates, add_candidate (struct z_candidate *candidates,
tree fn, tree convs, tree access_path, tree tree fn, tree args, tree convs, tree access_path,
conversion_path, int viable) tree conversion_path, int viable)
{ {
struct z_candidate *cand struct z_candidate *cand
= (struct z_candidate *) ggc_alloc_cleared (sizeof (struct z_candidate)); = (struct z_candidate *) ggc_alloc_cleared (sizeof (struct z_candidate));
cand->fn = fn; cand->fn = fn;
cand->args = args;
cand->convs = convs; cand->convs = convs;
cand->access_path = access_path; cand->access_path = access_path;
cand->conversion_path = conversion_path; cand->conversion_path = conversion_path;
...@@ -1326,6 +1339,7 @@ add_function_candidate (struct z_candidate *candidates, ...@@ -1326,6 +1339,7 @@ add_function_candidate (struct z_candidate *candidates,
int i, len; int i, len;
tree convs; tree convs;
tree parmnode, argnode; tree parmnode, argnode;
tree orig_arglist;
int viable = 1; int viable = 1;
/* The `this', `in_chrg' and VTT arguments to constructors are not /* The `this', `in_chrg' and VTT arguments to constructors are not
...@@ -1333,8 +1347,11 @@ add_function_candidate (struct z_candidate *candidates, ...@@ -1333,8 +1347,11 @@ add_function_candidate (struct z_candidate *candidates,
if (DECL_CONSTRUCTOR_P (fn)) if (DECL_CONSTRUCTOR_P (fn))
{ {
parmlist = skip_artificial_parms_for (fn, parmlist); parmlist = skip_artificial_parms_for (fn, parmlist);
orig_arglist = arglist;
arglist = skip_artificial_parms_for (fn, arglist); arglist = skip_artificial_parms_for (fn, arglist);
} }
else
orig_arglist = arglist;
len = list_length (arglist); len = list_length (arglist);
convs = make_tree_vec (len); convs = make_tree_vec (len);
...@@ -1432,7 +1449,7 @@ add_function_candidate (struct z_candidate *candidates, ...@@ -1432,7 +1449,7 @@ add_function_candidate (struct z_candidate *candidates,
} }
out: out:
return add_candidate (candidates, fn, convs, access_path, return add_candidate (candidates, fn, orig_arglist, convs, access_path,
conversion_path, viable); conversion_path, viable);
} }
...@@ -1509,7 +1526,7 @@ add_conv_candidate (struct z_candidate *candidates, tree fn, tree obj, ...@@ -1509,7 +1526,7 @@ add_conv_candidate (struct z_candidate *candidates, tree fn, tree obj,
if (!sufficient_parms_p (parmnode)) if (!sufficient_parms_p (parmnode))
viable = 0; viable = 0;
return add_candidate (candidates, totype, convs, access_path, return add_candidate (candidates, totype, arglist, convs, access_path,
conversion_path, viable); conversion_path, viable);
} }
...@@ -1556,7 +1573,7 @@ build_builtin_candidate (struct z_candidate *candidates, tree fnname, ...@@ -1556,7 +1573,7 @@ build_builtin_candidate (struct z_candidate *candidates, tree fnname,
viable = 0; viable = 0;
} }
return add_candidate (candidates, fnname, convs, return add_candidate (candidates, fnname, /*args=*/NULL_TREE, convs,
/*access_path=*/NULL_TREE, /*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE,
viable); viable);
...@@ -2396,7 +2413,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) ...@@ -2396,7 +2413,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
tree fromtype = TREE_TYPE (expr); tree fromtype = TREE_TYPE (expr);
tree ctors = NULL_TREE, convs = NULL_TREE, *p; tree ctors = NULL_TREE, convs = NULL_TREE, *p;
tree args = NULL_TREE; tree args = NULL_TREE;
tree templates = NULL_TREE;
/* We represent conversion within a hierarchy using RVALUE_CONV and /* We represent conversion within a hierarchy using RVALUE_CONV and
BASE_CONV, as specified by [over.best.ics]; these become plain BASE_CONV, as specified by [over.best.ics]; these become plain
...@@ -2438,8 +2454,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) ...@@ -2438,8 +2454,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
continue; continue;
if (TREE_CODE (ctor) == TEMPLATE_DECL) if (TREE_CODE (ctor) == TEMPLATE_DECL)
{
templates = tree_cons (NULL_TREE, ctor, templates);
candidates = candidates =
add_template_candidate (candidates, ctor, totype, add_template_candidate (candidates, ctor, totype,
NULL_TREE, args, NULL_TREE, NULL_TREE, args, NULL_TREE,
...@@ -2447,7 +2461,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) ...@@ -2447,7 +2461,6 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
TYPE_BINFO (totype), TYPE_BINFO (totype),
flags, flags,
DEDUCE_CALL); DEDUCE_CALL);
}
else else
candidates = add_function_candidate (candidates, ctor, totype, candidates = add_function_candidate (candidates, ctor, totype,
args, TYPE_BINFO (totype), args, TYPE_BINFO (totype),
...@@ -2487,15 +2500,12 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) ...@@ -2487,15 +2500,12 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
So we pass fromtype as CTYPE to add_*_candidate. */ So we pass fromtype as CTYPE to add_*_candidate. */
if (TREE_CODE (fn) == TEMPLATE_DECL) if (TREE_CODE (fn) == TEMPLATE_DECL)
{
templates = tree_cons (NULL_TREE, fn, templates);
candidates = candidates =
add_template_candidate (candidates, fn, fromtype, NULL_TREE, add_template_candidate (candidates, fn, fromtype, NULL_TREE,
args, totype, TYPE_BINFO (fromtype), args, totype, TYPE_BINFO (fromtype),
conversion_path, conversion_path,
flags, flags,
DEDUCE_CONV); DEDUCE_CONV);
}
else else
candidates = add_function_candidate (candidates, fn, fromtype, candidates = add_function_candidate (candidates, fn, fromtype,
args, args,
...@@ -2695,7 +2705,6 @@ build_new_function_call (tree fn, tree args) ...@@ -2695,7 +2705,6 @@ build_new_function_call (tree fn, tree args)
|| TREE_CODE (fn) == TEMPLATE_DECL) || TREE_CODE (fn) == TEMPLATE_DECL)
{ {
tree t1; tree t1;
tree templates = NULL_TREE;
args = resolve_args (args); args = resolve_args (args);
...@@ -2709,14 +2718,11 @@ build_new_function_call (tree fn, tree args) ...@@ -2709,14 +2718,11 @@ build_new_function_call (tree fn, tree args)
my_friendly_assert (!DECL_FUNCTION_MEMBER_P (t), 20020913); my_friendly_assert (!DECL_FUNCTION_MEMBER_P (t), 20020913);
if (TREE_CODE (t) == TEMPLATE_DECL) if (TREE_CODE (t) == TEMPLATE_DECL)
{
templates = tree_cons (NULL_TREE, t, templates);
candidates = add_template_candidate candidates = add_template_candidate
(candidates, t, NULL_TREE, explicit_targs, args, (candidates, t, NULL_TREE, explicit_targs, args,
NULL_TREE, /*access_path=*/NULL_TREE, NULL_TREE, /*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE,
LOOKUP_NORMAL, DEDUCE_CALL); LOOKUP_NORMAL, DEDUCE_CALL);
}
else if (! template_only) else if (! template_only)
candidates = add_function_candidate candidates = add_function_candidate
(candidates, t, NULL_TREE, args, (candidates, t, NULL_TREE, args,
...@@ -2745,7 +2751,7 @@ build_new_function_call (tree fn, tree args) ...@@ -2745,7 +2751,7 @@ build_new_function_call (tree fn, tree args)
return error_mark_node; return error_mark_node;
} }
return build_over_call (cand, args, LOOKUP_NORMAL); return build_over_call (cand, LOOKUP_NORMAL);
} }
/* This is not really overloaded. */ /* This is not really overloaded. */
...@@ -2787,14 +2793,12 @@ build_object_call (tree obj, tree args) ...@@ -2787,14 +2793,12 @@ build_object_call (tree obj, tree args)
{ {
tree fn = OVL_CURRENT (fns); tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL) if (TREE_CODE (fn) == TEMPLATE_DECL)
{
candidates candidates
= add_template_candidate (candidates, fn, base, NULL_TREE, = add_template_candidate (candidates, fn, base, NULL_TREE,
mem_args, NULL_TREE, mem_args, NULL_TREE,
TYPE_BINFO (type), TYPE_BINFO (type),
TYPE_BINFO (type), TYPE_BINFO (type),
LOOKUP_NORMAL, DEDUCE_CALL); LOOKUP_NORMAL, DEDUCE_CALL);
}
else else
candidates = add_function_candidate candidates = add_function_candidate
(candidates, fn, base, mem_args, TYPE_BINFO (type), (candidates, fn, base, mem_args, TYPE_BINFO (type),
...@@ -2855,7 +2859,7 @@ build_object_call (tree obj, tree args) ...@@ -2855,7 +2859,7 @@ build_object_call (tree obj, tree args)
DECL_NAME here. */ DECL_NAME here. */
if (TREE_CODE (cand->fn) == FUNCTION_DECL if (TREE_CODE (cand->fn) == FUNCTION_DECL
&& DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR) && DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR)
return build_over_call (cand, mem_args, LOOKUP_NORMAL); return build_over_call (cand, LOOKUP_NORMAL);
obj = convert_like_with_context obj = convert_like_with_context
(TREE_VEC_ELT (cand->convs, 0), obj, cand->fn, -1); (TREE_VEC_ELT (cand->convs, 0), obj, cand->fn, -1);
...@@ -3317,13 +3321,78 @@ prep_operand (tree operand) ...@@ -3317,13 +3321,78 @@ prep_operand (tree operand)
return operand; return 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,
ACCESS_PATH, and FLAGS are as for add_function_candidate. */
static struct z_candidate *
add_candidates (tree fns, tree args,
tree conversion_path, tree access_path,
int flags,
struct z_candidate *candidates)
{
tree ctype;
tree non_static_args;
ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
/* Delay creating the implicit this parameter until it is needed. */
non_static_args = NULL_TREE;
while (fns)
{
tree fn;
tree fn_args;
fn = OVL_CURRENT (fns);
/* Figure out which set of arguments to use. */
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
{
/* If this function is a non-static member, prepend the implicit
object parameter. */
if (!non_static_args)
non_static_args = tree_cons (NULL_TREE,
build_this (TREE_VALUE (args)),
TREE_CHAIN (args));
fn_args = non_static_args;
}
else
/* Otherwise, just use the list of arguments provided. */
fn_args = args;
if (TREE_CODE (fn) == TEMPLATE_DECL)
candidates = add_template_candidate (candidates,
fn,
ctype,
NULL_TREE,
fn_args,
NULL_TREE,
access_path,
conversion_path,
flags,
DEDUCE_CALL);
else
candidates = add_function_candidate (candidates,
fn,
ctype,
fn_args,
access_path,
conversion_path,
flags);
fns = OVL_NEXT (fns);
}
return candidates;
}
tree tree
build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3) build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
{ {
struct z_candidate *candidates = 0, *cand; struct z_candidate *candidates = 0, *cand;
tree fns, mem_arglist = NULL_TREE, arglist, fnname; tree arglist, fnname;
tree args[3];
enum tree_code code2 = NOP_EXPR; enum tree_code code2 = NOP_EXPR;
tree templates = NULL_TREE;
tree conv; tree conv;
bool viable_candidates; bool viable_candidates;
...@@ -3385,78 +3454,26 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3) ...@@ -3385,78 +3454,26 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
arglist = tree_cons (NULL_TREE, arg2, arglist); arglist = tree_cons (NULL_TREE, arg2, arglist);
arglist = tree_cons (NULL_TREE, arg1, arglist); arglist = tree_cons (NULL_TREE, arg1, arglist);
fns = lookup_function_nonclass (fnname, arglist); /* Add namespace-scope operators to the list of functions to
consider. */
if (fns && TREE_CODE (fns) == TREE_LIST) candidates = add_candidates (lookup_function_nonclass (fnname, arglist),
fns = TREE_VALUE (fns); arglist, NULL_TREE, NULL_TREE,
for (; fns; fns = OVL_NEXT (fns)) flags, candidates);
{ /* Add class-member operators to the candidate set. */
tree fn = OVL_CURRENT (fns); if (CLASS_TYPE_P (TREE_TYPE (arg1)))
if (TREE_CODE (fn) == TEMPLATE_DECL)
{ {
templates = tree_cons (NULL_TREE, fn, templates); tree fns;
candidates
= add_template_candidate (candidates, fn, NULL_TREE, NULL_TREE,
arglist, TREE_TYPE (fnname),
/*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE,
flags, DEDUCE_CALL);
}
else
candidates = add_function_candidate (candidates, fn, NULL_TREE,
arglist,
/*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE,
flags);
}
if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
{
fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1); fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1);
if (fns == error_mark_node) if (fns == error_mark_node)
return fns; return fns;
}
else
fns = NULL_TREE;
if (fns) if (fns)
{ candidates = add_candidates (BASELINK_FUNCTIONS (fns), arglist,
tree conversion_path = BASELINK_BINFO (fns); BASELINK_BINFO (fns),
TYPE_BINFO (TREE_TYPE (arg1)),
mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist)); flags, candidates);
for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
tree this_arglist;
tree access_path = TYPE_BINFO (TREE_TYPE (arg1));
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
this_arglist = mem_arglist;
else
this_arglist = arglist;
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
/* A member template. */
templates = tree_cons (NULL_TREE, fn, templates);
candidates
= add_template_candidate (candidates, fn,
BINFO_TYPE (conversion_path),
NULL_TREE,
this_arglist, TREE_TYPE (fnname),
access_path, conversion_path,
flags, DEDUCE_CALL);
}
else
candidates = add_function_candidate
(candidates, fn, BINFO_TYPE (conversion_path), this_arglist,
access_path, conversion_path, flags);
}
} }
{
tree args[3];
/* Rearrange the arguments for ?: so that add_builtin_candidate only has /* Rearrange the arguments for ?: so that add_builtin_candidate only has
to know about two args; a builtin candidate will always have a first to know about two args; a builtin candidate will always have a first
parameter of type bool. We'll handle that in parameter of type bool. We'll handle that in
...@@ -3476,7 +3493,6 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3) ...@@ -3476,7 +3493,6 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
candidates = add_builtin_candidates candidates = add_builtin_candidates
(candidates, code, code2, fnname, args, flags); (candidates, code, code2, fnname, args, flags);
}
switch (code) switch (code)
{ {
...@@ -3559,11 +3575,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3) ...@@ -3559,11 +3575,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
: candidates->fn); : candidates->fn);
} }
return build_over_call return build_over_call (cand, LOOKUP_NORMAL);
(cand,
TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
? mem_arglist : arglist,
LOOKUP_NORMAL);
} }
/* Check for comparison of different enum types. */ /* Check for comparison of different enum types. */
...@@ -3907,7 +3919,7 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner) ...@@ -3907,7 +3919,7 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner)
} }
else else
args = build_this (expr); args = build_this (expr);
expr = build_over_call (cand, args, LOOKUP_NORMAL); expr = build_over_call (cand, LOOKUP_NORMAL);
/* If this is a constructor or a function returning an aggr type, /* If this is a constructor or a function returning an aggr type,
we need to build up a TARGET_EXPR. */ we need to build up a TARGET_EXPR. */
...@@ -4238,9 +4250,10 @@ convert_for_arg_passing (tree type, tree val) ...@@ -4238,9 +4250,10 @@ convert_for_arg_passing (tree type, tree val)
bitmask of various LOOKUP_* flags which apply to the call itself. */ bitmask of various LOOKUP_* flags which apply to the call itself. */
static tree static tree
build_over_call (struct z_candidate *cand, tree args, int flags) build_over_call (struct z_candidate *cand, int flags)
{ {
tree fn = cand->fn; tree fn = cand->fn;
tree args = cand->args;
tree convs = cand->convs; tree convs = cand->convs;
tree converted_args = NULL_TREE; tree converted_args = NULL_TREE;
tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn)); tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
...@@ -4702,7 +4715,6 @@ build_new_method_call (tree instance, tree fns, tree args, ...@@ -4702,7 +4715,6 @@ build_new_method_call (tree instance, tree fns, tree args,
tree mem_args = NULL_TREE, instance_ptr; tree mem_args = NULL_TREE, instance_ptr;
tree name; tree name;
tree user_args; tree user_args;
tree templates = NULL_TREE;
tree call; tree call;
tree fn; tree fn;
tree class_type; tree class_type;
...@@ -4807,7 +4819,6 @@ build_new_method_call (tree instance, tree fns, tree args, ...@@ -4807,7 +4819,6 @@ build_new_method_call (tree instance, tree fns, tree args,
if (TREE_CODE (t) == TEMPLATE_DECL) if (TREE_CODE (t) == TEMPLATE_DECL)
{ {
/* A member template. */ /* A member template. */
templates = tree_cons (NULL_TREE, t, templates);
candidates = candidates =
add_template_candidate (candidates, t, add_template_candidate (candidates, t,
class_type, class_type,
...@@ -4888,10 +4899,10 @@ build_new_method_call (tree instance, tree fns, tree args, ...@@ -4888,10 +4899,10 @@ build_new_method_call (tree instance, tree fns, tree args,
flags |= LOOKUP_NONVIRTUAL; flags |= LOOKUP_NONVIRTUAL;
if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE) if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE)
call = build_over_call (cand, mem_args, flags); call = build_over_call (cand, flags);
else else
{ {
call = build_over_call (cand, args, flags); call = build_over_call (cand, flags);
/* In an expression of the form `a->f()' where `f' turns out to /* In an expression of the form `a->f()' where `f' turns out to
be a static member function, `a' is none-the-less evaluated. */ be a static member function, `a' is none-the-less evaluated. */
if (!is_dummy_object (instance_ptr) && TREE_SIDE_EFFECTS (instance)) if (!is_dummy_object (instance_ptr) && TREE_SIDE_EFFECTS (instance))
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
non-overloadable operators (like the `?:' ternary operator). non-overloadable operators (like the `?:' ternary operator).
Written by Mark Mitchell <mark@codesourcery.com> Written by Mark Mitchell <mark@codesourcery.com>
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -40,7 +40,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -40,7 +40,7 @@ Boston, MA 02111-1307, USA. */
assignment operators, the same tree-codes are reused; i.e., assignment operators, the same tree-codes are reused; i.e.,
`operator +' will also have PLUS_EXPR as its CODE. `operator +' will also have PLUS_EXPR as its CODE.
NEW_MANGLING MANGLING
The mangling prefix for the operator, as a C string, and as The mangling prefix for the operator, as a C string, and as
mangled under the new ABI. For `operator +', for example, this mangled under the new ABI. For `operator +', for example, this
...@@ -127,7 +127,7 @@ DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", 2) ...@@ -127,7 +127,7 @@ DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", 2)
DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", 2) DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", 2)
DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", 2) DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", 2)
DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", 2) DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", 2)
/* These are extensions. */ /* These operators are GNU extensions. */
DEF_SIMPLE_OPERATOR ("<?", MIN_EXPR, "v23min", 2) DEF_SIMPLE_OPERATOR ("<?", MIN_EXPR, "v23min", 2)
DEF_SIMPLE_OPERATOR (">?", MAX_EXPR, "v23max", 2) DEF_SIMPLE_OPERATOR (">?", MAX_EXPR, "v23max", 2)
/* This one is needed for mangling. */ /* This one is needed for mangling. */
...@@ -145,6 +145,9 @@ DEF_ASSN_OPERATOR ("|=", BIT_IOR_EXPR, "oR", 2) ...@@ -145,6 +145,9 @@ DEF_ASSN_OPERATOR ("|=", BIT_IOR_EXPR, "oR", 2)
DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO", 2) DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO", 2)
DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS", 2) DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS", 2)
DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS", 2) DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS", 2)
/* These operators are GNU extensions. */
DEF_ASSN_OPERATOR ("<?=", MIN_EXPR, "v23miN", 2);
DEF_ASSN_OPERATOR (">?=", MAX_EXPR, "v23maX", 2);
/* Ternary operators. */ /* Ternary operators. */
DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", 3) DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", 3)
......
2003-02-03 Mark Mitchell <mark@codesourcery.com>
PR c++/7129
* testsuite/g++.dg/ext/max.C: New test.
Mon Feb 3 16:05:11 CET 2003 Jan Hubicka <jh@suse.cz> Mon Feb 3 16:05:11 CET 2003 Jan Hubicka <jh@suse.cz>
* gcc.c-torture/execute/20030203-1.c: New test. * gcc.c-torture/execute/20030203-1.c: New test.
......
struct s_t {
};
void foo(void) {
s_t s; int i;
s<?=i; // { dg-error "" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment