parent
9d8757d442
commit
d11ad92ebe
1970
gcc/cp/ChangeLog
1970
gcc/cp/ChangeLog
File diff suppressed because it is too large
Load Diff
239
gcc/cp/call.c
239
gcc/cp/call.c
|
@ -2924,9 +2924,11 @@ struct z_candidate {
|
|||
#define PBOOL_RANK 4
|
||||
#define USER_RANK 5
|
||||
#define ELLIPSIS_RANK 6
|
||||
#define BAD_RANK 7
|
||||
|
||||
#define ICS_RANK(NODE) \
|
||||
(ICS_ELLIPSIS_FLAG (NODE) ? ELLIPSIS_RANK \
|
||||
(ICS_BAD_FLAG (NODE) ? BAD_RANK \
|
||||
: ICS_ELLIPSIS_FLAG (NODE) ? ELLIPSIS_RANK \
|
||||
: ICS_USER_FLAG (NODE) ? USER_RANK \
|
||||
: ICS_STD_RANK (NODE))
|
||||
|
||||
|
@ -2934,6 +2936,8 @@ struct z_candidate {
|
|||
|
||||
#define ICS_USER_FLAG(NODE) TREE_LANG_FLAG_0 (NODE)
|
||||
#define ICS_ELLIPSIS_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
|
||||
#define ICS_THIS_FLAG(NODE) TREE_LANG_FLAG_2 (NODE)
|
||||
#define ICS_BAD_FLAG(NODE) TREE_LANG_FLAG_3 (NODE)
|
||||
|
||||
#define USER_CONV_FN(NODE) TREE_OPERAND (NODE, 1)
|
||||
|
||||
|
@ -2947,7 +2951,7 @@ int
|
|||
null_ptr_cst_p (t)
|
||||
tree t;
|
||||
{
|
||||
if (t == null_pointer_node
|
||||
if (t == null_node
|
||||
|| integer_zerop (t) && INTEGRAL_TYPE_P (TREE_TYPE (t)))
|
||||
return 1;
|
||||
/* Remove this eventually. */
|
||||
|
@ -2984,6 +2988,7 @@ build_conv (code, type, from)
|
|||
}
|
||||
ICS_STD_RANK (t) = rank;
|
||||
ICS_USER_FLAG (t) = ICS_USER_FLAG (from);
|
||||
ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -3037,10 +3042,11 @@ standard_conversion (to, from, expr)
|
|||
{
|
||||
enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
|
||||
enum tree_code utcode = TREE_CODE (TREE_TYPE (to));
|
||||
tree nconv = NULL_TREE;
|
||||
|
||||
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (from)),
|
||||
TYPE_MAIN_VARIANT (TREE_TYPE (to)), 1))
|
||||
/* OK for now */;
|
||||
nconv = conv;
|
||||
else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE
|
||||
&& ufcode != FUNCTION_TYPE)
|
||||
{
|
||||
|
@ -3048,7 +3054,7 @@ standard_conversion (to, from, expr)
|
|||
(cp_build_type_variant (void_type_node,
|
||||
TYPE_READONLY (TREE_TYPE (from)),
|
||||
TYPE_VOLATILE (TREE_TYPE (from))));
|
||||
conv = build_conv (PTR_CONV, from, conv);
|
||||
nconv = build_conv (PTR_CONV, from, conv);
|
||||
}
|
||||
else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)
|
||||
{
|
||||
|
@ -3062,10 +3068,8 @@ standard_conversion (to, from, expr)
|
|||
{
|
||||
from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from)));
|
||||
from = build_pointer_type (from);
|
||||
conv = build_conv (PMEM_CONV, from, conv);
|
||||
nconv = build_conv (PMEM_CONV, from, conv);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else if (IS_AGGR_TYPE (TREE_TYPE (from))
|
||||
&& IS_AGGR_TYPE (TREE_TYPE (to)))
|
||||
|
@ -3076,22 +3080,23 @@ standard_conversion (to, from, expr)
|
|||
TYPE_READONLY (TREE_TYPE (from)),
|
||||
TYPE_VOLATILE (TREE_TYPE (from)));
|
||||
from = build_pointer_type (from);
|
||||
conv = build_conv (PTR_CONV, from, conv);
|
||||
nconv = build_conv (PTR_CONV, from, conv);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nconv && comptypes (from, to, 1))
|
||||
conv = nconv;
|
||||
else if (nconv && comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from)))
|
||||
conv = build_conv (QUAL_CONV, to, nconv);
|
||||
else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from)))
|
||||
{
|
||||
conv = build_conv (PTR_CONV, to, conv);
|
||||
ICS_BAD_FLAG (conv) = 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (! comptypes (from, to, 1))
|
||||
{
|
||||
if (! comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from)))
|
||||
return 0;
|
||||
|
||||
from = to;
|
||||
conv = build_conv (QUAL_CONV, from, conv);
|
||||
}
|
||||
from = to;
|
||||
}
|
||||
else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))
|
||||
{
|
||||
|
@ -3214,6 +3219,14 @@ reference_binding (rto, from, expr, flags)
|
|||
}
|
||||
}
|
||||
|
||||
if (! conv)
|
||||
{
|
||||
conv = standard_conversion
|
||||
(TYPE_MAIN_VARIANT (to), strip_top_quals (from), expr);
|
||||
if (conv)
|
||||
ICS_BAD_FLAG (conv) = 1;
|
||||
}
|
||||
|
||||
return conv;
|
||||
}
|
||||
|
||||
|
@ -3330,10 +3343,17 @@ add_function_candidate (candidates, fn, arglist, flags)
|
|||
ICS_ELLIPSIS_FLAG (t) = 1;
|
||||
}
|
||||
|
||||
if (i == 0 && t && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
|
||||
&& ! DECL_CONSTRUCTOR_P (fn))
|
||||
ICS_THIS_FLAG (t) = 1;
|
||||
|
||||
TREE_VEC_ELT (convs, i) = t;
|
||||
if (! t)
|
||||
break;
|
||||
|
||||
if (ICS_BAD_FLAG (t))
|
||||
viable = -1;
|
||||
|
||||
if (parmnode)
|
||||
parmnode = TREE_CHAIN (parmnode);
|
||||
argnode = TREE_CHAIN (argnode);
|
||||
|
@ -3387,12 +3407,9 @@ add_conv_candidate (candidates, fn, obj, arglist)
|
|||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
tree arg = i == 0 ? obj : TREE_VALUE (argnode);
|
||||
tree argtype = TREE_TYPE (arg);
|
||||
tree argtype = lvalue_type (arg);
|
||||
tree t;
|
||||
|
||||
argtype = cp_build_type_variant
|
||||
(argtype, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg));
|
||||
|
||||
if (i == 0)
|
||||
t = implicit_conversion (totype, argtype, arg, flags);
|
||||
else if (parmnode == void_list_node)
|
||||
|
@ -3409,6 +3426,9 @@ add_conv_candidate (candidates, fn, obj, arglist)
|
|||
if (! t)
|
||||
break;
|
||||
|
||||
if (ICS_BAD_FLAG (t))
|
||||
viable = -1;
|
||||
|
||||
if (i == 0)
|
||||
continue;
|
||||
|
||||
|
@ -3492,6 +3512,8 @@ build_builtin_candidate (candidates, fnname, type1, type2,
|
|||
/* We need something for printing the candidate. */
|
||||
t = build1 (IDENTITY_CONV, types[i], NULL_TREE);
|
||||
}
|
||||
else if (ICS_BAD_FLAG (t))
|
||||
viable = 0;
|
||||
TREE_VEC_ELT (convs, i) = t;
|
||||
}
|
||||
|
||||
|
@ -3954,9 +3976,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
|
|||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
if (args[i])
|
||||
argtypes[i] = cp_build_type_variant
|
||||
(TREE_TYPE (args[i]), TREE_READONLY (args[i]),
|
||||
TREE_THIS_VOLATILE (args[i]));
|
||||
argtypes[i] = lvalue_type (args[i]);
|
||||
else
|
||||
argtypes[i] = NULL_TREE;
|
||||
}
|
||||
|
@ -4117,7 +4137,7 @@ any_viable (cands)
|
|||
struct z_candidate *cands;
|
||||
{
|
||||
for (; cands; cands = cands->next)
|
||||
if (cands->viable)
|
||||
if (pedantic ? cands->viable == 1 : cands->viable)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4130,7 +4150,7 @@ splice_viable (cands)
|
|||
|
||||
for (; *p; )
|
||||
{
|
||||
if ((*p)->viable)
|
||||
if (pedantic ? (*p)->viable == 1 : (*p)->viable)
|
||||
p = &((*p)->next);
|
||||
else
|
||||
*p = (*p)->next;
|
||||
|
@ -4170,7 +4190,8 @@ print_z_candidates (candidates)
|
|||
TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)));
|
||||
}
|
||||
else
|
||||
cp_error_at ("%s %+D", str, candidates->fn);
|
||||
cp_error_at ("%s %+D%s", str, candidates->fn,
|
||||
candidates->viable == -1 ? " <bad>" : "");
|
||||
str = " ";
|
||||
}
|
||||
}
|
||||
|
@ -4232,6 +4253,8 @@ build_user_type_conversion_1 (totype, expr, flags)
|
|||
candidates = add_function_candidate (candidates, fn, args, flags);
|
||||
candidates->second_conv = ics;
|
||||
candidates->basetype_path = TREE_PURPOSE (convs);
|
||||
if (candidates->viable == 1 && ICS_BAD_FLAG (ics))
|
||||
candidates->viable = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4400,7 +4423,7 @@ build_object_call (obj, args)
|
|||
|
||||
if (! any_viable (candidates))
|
||||
{
|
||||
cp_error ("no match for call to `(%T) (%A)", TREE_TYPE (obj), args);
|
||||
cp_error ("no match for call to `(%T) (%A)'", TREE_TYPE (obj), args);
|
||||
print_z_candidates (candidates);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
@ -4437,22 +4460,22 @@ op_error (code, code2, arg1, arg2, arg3, problem)
|
|||
{
|
||||
case COND_EXPR:
|
||||
cp_error ("%s for `%T ? %T : %T'", problem,
|
||||
TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
|
||||
error_type (arg1), error_type (arg2), error_type (arg3));
|
||||
break;
|
||||
case POSTINCREMENT_EXPR:
|
||||
case POSTDECREMENT_EXPR:
|
||||
cp_error ("%s for `%T%s'", problem, TREE_TYPE (arg1), opname);
|
||||
cp_error ("%s for `%T%s'", problem, error_type (arg1), opname);
|
||||
break;
|
||||
case ARRAY_REF:
|
||||
cp_error ("%s for `%T[%T]'", problem,
|
||||
TREE_TYPE (arg1), TREE_TYPE (arg2));
|
||||
error_type (arg1), error_type (arg2));
|
||||
break;
|
||||
default:
|
||||
if (arg2)
|
||||
cp_error ("%s for `%T %s %T'", problem,
|
||||
TREE_TYPE (arg1), opname, TREE_TYPE (arg2));
|
||||
error_type (arg1), opname, error_type (arg2));
|
||||
else
|
||||
cp_error ("%s for `%s%T'", problem, opname, TREE_TYPE (arg1));
|
||||
cp_error ("%s for `%s%T'", problem, opname, error_type (arg1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4467,7 +4490,9 @@ build_new_op (code, flags, arg1, arg2, arg3)
|
|||
enum tree_code code2 = NOP_EXPR;
|
||||
tree templates = NULL_TREE;
|
||||
|
||||
if (arg1 == error_mark_node)
|
||||
if (arg1 == error_mark_node
|
||||
|| arg2 == error_mark_node
|
||||
|| arg3 == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (code == MODIFY_EXPR)
|
||||
|
@ -4717,6 +4742,26 @@ build_new_op (code, flags, arg1, arg2, arg3)
|
|||
LOOKUP_NORMAL);
|
||||
}
|
||||
|
||||
/* Check for comparison of different enum types. */
|
||||
switch (code)
|
||||
{
|
||||
case GT_EXPR:
|
||||
case LT_EXPR:
|
||||
case GE_EXPR:
|
||||
case LE_EXPR:
|
||||
case EQ_EXPR:
|
||||
case NE_EXPR:
|
||||
if (flag_int_enum_equivalence == 0
|
||||
&& TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE
|
||||
&& (TYPE_MAIN_VARIANT (TREE_TYPE (arg1))
|
||||
!= TYPE_MAIN_VARIANT (TREE_TYPE (arg2))))
|
||||
{
|
||||
cp_warning ("comparison between `%#T' and `%#T'",
|
||||
TREE_TYPE (arg1), TREE_TYPE (arg2));
|
||||
}
|
||||
}
|
||||
|
||||
arg1 = convert_from_reference
|
||||
(convert_like (TREE_VEC_ELT (cand->convs, 0), arg1));
|
||||
if (arg2)
|
||||
|
@ -4786,7 +4831,7 @@ builtin:
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
enforce_access (basetype_path, function)
|
||||
tree basetype_path, function;
|
||||
{
|
||||
|
@ -4814,6 +4859,26 @@ static tree
|
|||
convert_like (convs, expr)
|
||||
tree convs, expr;
|
||||
{
|
||||
if (ICS_BAD_FLAG (convs))
|
||||
{
|
||||
tree t = convs;
|
||||
for (; t; t = TREE_OPERAND (t, 0))
|
||||
{
|
||||
if (TREE_CODE (t) == USER_CONV)
|
||||
{
|
||||
expr = convert_like (t, expr);
|
||||
break;
|
||||
}
|
||||
else if (TREE_CODE (t) == AMBIG_CONV)
|
||||
return convert_like (t, expr);
|
||||
else if (TREE_CODE (t) == IDENTITY_CONV)
|
||||
break;
|
||||
}
|
||||
return convert_for_initialization
|
||||
(NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL,
|
||||
"conversion", NULL_TREE, 0);
|
||||
}
|
||||
|
||||
switch (TREE_CODE (convs))
|
||||
{
|
||||
case USER_CONV:
|
||||
|
@ -4917,6 +4982,7 @@ build_over_call (fn, convs, args, flags)
|
|||
tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
tree conv, arg, val;
|
||||
int i = 0;
|
||||
int is_method = 0;
|
||||
|
||||
if (args && TREE_CODE (args) != TREE_LIST)
|
||||
args = build_tree_list (NULL_TREE, args);
|
||||
|
@ -4940,19 +5006,56 @@ build_over_call (fn, convs, args, flags)
|
|||
/* Bypass access control for 'this' parameter. */
|
||||
else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
|
||||
{
|
||||
tree parmtype = TREE_VALUE (parm);
|
||||
tree argtype = TREE_TYPE (TREE_VALUE (arg));
|
||||
if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i)))
|
||||
{
|
||||
int dv = (TYPE_VOLATILE (TREE_TYPE (parmtype))
|
||||
< TYPE_VOLATILE (TREE_TYPE (argtype)));
|
||||
int dc = (TYPE_READONLY (TREE_TYPE (parmtype))
|
||||
< TYPE_READONLY (TREE_TYPE (argtype)));
|
||||
char *p = (dv && dc ? "const and volatile" :
|
||||
dc ? "const" : dv ? "volatile" : "");
|
||||
|
||||
cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards %s",
|
||||
TREE_TYPE (argtype), fn, p);
|
||||
}
|
||||
converted_args = tree_cons
|
||||
(NULL_TREE, convert_force (TREE_VALUE (parm), TREE_VALUE (arg), CONV_C_CAST),
|
||||
converted_args);
|
||||
parm = TREE_CHAIN (parm);
|
||||
arg = TREE_CHAIN (arg);
|
||||
++i;
|
||||
is_method = 1;
|
||||
}
|
||||
|
||||
for (; conv = TREE_VEC_ELT (convs, i), arg && parm;
|
||||
parm = TREE_CHAIN (parm), arg = TREE_CHAIN (arg), ++i)
|
||||
{
|
||||
tree type = TREE_VALUE (parm);
|
||||
val = convert_like (conv, TREE_VALUE (arg));
|
||||
|
||||
if (ICS_BAD_FLAG (conv))
|
||||
{
|
||||
tree t = conv;
|
||||
val = TREE_VALUE (arg);
|
||||
|
||||
for (; t; t = TREE_OPERAND (t, 0))
|
||||
{
|
||||
if (TREE_CODE (t) == USER_CONV
|
||||
|| TREE_CODE (t) == AMBIG_CONV)
|
||||
{
|
||||
val = convert_like (t, val);
|
||||
break;
|
||||
}
|
||||
else if (TREE_CODE (t) == IDENTITY_CONV)
|
||||
break;
|
||||
}
|
||||
val = convert_for_initialization
|
||||
(NULL_TREE, type, val, LOOKUP_NORMAL,
|
||||
"argument passing", fn, i - is_method);
|
||||
}
|
||||
else
|
||||
val = convert_like (conv, TREE_VALUE (arg));
|
||||
|
||||
#ifdef PROMOTE_PROTOTYPES
|
||||
if ((TREE_CODE (type) == INTEGER_TYPE
|
||||
|
@ -5035,6 +5138,10 @@ build_new_method_call (instance, name, args, basetype_path, flags)
|
|||
tree basetype, mem_args, fns, instance_ptr;
|
||||
tree pretty_name;
|
||||
|
||||
for (fns = args; fns; fns = TREE_CHAIN (fns))
|
||||
if (TREE_VALUE (fns) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (instance == NULL_TREE)
|
||||
basetype = BINFO_TYPE (basetype_path);
|
||||
else
|
||||
|
@ -5122,7 +5229,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
|
|||
|
||||
if (cand == 0)
|
||||
{
|
||||
cp_error ("call of overloaded `%D(%A)' is ambiguous");
|
||||
cp_error ("call of overloaded `%D(%A)' is ambiguous", pretty_name, args);
|
||||
print_z_candidates (candidates);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
@ -5197,18 +5304,55 @@ compare_ics (ics1, ics2)
|
|||
{
|
||||
tree main1, main2;
|
||||
|
||||
if (TREE_CODE (ics1) == QUAL_CONV)
|
||||
main1 = TREE_OPERAND (ics1, 0);
|
||||
else
|
||||
main1 = ics1;
|
||||
|
||||
if (TREE_CODE (ics2) == QUAL_CONV)
|
||||
main2 = TREE_OPERAND (ics2, 0);
|
||||
else
|
||||
main2 = ics2;
|
||||
|
||||
/* Conversions for `this' are PTR_CONVs, but we compare them as though
|
||||
they were REF_BINDs. */
|
||||
if (ICS_THIS_FLAG (ics1))
|
||||
{
|
||||
ics1 = build_conv (REF_BIND, TREE_TYPE (ics1), main1);
|
||||
TREE_OPERAND (ics1, 0) = TREE_OPERAND (main1, 0);
|
||||
main1 = ics1;
|
||||
}
|
||||
if (ICS_THIS_FLAG (ics2))
|
||||
{
|
||||
ics2 = build_conv (REF_BIND, TREE_TYPE (ics2), main2);
|
||||
TREE_OPERAND (ics2, 0) = TREE_OPERAND (main2, 0);
|
||||
main2 = ics2;
|
||||
}
|
||||
|
||||
if (ICS_RANK (ics1) > ICS_RANK (ics2))
|
||||
return -1;
|
||||
else if (ICS_RANK (ics1) < ICS_RANK (ics2))
|
||||
return 1;
|
||||
|
||||
if (ICS_RANK (ics1) == BAD_RANK)
|
||||
{
|
||||
if (ICS_USER_FLAG (ics1) > ICS_USER_FLAG (ics2)
|
||||
|| ICS_STD_RANK (ics1) > ICS_STD_RANK (ics2))
|
||||
return -1;
|
||||
else if (ICS_USER_FLAG (ics1) < ICS_USER_FLAG (ics2)
|
||||
|| ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2))
|
||||
return 1;
|
||||
|
||||
/* else fall through */
|
||||
}
|
||||
|
||||
/* User-defined conversion sequence U1 is a better conversion sequence
|
||||
than another user-defined conversion sequence U2 if they contain the
|
||||
same user-defined conversion operator or constructor and if the sec-
|
||||
ond standard conversion sequence of U1 is better than the second
|
||||
standard conversion sequence of U2. */
|
||||
|
||||
if (ICS_RANK (ics1) == USER_RANK)
|
||||
if (ICS_USER_FLAG (ics1))
|
||||
{
|
||||
tree t1, t2;
|
||||
|
||||
|
@ -5235,16 +5379,6 @@ compare_ics (ics1, ics2)
|
|||
conversion. */
|
||||
#endif
|
||||
|
||||
if (TREE_CODE (ics1) == QUAL_CONV)
|
||||
main1 = TREE_OPERAND (ics1, 0);
|
||||
else
|
||||
main1 = ics1;
|
||||
|
||||
if (TREE_CODE (ics2) == QUAL_CONV)
|
||||
main2 = TREE_OPERAND (ics2, 0);
|
||||
else
|
||||
main2 = ics2;
|
||||
|
||||
if (TREE_CODE (main1) != TREE_CODE (main2))
|
||||
return 0;
|
||||
|
||||
|
@ -5410,6 +5544,13 @@ joust (cand1, cand2)
|
|||
int winner = 0;
|
||||
int i, off1 = 0, off2 = 0, len;
|
||||
|
||||
/* Candidates that involve bad conversions are always worse than those
|
||||
that don't. */
|
||||
if (cand1->viable > cand2->viable)
|
||||
return 1;
|
||||
if (cand1->viable < cand2->viable)
|
||||
return -1;
|
||||
|
||||
/* a viable function F1
|
||||
is defined to be a better function than another viable function F2 if
|
||||
for all arguments i, ICSi(F1) is not a worse conversion sequence than
|
||||
|
|
|
@ -1520,6 +1520,8 @@ extern tree long_long_integer_type_node, long_long_unsigned_type_node;
|
|||
extern tree integer_two_node, integer_three_node;
|
||||
extern tree boolean_type_node, boolean_true_node, boolean_false_node;
|
||||
|
||||
extern tree null_node;
|
||||
|
||||
/* in pt.c */
|
||||
|
||||
extern tree current_template_parms;
|
||||
|
@ -2410,6 +2412,8 @@ extern tree break_out_target_exprs PROTO((tree));
|
|||
extern tree get_type_decl PROTO((tree));
|
||||
extern tree vec_binfo_member PROTO((tree, tree));
|
||||
extern tree hack_decl_function_context PROTO((tree));
|
||||
extern tree lvalue_type PROTO((tree));
|
||||
extern tree error_type PROTO((tree));
|
||||
|
||||
/* in typeck.c */
|
||||
extern tree condition_conversion PROTO((tree));
|
||||
|
|
|
@ -341,6 +341,11 @@ tree static_aggregates;
|
|||
tree integer_zero_node;
|
||||
tree null_pointer_node;
|
||||
|
||||
/* The value for __null (NULL), either of type `void *' or, with -ansi,
|
||||
an integer type of the same size. */
|
||||
|
||||
tree null_node;
|
||||
|
||||
/* A node for the integer constants 1, 2, and 3. */
|
||||
|
||||
tree integer_one_node, integer_two_node, integer_three_node;
|
||||
|
@ -4911,7 +4916,14 @@ init_decl_processing ()
|
|||
void_list_node = build_tree_list (NULL_TREE, void_type_node);
|
||||
TREE_PARMLIST (void_list_node) = 1;
|
||||
|
||||
null_pointer_node = build_int_2 (0, 0);
|
||||
TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node);
|
||||
layout_type (TREE_TYPE (null_pointer_node));
|
||||
|
||||
if (flag_ansi)
|
||||
TREE_TYPE (null_node) = type_for_size (POINTER_SIZE, 0);
|
||||
else
|
||||
TREE_TYPE (null_node) = build_pointer_type (void_type_node);
|
||||
|
||||
/* Used for expressions that do nothing, but are not errors. */
|
||||
void_zero_node = build_int_2 (0, 0);
|
||||
|
@ -11086,7 +11098,7 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
|
|||
It doesn't matter whether it's inline or not. */
|
||||
else if (interface_unknown == 0
|
||||
&& (! DECL_TEMPLATE_INSTANTIATION (decl1)
|
||||
|| flag_external_templates))
|
||||
|| flag_alt_external_templates))
|
||||
{
|
||||
if (DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)
|
||||
|| current_template_parms)
|
||||
|
|
100
gcc/cp/decl2.c
100
gcc/cp/decl2.c
|
@ -128,11 +128,7 @@ int flag_ansi;
|
|||
/* Nonzero means do argument matching for overloading according to the
|
||||
ANSI rules, rather than what g++ used to believe to be correct. */
|
||||
|
||||
#ifdef NEW_OVER
|
||||
int flag_ansi_overloading = 1;
|
||||
#else
|
||||
int flag_ansi_overloading;
|
||||
#endif
|
||||
|
||||
/* Nonzero means do emit exported implementations of functions even if
|
||||
they can be inlined. */
|
||||
|
@ -2481,6 +2477,31 @@ mark_vtable_entries (decl)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set DECL up to have the closest approximation of "initialized common"
|
||||
linkage available. */
|
||||
|
||||
void
|
||||
comdat_linkage (decl)
|
||||
tree decl;
|
||||
{
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
|
||||
#ifdef DECL_ONE_ONLY
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
{
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flag_weak)
|
||||
{
|
||||
DECL_WEAK (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
|
||||
based on TYPE and other static flags.
|
||||
|
||||
|
@ -2532,21 +2553,7 @@ import_export_vtable (decl, type, final)
|
|||
|
||||
if (final || ! found)
|
||||
{
|
||||
#ifdef DECL_ONE_ONLY
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (flag_weak)
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_WEAK (decl) = 1;
|
||||
}
|
||||
else
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
comdat_linkage (decl);
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
}
|
||||
else
|
||||
|
@ -2764,17 +2771,7 @@ import_export_decl (decl)
|
|||
&& (flag_implicit_templates || DECL_THIS_INLINE (decl)))
|
||||
{
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
#ifdef DECL_ONE_ONLY
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
else
|
||||
#endif
|
||||
if (flag_weak)
|
||||
DECL_WEAK (decl) = 1;
|
||||
else
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
}
|
||||
comdat_linkage (decl);
|
||||
/* Dynamically initialized vars go into common. */
|
||||
else if (DECL_INITIAL (decl) == NULL_TREE
|
||||
|| DECL_INITIAL (decl) == error_mark_node)
|
||||
|
@ -2784,14 +2781,18 @@ import_export_decl (decl)
|
|||
DECL_COMMON (decl) = 1;
|
||||
DECL_INITIAL (decl) = error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Statically initialized vars are weak or comdat, if
|
||||
supported. */
|
||||
#ifdef DECL_ONE_ONLY
|
||||
else if (SUPPORTS_ONE_ONLY)
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
#endif
|
||||
/* Statically initialized vars are weak or comdat, if supported. */
|
||||
else if (flag_weak)
|
||||
DECL_WEAK (decl) = 1;
|
||||
/* else leave vars public so multiple defs will break. */
|
||||
if (flag_weak)
|
||||
DECL_WEAK (decl) = 1;
|
||||
/* else leave vars public so multiple defs will break. */
|
||||
}
|
||||
}
|
||||
else
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 0;
|
||||
|
@ -2805,20 +2806,15 @@ import_export_decl (decl)
|
|||
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
|
||||
|| (DECL_THIS_INLINE (decl) && ! flag_implement_inlines));
|
||||
}
|
||||
#ifdef DECL_ONE_ONLY
|
||||
else if (SUPPORTS_ONE_ONLY)
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
#endif
|
||||
else if (flag_weak)
|
||||
DECL_WEAK (decl) = 1;
|
||||
else
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
/* tinfo function */
|
||||
else if (DECL_ARTIFICIAL (decl) && DECL_MUTABLE_P (decl))
|
||||
{
|
||||
tree ctype = TREE_TYPE (DECL_NAME (decl));
|
||||
if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype))
|
||||
if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
|
||||
&& TYPE_VIRTUAL_P (ctype))
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (decl)
|
||||
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
|
||||
|
@ -2826,25 +2822,13 @@ import_export_decl (decl)
|
|||
}
|
||||
else if (TYPE_BUILT_IN (ctype) && ctype == TYPE_MAIN_VARIANT (ctype))
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 0;
|
||||
#ifdef DECL_ONE_ONLY
|
||||
else if (SUPPORTS_ONE_ONLY)
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
#endif
|
||||
else if (flag_weak)
|
||||
DECL_WEAK (decl) = 1;
|
||||
else
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else if (DECL_C_STATIC (decl))
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
#ifdef DECL_ONE_ONLY
|
||||
else if (SUPPORTS_ONE_ONLY)
|
||||
DECL_ONE_ONLY (decl) = 1;
|
||||
#endif
|
||||
else if (flag_weak)
|
||||
DECL_WEAK (decl) = 1;
|
||||
else
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
comdat_linkage (decl);
|
||||
|
||||
DECL_INTERFACE_KNOWN (decl) = 1;
|
||||
}
|
||||
|
|
|
@ -1547,7 +1547,7 @@ args_as_string (p, v)
|
|||
OB_INIT ();
|
||||
for (; p; p = TREE_CHAIN (p))
|
||||
{
|
||||
dump_type (TREE_TYPE (TREE_VALUE (p)), v);
|
||||
dump_type (error_type (TREE_VALUE (p)), v);
|
||||
if (TREE_CHAIN (p))
|
||||
OB_PUTS (", ");
|
||||
}
|
||||
|
|
|
@ -592,6 +592,7 @@ do_unwind (inner_throw_label)
|
|||
temp = gen_reg_rtx (Pmode);
|
||||
emit_move_insn (temp, inner_throw_label);
|
||||
emit_move_insn (return_val_rtx, plus_constant (temp, -8));
|
||||
emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)));
|
||||
easy_expand_asm ("ret");
|
||||
easy_expand_asm ("restore");
|
||||
emit_barrier ();
|
||||
|
|
|
@ -3261,7 +3261,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
|
|||
tree type = TREE_TYPE (TREE_TYPE (base));
|
||||
tree size;
|
||||
|
||||
maxindex = convert (integer_type_node, maxindex);
|
||||
maxindex = convert (ptrdiff_type_node, maxindex);
|
||||
if (maxindex == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -3318,7 +3318,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
|
|||
goto done_init;
|
||||
}
|
||||
|
||||
iterator = get_temp_regvar (integer_type_node,
|
||||
iterator = get_temp_regvar (ptrdiff_type_node,
|
||||
build_int_2 (host_i, 0));
|
||||
init = NULL_TREE;
|
||||
goto init_by_default;
|
||||
|
@ -3340,7 +3340,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
|
|||
{
|
||||
tree itype;
|
||||
|
||||
iterator = get_temp_regvar (integer_type_node, maxindex);
|
||||
iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
|
||||
|
||||
init_by_default:
|
||||
|
||||
|
@ -3424,7 +3424,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
|
|||
build (PLUS_EXPR, build_pointer_type (type), base2, size), 0, 0);
|
||||
expand_loop_continue_here ();
|
||||
expand_exit_loop_if_false (0, build (NE_EXPR, boolean_type_node,
|
||||
build (PREDECREMENT_EXPR, integer_type_node, iterator, integer_one_node), minus_one));
|
||||
build (PREDECREMENT_EXPR, ptrdiff_type_node, iterator, integer_one_node), minus_one));
|
||||
|
||||
if (obey_regdecls)
|
||||
{
|
||||
|
|
|
@ -673,8 +673,8 @@ init_lex ()
|
|||
TREE_TYPE (signature_type_node) = signature_type_node;
|
||||
ridpointers[(int) RID_SIGNATURE] = signature_type_node;
|
||||
|
||||
null_pointer_node = build_int_2 (0, 0);
|
||||
ridpointers[RID_NULL] = null_pointer_node;
|
||||
null_node = build_int_2 (0, 0);
|
||||
ridpointers[RID_NULL] = null_node;
|
||||
|
||||
opname_tab[(int) COMPONENT_REF] = "->";
|
||||
opname_tab[(int) MEMBER_REF] = "->*";
|
||||
|
@ -1692,6 +1692,9 @@ cons_up_default_function (type, full_name, kind)
|
|||
if (fn == void_type_node)
|
||||
return fn;
|
||||
|
||||
if (kind > 2)
|
||||
SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn)));
|
||||
|
||||
#if 0
|
||||
if (processing_template_defn)
|
||||
{
|
||||
|
|
|
@ -1713,15 +1713,7 @@ make_thunk (function, delta)
|
|||
DECL_INITIAL (thunk) = function;
|
||||
THUNK_DELTA (thunk) = delta;
|
||||
DECL_EXTERNAL (thunk) = 1;
|
||||
#ifdef DECL_ONE_ONLY
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
{
|
||||
DECL_ONE_ONLY (thunk) = 1;
|
||||
TREE_PUBLIC (thunk) = 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
TREE_PUBLIC (thunk) = 0;
|
||||
comdat_linkage (thunk);
|
||||
/* So that finish_file can write out any thunks that need to be: */
|
||||
pushdecl_top_level (thunk);
|
||||
}
|
||||
|
|
22
gcc/cp/pt.c
22
gcc/cp/pt.c
|
@ -1240,6 +1240,8 @@ instantiate_class_template (type)
|
|||
TYPE_HAS_CONVERSION (type) = TYPE_HAS_CONVERSION (pattern);
|
||||
TYPE_USES_COMPLEX_INHERITANCE (type)
|
||||
= TYPE_USES_COMPLEX_INHERITANCE (pattern);
|
||||
TYPE_USES_MULTIPLE_INHERITANCE (type)
|
||||
= TYPE_USES_MULTIPLE_INHERITANCE (pattern);
|
||||
TYPE_USES_VIRTUAL_BASECLASSES (type)
|
||||
= TYPE_USES_VIRTUAL_BASECLASSES (pattern);
|
||||
TYPE_PACKED (type) = TYPE_PACKED (pattern);
|
||||
|
@ -1627,8 +1629,10 @@ tsubst (t, args, nargs, in_decl)
|
|||
if (TREE_STATIC (r))
|
||||
DECL_ASSEMBLER_NAME (r)
|
||||
= build_static_name (DECL_CONTEXT (r), DECL_NAME (r));
|
||||
DECL_INITIAL (r) = tsubst_expr
|
||||
(DECL_INITIAL (t), args, nargs, in_decl);
|
||||
|
||||
/* Don't try to expand the initializer until someone tries to use
|
||||
this variable; otherwise we run into circular dependencies. */
|
||||
DECL_INITIAL (r) = NULL_TREE;
|
||||
|
||||
DECL_RTL (r) = 0;
|
||||
DECL_SIZE (r) = 0;
|
||||
|
@ -3283,6 +3287,14 @@ instantiate_decl (d)
|
|||
import_export_decl (d);
|
||||
}
|
||||
|
||||
/* We need to set up DECL_INITIAL regardless of pattern_defined if the
|
||||
variable is a static const initialized in the class body. */
|
||||
if (TREE_CODE (d) == VAR_DECL
|
||||
&& ! DECL_INITIAL (d) && DECL_INITIAL (pattern))
|
||||
DECL_INITIAL (d) = tsubst_expr
|
||||
(DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
|
||||
TREE_VEC_LENGTH (args), tmpl);
|
||||
|
||||
if (! pattern_defined
|
||||
|| (TREE_CODE (d) == FUNCTION_DECL && ! DECL_INLINE (d)
|
||||
&& (! DECL_INTERFACE_KNOWN (d)
|
||||
|
@ -3308,6 +3320,12 @@ instantiate_decl (d)
|
|||
td = tsubst (pattern, &TREE_VEC_ELT (args, 0), TREE_VEC_LENGTH (args), tmpl);
|
||||
DECL_TEMPLATE_INFO (pattern) = save_ti;
|
||||
|
||||
/* And set up DECL_INITIAL, since tsubst doesn't. */
|
||||
if (TREE_CODE (td) == VAR_DECL)
|
||||
DECL_INITIAL (td) = tsubst_expr
|
||||
(DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
|
||||
TREE_VEC_LENGTH (args), tmpl);
|
||||
|
||||
/* Convince duplicate_decls to use the DECL_ARGUMENTS from the new decl. */
|
||||
if (TREE_CODE (d) == FUNCTION_DECL)
|
||||
DECL_INITIAL (td) = error_mark_node;
|
||||
|
|
|
@ -2105,3 +2105,31 @@ make_temp_vec (len)
|
|||
pop_obstacks ();
|
||||
return node;
|
||||
}
|
||||
|
||||
/* The type of ARG when used as an lvalue. */
|
||||
|
||||
tree
|
||||
lvalue_type (arg)
|
||||
tree arg;
|
||||
{
|
||||
return cp_build_type_variant
|
||||
(TREE_TYPE (arg), TREE_READONLY (arg), TREE_THIS_VOLATILE (arg));
|
||||
}
|
||||
|
||||
/* The type of ARG for printing error messages; denote lvalues with
|
||||
reference types. */
|
||||
|
||||
tree
|
||||
error_type (arg)
|
||||
tree arg;
|
||||
{
|
||||
tree type = TREE_TYPE (arg);
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
;
|
||||
else if (real_lvalue_p (arg))
|
||||
type = build_reference_type (lvalue_type (arg));
|
||||
else if (IS_AGGR_TYPE (type))
|
||||
type = lvalue_type (arg);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
|
|
@ -1792,7 +1792,8 @@ build_component_ref (datum, component, basetype_path, protect)
|
|||
hierarchy, the compiler will abort (because vptr lookups are
|
||||
not supposed to be ambiguous. */
|
||||
field = CLASSTYPE_VFIELD (basetype);
|
||||
else if (TREE_CODE (component) == FIELD_DECL)
|
||||
else if (TREE_CODE (component) == FIELD_DECL
|
||||
|| TREE_CODE (component) == TYPE_DECL)
|
||||
{
|
||||
field = component;
|
||||
}
|
||||
|
@ -4829,16 +4830,14 @@ build_conditional_expr (ifexp, op1, op2)
|
|||
pedwarn ("ANSI C++ forbids conditional expr with only one void side");
|
||||
result_type = void_type_node;
|
||||
}
|
||||
else if (code1 == POINTER_TYPE && null_ptr_cst_p (op2))
|
||||
result_type = qualify_type (type1, type2);
|
||||
else if (code2 == POINTER_TYPE && null_ptr_cst_p (op1))
|
||||
result_type = qualify_type (type2, type1);
|
||||
else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
|
||||
{
|
||||
if (comp_target_types (type1, type2, 1))
|
||||
result_type = common_type (type1, type2);
|
||||
else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
|
||||
&& TREE_CODE (orig_op1) != NOP_EXPR)
|
||||
result_type = qualify_type (type2, type1);
|
||||
else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node
|
||||
&& TREE_CODE (orig_op2) != NOP_EXPR)
|
||||
result_type = qualify_type (type1, type2);
|
||||
else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node)
|
||||
{
|
||||
if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE)
|
||||
|
@ -4883,20 +4882,12 @@ build_conditional_expr (ifexp, op1, op2)
|
|||
}
|
||||
else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
|
||||
{
|
||||
if (!integer_zerop (op2))
|
||||
pedwarn ("pointer/integer type mismatch in conditional expression");
|
||||
else
|
||||
op2 = null_pointer_node;
|
||||
|
||||
pedwarn ("pointer/integer type mismatch in conditional expression");
|
||||
result_type = type1;
|
||||
}
|
||||
else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
|
||||
{
|
||||
if (!integer_zerop (op1))
|
||||
pedwarn ("pointer/integer type mismatch in conditional expression");
|
||||
else
|
||||
op1 = null_pointer_node;
|
||||
|
||||
pedwarn ("pointer/integer type mismatch in conditional expression");
|
||||
result_type = type2;
|
||||
}
|
||||
|
||||
|
@ -6376,7 +6367,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (ctt < 0)
|
||||
if (ctt < 0 && TYPE_MAIN_VARIANT (ttl) != TYPE_MAIN_VARIANT (ttr))
|
||||
cp_pedwarn ("converting `%T' to `%T' is a contravariance violation",
|
||||
rhstype, type);
|
||||
|
||||
|
@ -7269,6 +7260,10 @@ comp_ptr_ttypes_real (to, from, constp)
|
|||
if (TREE_CODE (to) != TREE_CODE (from))
|
||||
return 0;
|
||||
|
||||
if (TREE_CODE (from) == OFFSET_TYPE
|
||||
&& TYPE_OFFSET_BASETYPE (from) == TYPE_OFFSET_BASETYPE (to))
|
||||
continue;
|
||||
|
||||
/* Const and volatile mean something different for function types,
|
||||
so the usual checks are not appropriate. */
|
||||
if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
|
||||
|
@ -7299,3 +7294,26 @@ comp_ptr_ttypes (to, from)
|
|||
{
|
||||
return comp_ptr_ttypes_real (to, from, 1);
|
||||
}
|
||||
|
||||
/* Returns 1 if to and from are (possibly multi-level) pointers to the same
|
||||
type or inheritance-related types, regardless of cv-quals. */
|
||||
|
||||
int
|
||||
ptr_reasonably_similar (to, from)
|
||||
tree to, from;
|
||||
{
|
||||
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
|
||||
{
|
||||
if (TREE_CODE (to) != TREE_CODE (from))
|
||||
return 0;
|
||||
|
||||
if (TREE_CODE (from) == OFFSET_TYPE
|
||||
&& comptypes (TYPE_OFFSET_BASETYPE (to),
|
||||
TYPE_OFFSET_BASETYPE (from), -1))
|
||||
continue;
|
||||
|
||||
if (TREE_CODE (to) != POINTER_TYPE)
|
||||
return comptypes
|
||||
(TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), -1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue