mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-04 06:39:30 +08:00
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:
parent
f66bbb410c
commit
4f0aa41654
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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 ();
|
||||
|
11
gcc/testsuite/g++.old-deja/g++.other/cond2.C
Normal file
11
gcc/testsuite/g++.old-deja/g++.other/cond2.C
Normal 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; }
|
||||
};
|
22
gcc/testsuite/g++.old-deja/g++.other/init14.C
Normal file
22
gcc/testsuite/g++.old-deja/g++.other/init14.C
Normal 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);
|
||||
}
|
||||
|
||||
|
30
gcc/testsuite/g++.old-deja/g++.other/ref3.C
Normal file
30
gcc/testsuite/g++.old-deja/g++.other/ref3.C
Normal 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user