]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
call.c (conditional_conversion): Don't build BASE_CONVs for conversions between thing...
authorMark Mitchell <mark@codesourcery.com>
Wed, 28 Jul 1999 08:20:09 +0000 (08:20 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 28 Jul 1999 08:20:09 +0000 (08:20 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/init.c
gcc/testsuite/g++.old-deja/g++.other/cond2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/init14.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/ref3.C [new file with mode: 0644]

index 63adc40f37c8df855329b6e72cd3165245c71d8f..3c7ddbd7f950e8af5dad505a68c03defe7a39936 100644 (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.
index 1d9e83745d45fcb64fa525f46655311214f3c48f..4deaac2d5b2df7d2bdf3387506efa5b1e5a0d405 100644 (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);
index b3b9dcb0bc97f18af690083bf59b9ec992f58762..4163b1b894907e88f71e6f57ae49414eb0fc3410 100644 (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 ();
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 (file)
index 0000000..a83273f
--- /dev/null
@@ -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 (file)
index 0000000..8c866d7
--- /dev/null
@@ -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 (file)
index 0000000..6d615d4
--- /dev/null
@@ -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;
+}
+