aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-07-28 08:20:09 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-07-28 08:20:09 +0000
commit4f0aa41654923b227eae756fec96308c0e53ef47 (patch)
treeec3157e90ada3b76e2cacb25e81cf9dda4a08fd8
parentf66bbb410c40ea0a010329ecacb56b8214853d26 (diff)
downloadgcc-4f0aa41654923b227eae756fec96308c0e53ef47.zip
gcc-4f0aa41654923b227eae756fec96308c0e53ef47.tar.gz
gcc-4f0aa41654923b227eae756fec96308c0e53ef47.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/call.c34
-rw-r--r--gcc/cp/init.c26
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/cond2.C11
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/init14.C22
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/ref3.C30
6 files changed, 116 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 63adc40..3c7ddbd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 1d9e837..4deaac2 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index b3b9dcb..4163b1b 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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 ();
diff --git a/gcc/testsuite/g++.old-deja/g++.other/cond2.C b/gcc/testsuite/g++.old-deja/g++.other/cond2.C
new file mode 100644
index 0000000..a83273f
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/cond2.C
@@ -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; }
+};
diff --git a/gcc/testsuite/g++.old-deja/g++.other/init14.C b/gcc/testsuite/g++.old-deja/g++.other/init14.C
new file mode 100644
index 0000000..8c866d7
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/init14.C
@@ -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);
+}
+
+
diff --git a/gcc/testsuite/g++.old-deja/g++.other/ref3.C b/gcc/testsuite/g++.old-deja/g++.other/ref3.C
new file mode 100644
index 0000000..6d615d4
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/ref3.C
@@ -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;
+}
+