Commit 27b8d0cd by Mark Mitchell Committed by Mark Mitchell

call.c (NEED_TEMPORARY_P): New macro.

	* call.c (NEED_TEMPORARY_P): New macro.
	(standard_conversion): Set it, for derived-to-base conversions.
	(reference_related_p): New function.
	(reference_compatible_p): Likewise.
	(convert_class_to_reference): Likewise.
	(direct_reference_binding): Likewise.
	(reference_binding): Rework for standards-compliance.
	(convert_like): Adjust accordingly.
	(maybe_handle_ref_bind): Simplify; the right conversion sequences
	are now built up in reference_binding.
	(initialize_reference): New function.
	* cp-tree.h (ICS_USER_FLAG): Document.
	(ICS_THIS_FLAG): Likewise.
	(ICS_BAD_FLAG): Likewise.
	(NEED_TEMPORARY_P): Likewise.
	(cp_lvalue_kind): New type.
	(real_lvalue_p): Return it.
	* error.c (dump_expr): Provide more accurate representation for
	AGGR_INIT_EXPRs.
	* init.c (expand_default_init): Do not try to perform implicit
	conversions for a brace-enclosed initializer.
	* search.c (lookup_conversions): Document.
	* tree.c (lvalue_p_1): Return a cp_lvalue_kind.  Calculate
	appropriately.
	(real_lvalue_p): Adjust accordingly.
	(lvalue_p): Likewise.
	(build_cplus_new): Don't allow the creation of an abstract class.
	* typeck.c (convert_for_initialization): Use initialize_reference.

From-SVN: r28221
parent ac1d97ce
1999-07-22 Mark Mitchell <mark@codesourcery.com>
* call.c (NEED_TEMPORARY_P): New macro.
(standard_conversion): Set it, for derived-to-base conversions.
(reference_related_p): New function.
(reference_compatible_p): Likewise.
(convert_class_to_reference): Likewise.
(direct_reference_binding): Likewise.
(reference_binding): Rework for standards-compliance.
(convert_like): Adjust accordingly.
(maybe_handle_ref_bind): Simplify; the right conversion sequences
are now built up in reference_binding.
(initialize_reference): New function.
* cp-tree.h (ICS_USER_FLAG): Document.
(ICS_THIS_FLAG): Likewise.
(ICS_BAD_FLAG): Likewise.
(NEED_TEMPORARY_P): Likewise.
(cp_lvalue_kind): New type.
(real_lvalue_p): Return it.
* error.c (dump_expr): Provide more accurate representation for
AGGR_INIT_EXPRs.
* init.c (expand_default_init): Do not try to perform implicit
conversions for a brace-enclosed initializer.
* search.c (lookup_conversions): Document.
* tree.c (lvalue_p_1): Return a cp_lvalue_kind. Calculate
appropriately.
(real_lvalue_p): Adjust accordingly.
(lvalue_p): Likewise.
(build_cplus_new): Don't allow the creation of an abstract class.
* typeck.c (convert_for_initialization): Use initialize_reference.
1999-07-21 Gavin Romig-Koch <gavin@cygnus.com>
* lex.c (real_yylex) : Correct the test for overflow when lexing
......
......@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA. */
TREE_INDIRECT_USING (in NAMESPACE_DECL).
IDENTIFIER_MARKED (used by search routines).
LOCAL_BINDING_P (in CPLUS_BINDING)
ICS_USER_FLAG (in _CONV)
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
......@@ -43,17 +44,21 @@ Boston, MA 02111-1307, USA. */
C_DECLARED_LABEL_FLAG.
INHERITED_VALUE_BINDING_P (in CPLUS_BINDING)
BASELINK_P (in TREE_LIST)
ICS_ELLIPSIS_FLAG (in _CONV)
2: IDENTIFIER_OPNAME_P.
BINFO_VBASE_MARKED.
BINFO_FIELDS_MARKED.
TYPE_VIRTUAL_P.
ICS_THIS_FLAG (in _CONV)
3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
BINFO_VTABLE_PATH_MARKED.
BINFO_PUSHDECLS_MARKED.
(TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
ICS_BAD_FLAG (in _CONV)
4: BINFO_NEW_VTABLE_MARKED.
TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
or FIELD_DECL).
NEED_TEMPORARY_P (in REF_BIND, BASE_CONV)
5: Not used.
6: Not used.
......@@ -2140,6 +2145,14 @@ extern int flag_new_for_scope;
enum tag_types { record_type, class_type, union_type, enum_type,
signature_type };
/* The various kinds of lvalues we distinguish. */
typedef enum cp_lvalue_kind {
clk_none = 0, /* Things that are not an lvalue. */
clk_ordinary = 1, /* An ordinary lvalue. */
clk_class = 2, /* An rvalue of class-type. */
clk_bitfield = 4, /* An lvalue for a bit-field. */
} cp_lvalue_kind;
/* Zero means prototype weakly, as in ANSI C (no args means nothing).
Each language context defines how this variable should be set. */
extern int strict_prototype;
......@@ -2753,6 +2766,7 @@ extern int enforce_access PROTO((tree, tree));
extern tree convert_default_arg PROTO((tree, tree, tree));
extern tree convert_arg_to_ellipsis PROTO((tree));
extern int is_properly_derived_from PROTO((tree, tree));
extern tree initialize_reference PROTO((tree, tree));
/* in class.c */
extern tree build_vbase_path PROTO((enum tree_code, tree, tree, tree, int));
......@@ -3363,7 +3377,7 @@ extern tree arbitrate_lookup PROTO((tree, tree, tree));
extern int pod_type_p PROTO((tree));
extern void unshare_base_binfos PROTO((tree));
extern int member_p PROTO((tree));
extern int real_lvalue_p PROTO((tree));
extern cp_lvalue_kind real_lvalue_p PROTO((tree));
extern tree build_min PVPROTO((enum tree_code, tree, ...));
extern tree build_min_nt PVPROTO((enum tree_code, ...));
extern tree min_tree_cons PROTO((tree, tree, tree));
......
......@@ -1409,7 +1409,22 @@ dump_expr (t, nop)
break;
case AGGR_INIT_EXPR:
{
tree fn = NULL_TREE;
if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
if (fn && TREE_CODE (fn) == FUNCTION_DECL)
{
if (DECL_CONSTRUCTOR_P (fn))
OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
else
dump_decl (fn, 0);
}
else
dump_expr (TREE_OPERAND (t, 0), 0);
}
OB_PUTC ('(');
if (TREE_OPERAND (t, 1))
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
......
......@@ -1177,6 +1177,10 @@ expand_default_init (binfo, true_exp, exp, init, flags)
to run a new constructor; and catching an exception, where we
have already built up the constructor call so we could wrap it
in an exception region. */;
else if (TREE_CODE (init) == CONSTRUCTOR)
/* A brace-enclosed initializer has whatever type is
required. There's no need to convert it. */
;
else
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
......
......@@ -3150,6 +3150,12 @@ add_conversions (binfo, data)
return NULL_TREE;
}
/* Return a TREE_LIST containing all the non-hidden user-defined
conversion functions for TYPE (and its base-classes). The
TREE_VALUE of each node is a FUNCTION_DECL or an OVERLOAD
containing the conversion functions. The TREE_PURPOSE is the BINFO
from which the conversion functions in this node were selected. */
tree
lookup_conversions (type)
tree type;
......
......@@ -36,27 +36,30 @@ static int list_hash PROTO((tree, tree, tree));
static tree list_hash_lookup PROTO((int, tree, tree, tree));
static void propagate_binfo_offsets PROTO((tree, tree));
static int avoid_overlap PROTO((tree, tree));
static int lvalue_p_1 PROTO((tree, int));
static cp_lvalue_kind lvalue_p_1 PROTO((tree, int));
static int equal_functions PROTO((tree, tree));
static tree no_linkage_helper PROTO((tree));
static tree build_srcloc PROTO((char *, int));
#define CEIL(x,y) (((x) + (y) - 1) / (y))
/* Returns non-zero if REF is an lvalue. If
TREAT_CLASS_RVALUES_AS_LVALUES is non-zero, rvalues of class type
are considered lvalues. */
/* If REF is an lvalue, returns the kind of lvalue that REF is.
Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is
non-zero, rvalues of class type are considered lvalues. */
static int
static cp_lvalue_kind
lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
tree ref;
int treat_class_rvalues_as_lvalues;
{
cp_lvalue_kind op1_lvalue_kind = clk_none;
cp_lvalue_kind op2_lvalue_kind = clk_none;
if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
return 1;
return clk_ordinary;
if (ref == current_class_ptr && flag_this_is_variable <= 0)
return 0;
return clk_none;
switch (TREE_CODE (ref))
{
......@@ -64,7 +67,6 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
what they refer to are valid lvals. */
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
case COMPONENT_REF:
case SAVE_EXPR:
case UNSAVE_EXPR:
case TRY_CATCH_EXPR:
......@@ -75,20 +77,37 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
return lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues);
case COMPONENT_REF:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues);
if (op1_lvalue_kind
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */
&& TREE_CODE (TREE_OPERAND (ref, 1)) == FIELD_DECL
&& DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
{
/* Clear the ordinary bit. If this object was a class
rvalue we want to preserve that information. */
op1_lvalue_kind &= ~clk_ordinary;
/* The lvalue is for a btifield. */
op1_lvalue_kind |= clk_bitfield;
}
return op1_lvalue_kind;
case STRING_CST:
return 1;
return clk_ordinary;
case VAR_DECL:
if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
&& DECL_LANG_SPECIFIC (ref)
&& DECL_IN_AGGR_P (ref))
return 0;
return clk_none;
case INDIRECT_REF:
case ARRAY_REF:
case PARM_DECL:
case RESULT_DECL:
if (TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
return 1;
return clk_ordinary;
break;
/* A currently unresolved scope ref. */
......@@ -96,72 +115,84 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
my_friendly_abort (103);
case OFFSET_REF:
if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
return 1;
return (lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues)
&& lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues));
return clk_ordinary;
/* Fall through. */
case MAX_EXPR:
case MIN_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues);
break;
case COND_EXPR:
return (lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues)
&& lvalue_p_1 (TREE_OPERAND (ref, 2),
treat_class_rvalues_as_lvalues));
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
treat_class_rvalues_as_lvalues);
break;
case MODIFY_EXPR:
return 1;
return clk_ordinary;
case COMPOUND_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues);
case MAX_EXPR:
case MIN_EXPR:
return (lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues)
&& lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues));
case TARGET_EXPR:
return treat_class_rvalues_as_lvalues;
return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
case CALL_EXPR:
return (treat_class_rvalues_as_lvalues
&& IS_AGGR_TYPE (TREE_TYPE (ref)));
return ((treat_class_rvalues_as_lvalues
&& IS_AGGR_TYPE (TREE_TYPE (ref)))
? clk_class : clk_none);
case FUNCTION_DECL:
/* All functions (except non-static-member functions) are
lvalues. */
return !DECL_NONSTATIC_MEMBER_FUNCTION_P (ref);
return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
? clk_none : clk_ordinary);
default:
break;
}
return 0;
/* If one operand is not an lvalue at all, then this expression is
not an lvalue. */
if (!op1_lvalue_kind || !op2_lvalue_kind)
return clk_none;
/* Otherwise, it's an lvalue, and it has all the odd properties
contributed by either operand. */
op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind;
/* It's not an ordinary lvalue if it involves either a bit-field or
a class rvalue. */
if ((op1_lvalue_kind & ~clk_ordinary) != clk_none)
op1_lvalue_kind &= ~clk_ordinary;
return op1_lvalue_kind;
}
/* Return nonzero if REF is an lvalue valid for this language.
Lvalues can be assigned, unless they have TREE_READONLY, or unless
they are FUNCTION_DECLs. Lvalues can have their address taken,
unless they have DECL_REGISTER. */
/* If REF is an lvalue, returns the kind of lvalue that REF is.
Otherwise, returns clk_none. Lvalues can be assigned, unless they
have TREE_READONLY, or unless they are FUNCTION_DECLs. Lvalues can
have their address taken, unless they have DECL_REGISTER. */
int
cp_lvalue_kind
real_lvalue_p (ref)
tree ref;
{
return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/0);
}
/* This differs from real_lvalue_p in that class rvalues are considered
lvalues. */
/* This differs from real_lvalue_p in that class rvalues are
considered lvalues. */
int
lvalue_p (ref)
tree ref;
{
return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/1);
return
(lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/1) != clk_none);
}
/* Return nonzero if REF is an lvalue valid for this language;
......@@ -193,6 +224,11 @@ build_cplus_new (type, init)
tree slot;
tree rval;
/* Make sure that we're not trying to create an instance of an
abstract class. */
if (CLASSTYPE_ABSTRACT_VIRTUALS (type))
abstract_virtuals_error (NULL_TREE, type);
if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != AGGR_INIT_EXPR)
return convert (type, init);
......
......@@ -7122,8 +7122,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
if (fndecl)
savew = warningcount, savee = errorcount;
rhs = convert_to_reference (type, rhs, CONV_IMPLICIT, flags,
exp ? exp : error_mark_node);
rhs = initialize_reference (type, rhs);
if (fndecl)
{
if (warningcount > savew)
......
// Build don't link:
// Based on a bug report by Stephen Vavasis <vavasis@CS.Cornell.EDU>
// excess errors test - XFAIL *-*-*
// declares template operator!=
#include <utility>
......
//Build don't link:
// the template operator!= interferes. It should be in a namespace.
// excess errors test - XFAIL *-*-*
#include <utility>
......
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