call.c (conditional_conversion): Don't build BASE_CONVs for conversions between things that have the same type.

* call.c (conditional_conversion): Don't build BASE_CONVs for
	conversions between things that have the same type.
	(build_conditional_expr): Tweak.
	(convert_like): Some BASE_CONVs really do require the generation
	of code.

	* init.c (perform_member_init): Don't go through build_modify_expr
	for simple initializations.

From-SVN: r28310
This commit is contained in:
Mark Mitchell 1999-07-28 08:20:09 +00:00 committed by Mark Mitchell
parent f66bbb410c
commit 4f0aa41654
6 changed files with 116 additions and 18 deletions

View File

@ -1,3 +1,14 @@
1999-07-28 Mark Mitchell <mark@codesourcery.com>
* call.c (conditional_conversion): Don't build BASE_CONVs for
conversions between things that have the same type.
(build_conditional_expr): Tweak.
(convert_like): Some BASE_CONVs really do require the generation
of code.
* init.c (perform_member_init): Don't go through build_modify_expr
for simple initializations.
1999-07-27 Jason Merrill <jason@yorick.cygnus.com>
* cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro.

View File

@ -2716,7 +2716,9 @@ conditional_conversion (e1, e2)
if (at_least_as_qualified_p (t2, t1))
{
conv = build1 (IDENTITY_CONV, t1, e1);
conv = build_conv (BASE_CONV, t2, conv);
if (!same_type_p (TYPE_MAIN_VARIANT (t1),
TYPE_MAIN_VARIANT (t2)))
conv = build_conv (BASE_CONV, t2, conv);
return conv;
}
else
@ -2865,11 +2867,22 @@ build_conditional_expr (arg1, arg2, arg3)
else if (conv2 && !ICS_BAD_FLAG (conv2))
{
arg2 = convert_like (conv2, arg2);
/* That may not quite have done the trick. If the two types
are cv-qualified variants of one another, we will have
just used an IDENTITY_CONV. (There's no conversion from
an lvalue of one class type to an lvalue of another type,
even a cv-qualified variant, and we don't want to lose
lvalue-ness here.) So, we manually add a NOP_EXPR here
if necessary. */
if (!same_type_p (TREE_TYPE (arg2), arg3_type))
arg2 = build1 (NOP_EXPR, arg3_type, arg2);
arg2_type = TREE_TYPE (arg2);
}
else if (conv3 && !ICS_BAD_FLAG (conv3))
{
arg3 = convert_like (conv3, arg3);
if (!same_type_p (TREE_TYPE (arg3), arg2_type))
arg2 = build1 (NOP_EXPR, arg2_type, arg3);
arg3_type = TREE_TYPE (arg3);
}
}
@ -3647,12 +3660,19 @@ convert_like (convs, expr)
return expr;
/* else fall through */
case BASE_CONV:
if (TREE_CODE (convs) == BASE_CONV
&& !NEED_TEMPORARY_P (convs))
/* We are going to bind a reference directly to a base-class
subobject of EXPR. We don't have to generate any code
here. */
return expr;
if (TREE_CODE (convs) == BASE_CONV && !NEED_TEMPORARY_P (convs))
{
/* We are going to bind a reference directly to a base-class
subobject of EXPR. */
tree base_ptr = build_pointer_type (TREE_TYPE (convs));
/* Build an expression for `*((base*) &expr)'. */
expr = build_unary_op (ADDR_EXPR, expr, 0);
expr = perform_implicit_conversion (base_ptr, expr);
expr = build_indirect_ref (expr, "implicit conversion");
return expr;
}
{
tree cvt_expr = build_user_type_conversion
(TREE_TYPE (convs), expr, LOOKUP_NORMAL);

View File

@ -194,13 +194,21 @@ perform_member_init (member, name, init, explicit)
{
/* default-initialization. */
if (AGGREGATE_TYPE_P (type))
init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
else if (TREE_CODE (type) == REFERENCE_TYPE)
{
cp_error ("default-initialization of `%#D', which has reference type",
member);
init = error_mark_node;
/* This is a default initialization of an aggregate,
but not one of non-POD class type. We cleverly
notice that the initialization rules in such a
case are the same as for initialization with an
empty brace-initialization list. We don't want
to call build_modify_expr as that will go looking
for constructors and such. */
tree e = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
TREE_SIDE_EFFECTS (e) = 1;
expand_expr_stmt (build (INIT_EXPR, type, decl, e));
}
else if (TREE_CODE (type) == REFERENCE_TYPE)
cp_error ("default-initialization of `%#D', which has reference type",
member);
else
init = integer_zero_node;
}
@ -221,12 +229,8 @@ perform_member_init (member, name, init, explicit)
init = TREE_VALUE (init);
}
/* We only build this with a null init if we got it from the
current_member_init_list. */
if (init || explicit)
{
expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
}
if (init)
expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
}
expand_end_target_temps ();

View File

@ -0,0 +1,11 @@
// Build don't link:
// Origin: Loring Holden <lsh@cs.brown.edu>
class Wpt {};
class RAYhit {
protected:
Wpt _nearpt;
public:
Wpt surf () const { return true ? Wpt(): _nearpt; }
};

View File

@ -0,0 +1,22 @@
// Build don't link:
// Origin: bkoz@nabi.net
typedef struct
{
int count;
} mbstate_t;
struct fpos
{
mbstate_t _M_st;
fpos(int __pos)
: _M_st() {
}
};
int main ()
{
fpos f (2);
}

View File

@ -0,0 +1,30 @@
// Origin: Mark Mitchell <mark@codesourcery.com>
struct B1
{
int i;
};
struct B2
{
int j;
};
struct D: public B1, B2
{
};
bool f (B2& b)
{
return b.j == 7;
}
int main ()
{
D d;
d.i = 2;
d.j = 7;
if (!f (d))
return 1;
}