Commit e6e174e5 by Jason Merrill Committed by Jason Merrill

call.c (standard_conversion): instantiate_type here.

	* call.c (standard_conversion): instantiate_type here.
	(reference_binding): And here.
	(implicit_conversion): Not here.
	(build_op_delete_call): No need to cons up an OVERLOAD.
	* cvt.c (cp_convert_to_pointer): instantiate_type here.
	(convert_to_reference): And here.
	* decl.c (grok_reference_init): Not here.
	(grokparms): Or here.
	* typeck2.c (digest_init): Or here.
	* typeck.c (decay_conversion): Take the address of overloaded
	functions, too.
	(require_instantiated_type): Lose.
	(convert_arguments): Don't handle unknown types here.
	(build_c_cast): Likewise.
	(build_binary_op): Gut.
	(build_conditional_expr): Don't require_instantiated_type.
	(build_modify_expr): Likewise.
	(build_static_cast): Don't instantiate_type.
	(build_reinterpret_cast): Likewise.
	(build_const_cast): Likewise.
	(convert_for_initialization): Likewise.
	(build_ptrmemfunc): Use type_unknown_p.
	(convert_for_assignment): Also do default_conversion on overloaded
	functions.  Hand them off to ocp_convert.
	* pt.c (convert_nontype_argument): Tell instantiate_type to complain.
	Do complain about overload resolution producing a non-public fn.

From-SVN: r23373
parent 950ad3c3
1998-10-27 Jason Merrill <jason@yorick.cygnus.com>
* call.c (standard_conversion): instantiate_type here.
(reference_binding): And here.
(implicit_conversion): Not here.
(build_op_delete_call): No need to cons up an OVERLOAD.
* cvt.c (cp_convert_to_pointer): instantiate_type here.
(convert_to_reference): And here.
* decl.c (grok_reference_init): Not here.
(grokparms): Or here.
* typeck2.c (digest_init): Or here.
* typeck.c (decay_conversion): Take the address of overloaded
functions, too.
(require_instantiated_type): Lose.
(convert_arguments): Don't handle unknown types here.
(build_c_cast): Likewise.
(build_binary_op): Gut.
(build_conditional_expr): Don't require_instantiated_type.
(build_modify_expr): Likewise.
(build_static_cast): Don't instantiate_type.
(build_reinterpret_cast): Likewise.
(build_const_cast): Likewise.
(convert_for_initialization): Likewise.
(build_ptrmemfunc): Use type_unknown_p.
(convert_for_assignment): Also do default_conversion on overloaded
functions. Hand them off to ocp_convert.
* pt.c (convert_nontype_argument): Tell instantiate_type to complain.
Do complain about overload resolution producing a non-public fn.
1998-10-26 Mark Mitchell <mark@markmitchell.com> 1998-10-26 Mark Mitchell <mark@markmitchell.com>
* error.c (dump_decl): Deal with TEMPLATE_DECLs that are * error.c (dump_decl): Deal with TEMPLATE_DECLs that are
......
...@@ -803,6 +803,15 @@ standard_conversion (to, from, expr) ...@@ -803,6 +803,15 @@ standard_conversion (to, from, expr)
to = strip_top_quals (to); to = strip_top_quals (to);
from = strip_top_quals (from); from = strip_top_quals (from);
if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
&& expr && type_unknown_p (expr))
{
expr = instantiate_type (to, expr, 0);
if (expr == error_mark_node)
return NULL_TREE;
from = TREE_TYPE (expr);
}
fcode = TREE_CODE (from); fcode = TREE_CODE (from);
tcode = TREE_CODE (to); tcode = TREE_CODE (to);
...@@ -968,6 +977,14 @@ reference_binding (rto, rfrom, expr, flags) ...@@ -968,6 +977,14 @@ reference_binding (rto, rfrom, expr, flags)
tree from = rfrom; tree from = rfrom;
int related; int related;
if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
{
expr = instantiate_type (to, expr, 0);
if (expr == error_mark_node)
return NULL_TREE;
from = TREE_TYPE (expr);
}
if (TREE_CODE (from) == REFERENCE_TYPE) if (TREE_CODE (from) == REFERENCE_TYPE)
from = TREE_TYPE (from); from = TREE_TYPE (from);
else if (! expr || ! real_lvalue_p (expr)) else if (! expr || ! real_lvalue_p (expr))
...@@ -1032,14 +1049,6 @@ implicit_conversion (to, from, expr, flags) ...@@ -1032,14 +1049,6 @@ implicit_conversion (to, from, expr, flags)
tree conv; tree conv;
struct z_candidate *cand; struct z_candidate *cand;
if (expr && type_unknown_p (expr))
{
expr = instantiate_type (to, expr, 0);
if (expr == error_mark_node)
return 0;
from = TREE_TYPE (expr);
}
if (TREE_CODE (to) == REFERENCE_TYPE) if (TREE_CODE (to) == REFERENCE_TYPE)
conv = reference_binding (to, from, expr, flags); conv = reference_binding (to, from, expr, flags);
else else
...@@ -1049,7 +1058,7 @@ implicit_conversion (to, from, expr, flags) ...@@ -1049,7 +1058,7 @@ implicit_conversion (to, from, expr, flags)
; ;
else if (expr != NULL_TREE else if (expr != NULL_TREE
&& (IS_AGGR_TYPE (non_reference (from)) && (IS_AGGR_TYPE (non_reference (from))
|| IS_AGGR_TYPE (non_reference (to))) || IS_AGGR_TYPE (non_reference (to)))
&& (flags & LOOKUP_NO_CONVERSION) == 0) && (flags & LOOKUP_NO_CONVERSION) == 0)
{ {
cand = build_user_type_conversion_1 cand = build_user_type_conversion_1
...@@ -2907,11 +2916,6 @@ build_op_delete_call (code, addr, size, flags, placement) ...@@ -2907,11 +2916,6 @@ build_op_delete_call (code, addr, size, flags, placement)
if (type != TYPE_MAIN_VARIANT (type)) if (type != TYPE_MAIN_VARIANT (type))
addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr); addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr);
/* instantiate_type will always return a plain function; pretend it's
overloaded. */
if (TREE_CODE (fns) == FUNCTION_DECL)
fns = scratch_ovl_cons (fns, NULL_TREE);
fn = instantiate_type (fntype, fns, 0); fn = instantiate_type (fntype, fns, 0);
if (fn != error_mark_node) if (fn != error_mark_node)
......
...@@ -4968,8 +4968,8 @@ validate_lhs (lhstype, complain) ...@@ -4968,8 +4968,8 @@ validate_lhs (lhstype, complain)
try many possible instantiations, in hopes that at least one will try many possible instantiations, in hopes that at least one will
work. work.
This function is used in build_modify_expr, convert_arguments, For non-recursive calls, LHSTYPE should be a function, pointer to
build_c_cast, and compute_conversion_costs. */ function, or a pointer to member function. */
tree tree
instantiate_type (lhstype, rhs, complain) instantiate_type (lhstype, rhs, complain)
...@@ -5132,8 +5132,8 @@ instantiate_type (lhstype, rhs, complain) ...@@ -5132,8 +5132,8 @@ instantiate_type (lhstype, rhs, complain)
{ {
if (complain) if (complain)
cp_error("cannot resolve overloaded function `%D' " cp_error("cannot resolve overloaded function `%D' "
"based on non-function type", "based on non-function type `%T'",
DECL_NAME (OVL_FUNCTION (rhs))); DECL_NAME (OVL_FUNCTION (rhs)), lhstype);
return error_mark_node; return error_mark_node;
} }
......
...@@ -3136,7 +3136,6 @@ extern tree complete_type PROTO((tree)); ...@@ -3136,7 +3136,6 @@ extern tree complete_type PROTO((tree));
extern tree complete_type_or_else PROTO((tree)); extern tree complete_type_or_else PROTO((tree));
extern int type_unknown_p PROTO((tree)); extern int type_unknown_p PROTO((tree));
extern int fntype_p PROTO((tree)); extern int fntype_p PROTO((tree));
extern tree require_instantiated_type PROTO((tree, tree, tree));
extern tree commonparms PROTO((tree, tree)); extern tree commonparms PROTO((tree, tree));
extern tree original_type PROTO((tree)); extern tree original_type PROTO((tree));
extern tree common_type PROTO((tree, tree)); extern tree common_type PROTO((tree, tree));
......
...@@ -249,6 +249,9 @@ cp_convert_to_pointer (type, expr) ...@@ -249,6 +249,9 @@ cp_convert_to_pointer (type, expr)
return convert_to_pointer (type, expr); return convert_to_pointer (type, expr);
} }
if (type_unknown_p (expr))
return instantiate_type (type, expr, 1);
cp_error ("cannot convert `%E' from type `%T' to type `%T'", cp_error ("cannot convert `%E' from type `%T' to type `%T'",
expr, intype, type); expr, intype, type);
return error_mark_node; return error_mark_node;
...@@ -407,6 +410,12 @@ convert_to_reference (reftype, expr, convtype, flags, decl) ...@@ -407,6 +410,12 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
tree rval_as_conversion = NULL_TREE; tree rval_as_conversion = NULL_TREE;
int i; int i;
if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node)
{
expr = instantiate_type (type, expr, 0);
intype = TREE_TYPE (expr);
}
if (TREE_CODE (intype) == REFERENCE_TYPE) if (TREE_CODE (intype) == REFERENCE_TYPE)
my_friendly_abort (364); my_friendly_abort (364);
......
...@@ -6921,10 +6921,6 @@ grok_reference_init (decl, type, init) ...@@ -6921,10 +6921,6 @@ grok_reference_init (decl, type, init)
return; return;
} }
if (TREE_TYPE (init) && TREE_CODE (TREE_TYPE (init)) == UNKNOWN_TYPE)
/* decay_conversion is probably wrong for references to functions. */
init = decay_conversion (instantiate_type (TREE_TYPE (type), init, 1));
if (TREE_CODE (init) == TREE_LIST) if (TREE_CODE (init) == TREE_LIST)
init = build_compound_expr (init); init = build_compound_expr (init);
...@@ -11146,8 +11142,12 @@ grokparms (first_parm, funcdef_flag) ...@@ -11146,8 +11142,12 @@ grokparms (first_parm, funcdef_flag)
else if (TREE_READONLY_DECL_P (init)) else if (TREE_READONLY_DECL_P (init))
init = decl_constant_value (init); init = decl_constant_value (init);
} }
else else if (TREE_TYPE (init) == NULL_TREE)
init = require_instantiated_type (type, init, integer_zero_node); {
error ("argument list may not have an initializer list");
init = error_mark_node;
}
if (! processing_template_decl if (! processing_template_decl
&& init != error_mark_node && init != error_mark_node
&& TREE_CODE (init) != DEFAULT_ARG && TREE_CODE (init) != DEFAULT_ARG
......
...@@ -2510,7 +2510,7 @@ convert_nontype_argument (type, expr) ...@@ -2510,7 +2510,7 @@ convert_nontype_argument (type, expr)
else else
fns = expr; fns = expr;
fn = instantiate_type (type_pointed_to, fns, 0); fn = instantiate_type (type_pointed_to, fns, 1);
if (fn == error_mark_node) if (fn == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -2567,22 +2567,24 @@ convert_nontype_argument (type, expr) ...@@ -2567,22 +2567,24 @@ convert_nontype_argument (type, expr)
tree fns = expr; tree fns = expr;
tree fn; tree fn;
fn = instantiate_type (type_referred_to, fns, 0); fn = instantiate_type (type_referred_to, fns, 1);
if (fn == error_mark_node)
return error_mark_node;
if (!TREE_PUBLIC (fn)) if (!TREE_PUBLIC (fn))
{ {
#if 0
if (really_overloaded_fn (fns)) if (really_overloaded_fn (fns))
/* Don't issue an error here; we might get a different /* Don't issue an error here; we might get a different
function if the overloading had worked out function if the overloading had worked out
differently. */ differently. */
return error_mark_node; return error_mark_node;
else else
#endif
goto bad_argument; goto bad_argument;
} }
if (fn == error_mark_node)
return error_mark_node;
my_friendly_assert (comptypes (type_referred_to, TREE_TYPE (fn), 1), my_friendly_assert (comptypes (type_referred_to, TREE_TYPE (fn), 1),
0); 0);
...@@ -2646,7 +2648,7 @@ convert_nontype_argument (type, expr) ...@@ -2646,7 +2648,7 @@ convert_nontype_argument (type, expr)
fns = TREE_OPERAND (expr, 0); fns = TREE_OPERAND (expr, 0);
fn = instantiate_type (TREE_TYPE (TREE_TYPE (type)), fn = instantiate_type (TREE_TYPE (TREE_TYPE (type)),
fns, 0); fns, 1);
if (fn == error_mark_node) if (fn == error_mark_node)
return error_mark_node; return error_mark_node;
......
...@@ -206,32 +206,6 @@ fntype_p (t) ...@@ -206,32 +206,6 @@ fntype_p (t)
|| TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE))); || TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)));
} }
/* Do `exp = require_instantiated_type (type, exp);' to make sure EXP
does not have an uninstantiated type.
TYPE is type to instantiate with, if uninstantiated. */
tree
require_instantiated_type (type, exp, errval)
tree type, exp, errval;
{
if (TREE_TYPE (exp) == NULL_TREE)
{
error ("argument list may not have an initializer list");
return errval;
}
if (TREE_CODE (exp) == OVERLOAD
|| TREE_TYPE (exp) == unknown_type_node
|| (TREE_CODE (TREE_TYPE (exp)) == OFFSET_TYPE
&& TREE_TYPE (TREE_TYPE (exp)) == unknown_type_node))
{
exp = instantiate_type (type, exp, 1);
if (TREE_TYPE (exp) == error_mark_node)
return errval;
}
return exp;
}
/* Return a variant of TYPE which has all the type qualifiers of LIKE /* Return a variant of TYPE which has all the type qualifiers of LIKE
as well as those of TYPE. */ as well as those of TYPE. */
...@@ -1690,13 +1664,13 @@ decay_conversion (exp) ...@@ -1690,13 +1664,13 @@ decay_conversion (exp)
error ("void value not ignored as it ought to be"); error ("void value not ignored as it ought to be");
return error_mark_node; return error_mark_node;
} }
if (code == FUNCTION_TYPE) if (code == METHOD_TYPE)
{ {
cp_pedwarn ("assuming & on `%E'", exp);
return build_unary_op (ADDR_EXPR, exp, 0); return build_unary_op (ADDR_EXPR, exp, 0);
} }
if (code == METHOD_TYPE) if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
{ {
cp_pedwarn ("assuming & on `%E'", exp);
return build_unary_op (ADDR_EXPR, exp, 0); return build_unary_op (ADDR_EXPR, exp, 0);
} }
if (code == ARRAY_TYPE) if (code == ARRAY_TYPE)
...@@ -3045,25 +3019,7 @@ convert_arguments (typelist, values, fndecl, flags) ...@@ -3045,25 +3019,7 @@ convert_arguments (typelist, values, fndecl, flags)
break; break;
} }
/* The tree type of the parameter being passed may not yet be if (TREE_CODE (val) == OFFSET_REF)
known. In this case, its type is TYPE_UNKNOWN, and will
be instantiated by the type given by TYPE. If TYPE
is also NULL, the tree type of VAL is ERROR_MARK_NODE. */
if (type && type_unknown_p (val))
val = require_instantiated_type (type, val, integer_zero_node);
else if (type_unknown_p (val))
{
/* Strip the `&' from an overloaded FUNCTION_DECL. */
if (TREE_CODE (val) == ADDR_EXPR)
val = TREE_OPERAND (val, 0);
if (really_overloaded_fn (val))
cp_error ("insufficient type information to resolve address of overloaded function `%D'",
DECL_NAME (get_first_fn (val)));
else
error ("insufficient type information in parameter list");
val = integer_zero_node;
}
else if (TREE_CODE (val) == OFFSET_REF)
val = resolve_offset_ref (val); val = resolve_offset_ref (val);
/* 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.
...@@ -3188,39 +3144,7 @@ build_binary_op (code, arg1, arg2, convert_p) ...@@ -3188,39 +3144,7 @@ build_binary_op (code, arg1, arg2, convert_p)
tree arg1, arg2; tree arg1, arg2;
int convert_p; int convert_p;
{ {
tree args[2]; return build_binary_op_nodefault (code, arg1, arg2, code);
args[0] = arg1;
args[1] = arg2;
if (convert_p)
{
tree type0, type1;
args[0] = decay_conversion (args[0]);
args[1] = decay_conversion (args[1]);
if (args[0] == error_mark_node || args[1] == error_mark_node)
return error_mark_node;
type0 = TREE_TYPE (args[0]);
type1 = TREE_TYPE (args[1]);
if (type_unknown_p (args[0]))
{
args[0] = instantiate_type (type1, args[0], 1);
args[0] = decay_conversion (args[0]);
}
else if (type_unknown_p (args[1]))
{
args[1] = require_instantiated_type (type0, args[1],
error_mark_node);
args[1] = decay_conversion (args[1]);
}
if (IS_AGGR_TYPE (type0) || IS_AGGR_TYPE (type1))
my_friendly_abort (754867);
}
return build_binary_op_nodefault (code, args[0], args[1], code);
} }
/* Build a binary-operation expression without default conversions. /* Build a binary-operation expression without default conversions.
...@@ -5026,13 +4950,6 @@ build_conditional_expr (ifexp, op1, op2) ...@@ -5026,13 +4950,6 @@ build_conditional_expr (ifexp, op1, op2)
if (TREE_CODE (ifexp) == ERROR_MARK) if (TREE_CODE (ifexp) == ERROR_MARK)
return error_mark_node; return error_mark_node;
op1 = require_instantiated_type (TREE_TYPE (op2), op1, error_mark_node);
if (op1 == error_mark_node)
return error_mark_node;
op2 = require_instantiated_type (TREE_TYPE (op1), op2, error_mark_node);
if (op2 == error_mark_node)
return error_mark_node;
/* C++: REFERENCE_TYPES must be dereferenced. */ /* C++: REFERENCE_TYPES must be dereferenced. */
type1 = TREE_TYPE (op1); type1 = TREE_TYPE (op1);
code1 = TREE_CODE (type1); code1 = TREE_CODE (type1);
...@@ -5229,6 +5146,10 @@ build_conditional_expr (ifexp, op1, op2) ...@@ -5229,6 +5146,10 @@ build_conditional_expr (ifexp, op1, op2)
pedwarn ("pointer/integer type mismatch in conditional expression"); pedwarn ("pointer/integer type mismatch in conditional expression");
result_type = type2; result_type = type2;
} }
if (type2 == unknown_type_node)
result_type = type1;
else if (type1 == unknown_type_node)
result_type = type2;
if (!result_type) if (!result_type)
{ {
...@@ -5431,13 +5352,6 @@ build_static_cast (type, expr) ...@@ -5431,13 +5352,6 @@ build_static_cast (type, expr)
if (TREE_CODE (type) == VOID_TYPE) if (TREE_CODE (type) == VOID_TYPE)
return build1 (CONVERT_EXPR, type, expr); return build1 (CONVERT_EXPR, type, expr);
if (type_unknown_p (expr))
{
expr = instantiate_type (type, expr, 1);
if (expr == error_mark_node)
return error_mark_node;
}
if (TREE_CODE (type) == REFERENCE_TYPE) if (TREE_CODE (type) == REFERENCE_TYPE)
return (convert_from_reference return (convert_from_reference
(convert_to_reference (type, expr, CONV_STATIC|CONV_IMPLICIT, (convert_to_reference (type, expr, CONV_STATIC|CONV_IMPLICIT,
...@@ -5521,13 +5435,6 @@ build_reinterpret_cast (type, expr) ...@@ -5521,13 +5435,6 @@ build_reinterpret_cast (type, expr)
expr = TREE_OPERAND (expr, 0); expr = TREE_OPERAND (expr, 0);
} }
if (type_unknown_p (expr))
{
expr = instantiate_type (type, expr, 1);
if (expr == error_mark_node)
return error_mark_node;
}
intype = TREE_TYPE (expr); intype = TREE_TYPE (expr);
if (TREE_CODE (type) == REFERENCE_TYPE) if (TREE_CODE (type) == REFERENCE_TYPE)
...@@ -5622,13 +5529,6 @@ build_const_cast (type, expr) ...@@ -5622,13 +5529,6 @@ build_const_cast (type, expr)
expr = TREE_OPERAND (expr, 0); expr = TREE_OPERAND (expr, 0);
} }
if (type_unknown_p (expr))
{
expr = instantiate_type (type, expr, 1);
if (expr == error_mark_node)
return error_mark_node;
}
intype = TREE_TYPE (expr); intype = TREE_TYPE (expr);
if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1)) if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1))
...@@ -5667,6 +5567,7 @@ build_c_cast (type, expr) ...@@ -5667,6 +5567,7 @@ build_c_cast (type, expr)
tree type, expr; tree type, expr;
{ {
register tree value = expr; register tree value = expr;
tree otype;
if (type == error_mark_node || expr == error_mark_node) if (type == error_mark_node || expr == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -5721,109 +5622,94 @@ build_c_cast (type, expr) ...@@ -5721,109 +5622,94 @@ build_c_cast (type, expr)
return t; return t;
} }
if (TREE_CODE (type) == VOID_TYPE) /* Convert functions and arrays to pointers and
value = build1 (CONVERT_EXPR, type, value); convert references to their expanded types,
else if (TREE_TYPE (value) == NULL_TREE but don't convert any other types. If, however, we are
|| type_unknown_p (value)) casting to a class type, there's no reason to do this: the
{ cast will only succeed if there is a converting constructor,
value = instantiate_type (type, value, 1); and the default conversions will be done at that point. In
/* Did we lose? */ fact, doing the default conversion here is actually harmful
if (value == error_mark_node) in cases like this:
return error_mark_node;
} typedef int A[2];
else struct S { S(const A&); };
{
tree otype; since we don't want the array-to-pointer conversion done. */
if (!IS_AGGR_TYPE (type))
/* Convert functions and arrays to pointers and {
convert references to their expanded types, if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
but don't convert any other types. If, however, we are || (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
casting to a class type, there's no reason to do this: the /* Don't do the default conversion if we want a
cast will only succeed if there is a converting constructor, pointer to a function. */
and the default conversions will be done at that point. In && ! (TREE_CODE (type) == POINTER_TYPE
fact, doing the default conversion here is actually harmful && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
in cases like this: || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
typedef int A[2]; value = default_conversion (value);
struct S { S(const A&); }; }
else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
since we don't want the array-to-pointer conversion done. */ /* However, even for class types, we still need to strip away
if (!IS_AGGR_TYPE (type)) the reference type, since the call to convert_force below
{ does not expect the input expression to be of reference
if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE type. */
|| (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE value = convert_from_reference (value);
/* Don't do the default conversion if we want a
pointer to a function. */
&& ! (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
|| TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
value = default_conversion (value);
}
else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
/* However, even for class types, we still need to strip away
the reference type, since the call to convert_force below
does not expect the input expression to be of reference
type. */
value = convert_from_reference (value);
otype = TREE_TYPE (value); otype = TREE_TYPE (value);
/* Optionally warn about potentially worrisome casts. */ /* Optionally warn about potentially worrisome casts. */
if (warn_cast_qual if (warn_cast_qual
&& TREE_CODE (type) == POINTER_TYPE && TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE && TREE_CODE (otype) == POINTER_TYPE
&& !at_least_as_qualified_p (TREE_TYPE (type), && !at_least_as_qualified_p (TREE_TYPE (type),
TREE_TYPE (otype))) TREE_TYPE (otype)))
cp_warning ("cast discards qualifiers from pointer target type"); cp_warning ("cast discards qualifiers from pointer target type");
/* Warn about possible alignment problems. */ /* Warn about possible alignment problems. */
if (STRICT_ALIGNMENT && warn_cast_align if (STRICT_ALIGNMENT && warn_cast_align
&& TREE_CODE (type) == POINTER_TYPE && TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE && TREE_CODE (otype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
&& TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
&& TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
warning ("cast increases required alignment of target type"); warning ("cast increases required alignment of target type");
#if 0 #if 0
/* We should see about re-enabling these, they seem useful to /* We should see about re-enabling these, they seem useful to
me. */ me. */
if (TREE_CODE (type) == INTEGER_TYPE if (TREE_CODE (type) == INTEGER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE && TREE_CODE (otype) == POINTER_TYPE
&& TYPE_PRECISION (type) != TYPE_PRECISION (otype)) && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
warning ("cast from pointer to integer of different size"); warning ("cast from pointer to integer of different size");
if (TREE_CODE (type) == POINTER_TYPE if (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == INTEGER_TYPE && TREE_CODE (otype) == INTEGER_TYPE
&& TYPE_PRECISION (type) != TYPE_PRECISION (otype) && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
/* Don't warn about converting 0 to pointer, /* Don't warn about converting 0 to pointer,
provided the 0 was explicit--not cast or made by folding. */ provided the 0 was explicit--not cast or made by folding. */
&& !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value))) && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value)))
warning ("cast to pointer from integer of different size"); warning ("cast to pointer from integer of different size");
#endif #endif
if (TREE_CODE (type) == REFERENCE_TYPE) if (TREE_CODE (type) == REFERENCE_TYPE)
value = (convert_from_reference value = (convert_from_reference
(convert_to_reference (type, value, CONV_C_CAST, (convert_to_reference (type, value, CONV_C_CAST,
LOOKUP_COMPLAIN, NULL_TREE))); LOOKUP_COMPLAIN, NULL_TREE)));
else else
{ {
tree ovalue; tree ovalue;
if (TREE_READONLY_DECL_P (value)) if (TREE_READONLY_DECL_P (value))
value = decl_constant_value (value); value = decl_constant_value (value);
ovalue = value; ovalue = value;
value = convert_force (type, value, CONV_C_CAST); value = convert_force (type, value, CONV_C_CAST);
/* Ignore any integer overflow caused by the cast. */ /* Ignore any integer overflow caused by the cast. */
if (TREE_CODE (value) == INTEGER_CST) if (TREE_CODE (value) == INTEGER_CST)
{ {
TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue); TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
}
} }
} }
...@@ -6107,14 +5993,6 @@ build_modify_expr (lhs, modifycode, rhs) ...@@ -6107,14 +5993,6 @@ build_modify_expr (lhs, modifycode, rhs)
current_function_just_assigned_this = 1; current_function_just_assigned_this = 1;
} }
/* The TREE_TYPE of RHS may be TYPE_UNKNOWN. This can happen
when the type of RHS is not yet known, i.e. its type
is inherited from LHS. */
rhs = require_instantiated_type (lhstype, newrhs, error_mark_node);
if (rhs == error_mark_node)
return error_mark_node;
newrhs = rhs;
if (modifycode != INIT_EXPR) if (modifycode != INIT_EXPR)
{ {
/* Make modifycode now either a NOP_EXPR or an INIT_EXPR. */ /* Make modifycode now either a NOP_EXPR or an INIT_EXPR. */
...@@ -6529,9 +6407,7 @@ build_ptrmemfunc (type, pfn, force) ...@@ -6529,9 +6407,7 @@ build_ptrmemfunc (type, pfn, force)
pfn, NULL_TREE); pfn, NULL_TREE);
} }
if (TREE_CODE (pfn) == TREE_LIST if (type_unknown_p (pfn))
|| (TREE_CODE (pfn) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (pfn, 0)) == TREE_LIST))
return instantiate_type (type, pfn, 1); return instantiate_type (type, pfn, 1);
if (!force if (!force
...@@ -6608,9 +6484,6 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) ...@@ -6608,9 +6484,6 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (ARITHMETIC_TYPE_P (type) && rhs == null_node) if (ARITHMETIC_TYPE_P (type) && rhs == null_node)
cp_warning ("converting NULL to non-pointer type"); cp_warning ("converting NULL to non-pointer type");
if (coder == UNKNOWN_TYPE)
rhs = instantiate_type (type, rhs, 1);
if (coder == ERROR_MARK) if (coder == ERROR_MARK)
return error_mark_node; return error_mark_node;
...@@ -6640,12 +6513,17 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) ...@@ -6640,12 +6513,17 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
} }
if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE || is_overloaded_fn (rhs))
|| TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
rhs = default_conversion (rhs); rhs = default_conversion (rhs);
else if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE) else if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE)
rhs = convert_from_reference (rhs); rhs = convert_from_reference (rhs);
/* If rhs is some sort of overloaded function, ocp_convert will either
do the right thing or complain; we don't need to check anything else.
So just hand off. */
if (type_unknown_p (rhs))
return ocp_convert (type, rhs, CONV_IMPLICIT, LOOKUP_NORMAL);
rhstype = TREE_TYPE (rhs); rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype); coder = TREE_CODE (rhstype);
...@@ -7067,13 +6945,6 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) ...@@ -7067,13 +6945,6 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
rhstype = TREE_TYPE (rhs); rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype); coder = TREE_CODE (rhstype);
if (coder == UNKNOWN_TYPE)
{
rhs = instantiate_type (type, rhs, 1);
rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype);
}
if (coder == ERROR_MARK) if (coder == ERROR_MARK)
return error_mark_node; return error_mark_node;
......
...@@ -646,13 +646,6 @@ store_init_value (decl, init) ...@@ -646,13 +646,6 @@ store_init_value (decl, init)
else else
init = TREE_VALUE (init); init = TREE_VALUE (init);
} }
else if (TREE_TYPE (init) != 0
&& TREE_CODE (TREE_TYPE (init)) == OFFSET_TYPE)
{
/* Use the type of our variable to instantiate
the type of our initializer. */
init = instantiate_type (type, init, 1);
}
else if (TREE_CODE (init) == TREE_LIST else if (TREE_CODE (init) == TREE_LIST
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
{ {
......
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