re PR c++/8748 (ICE in cp_expr_size at cp/cp-lang.c: 307)
authorJason Merrill <jason@redhat.com>
Mon, 13 Jan 2003 09:14:47 +0000 (04:14 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 13 Jan 2003 09:14:47 +0000 (04:14 -0500)
        PR c++/8748
        * class.c (build_base_path): Take the address before calling save_expr.

        * call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if
        all the ambiguous conversions are bad.

        * class.c (maybe_warn_about_overly_private_class): Don't stop
        searching when we find a nonprivate method.

        * typeck.c (build_class_member_access_expr): Use unary_complex_lvalue.

From-SVN: r61246

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/typeck.c

index 4111b95f11424624c48029ce91e89ed0d1c29a71..b209ca4c0ea9e85ffcf6f906b775c860e39edf9f 100644 (file)
@@ -1,3 +1,16 @@
+2003-01-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/8748
+       * class.c (build_base_path): Take the address before calling save_expr.
+
+       * call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if
+       all the ambiguous conversions are bad.
+
+       * class.c (maybe_warn_about_overly_private_class): Don't stop
+       searching when we find a nonprivate method.
+
+       * typeck.c (build_class_member_access_expr): Use unary_complex_lvalue.
+
 2003-01-12  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (get_arglist_len_in_bytes): Remove.
index cd93f7bbe4bbc8938331670496bab1db73fef8a9..5340356d4d552770b4500747c04323041e59f035 100644 (file)
@@ -2536,8 +2536,11 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
       cand = candidates;       /* any one will do */
       cand->second_conv = build1 (AMBIG_CONV, totype, expr);
       ICS_USER_FLAG (cand->second_conv) = 1;
-      /* Don't set ICS_BAD_FLAG; an ambiguous conversion is no worse than
-        another user-defined conversion.  */
+      if (!any_strictly_viable (candidates))
+       ICS_BAD_FLAG (cand->second_conv) = 1;
+      /* If there are viable candidates, don't set ICS_BAD_FLAG; an
+        ambiguous conversion is no worse than another user-defined
+        conversion.  */
 
       return cand;
     }
index bace3f4d7c942d09465e4441a7ad31330486801c..6d492f962f881532d6629623b718569d169fa6e7 100644 (file)
@@ -291,13 +291,15 @@ build_base_path (code, expr, binfo, nonnull)
       return error_mark_node;
     }
 
+  if (!want_pointer)
+    /* This must happen before the call to save_expr.  */
+    expr = build_unary_op (ADDR_EXPR, expr, 0);
+
   fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
   if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr))
     expr = save_expr (expr);
 
-  if (!want_pointer)
-    expr = build_unary_op (ADDR_EXPR, expr, 0);
-  else if (!nonnull)
+  if (want_pointer && !nonnull)
     null_test = build (EQ_EXPR, boolean_type_node, expr, integer_zero_node);
   
   offset = BINFO_OFFSET (binfo);
@@ -1833,7 +1835,7 @@ maybe_warn_about_overly_private_class (t)
              return;
                
            has_nonprivate_method = 1;
-           break;
+           /* Keep searching for a static member function.  */
          }
        else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
          has_member_fn = 1;
@@ -1980,7 +1982,7 @@ resort_field_decl_cmp (x_p, y_p)
 void 
 resort_sorted_fields (obj, orig_obj, new_value, cookie)
      void *obj;
-     void *orig_obj;
+     void *orig_obj ATTRIBUTE_UNUSED;
      gt_pointer_operator new_value;
      void *cookie;
 {
@@ -2042,7 +2044,7 @@ resort_method_name_cmp (m1_p, m2_p)
 void 
 resort_type_method_vec (obj, orig_obj, new_value, cookie)
      void *obj;
-     void *orig_obj;
+     void *orig_obj ATTRIBUTE_UNUSED;
      gt_pointer_operator new_value;
      void *cookie;
 {
index e7921c55e1009e5c3c384bdecf6972c830887adc..2c896d4ef20ee8846f194b84b66d1964ac042163 100644 (file)
@@ -1904,33 +1904,14 @@ build_class_member_access_expr (tree object, tree member,
       return error_mark_node;
     }
 
-  /* Transform `(a, b).x' into `(*(a, &b)).x' and `(a ? b : c).x' into
-     `(*(a ?  &b : &c)).x'.  Unfortunately, expand_expr cannot handle a
-     COMPONENT_REF where the first operand is a conditional or comma
-     expression with class type.  */
-  if (TREE_CODE (object) == COMPOUND_EXPR)
-    {
-      object = build (COMPOUND_EXPR, 
-                     build_pointer_type (object_type),
-                     TREE_OPERAND (object, 0),
-                     build_unary_op (ADDR_EXPR, 
-                                     TREE_OPERAND (object, 1),
-                                     /*noconvert=*/1));
-      object = build_indirect_ref (object, NULL);
-    }
-  else if (TREE_CODE (object) == COND_EXPR)
-    {
-      object = build (COND_EXPR, 
-                     build_pointer_type (object_type),
-                     TREE_OPERAND (object, 0),
-                     build_unary_op (ADDR_EXPR, 
-                                     TREE_OPERAND (object, 1),
-                                     /*noconvert=*/1),
-                     build_unary_op (ADDR_EXPR, 
-                                     TREE_OPERAND (object, 2),
-                                     /*noconvert=*/1));
-      object = build_indirect_ref (object, NULL);
-    }
+  /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
+     `(*(a ?  &b : &c)).x', and so on.  A COND_EXPR is only an lvalue
+     in the frontend; only _DECLs and _REFs are lvalues in the backend.  */
+  {
+    tree temp = unary_complex_lvalue (ADDR_EXPR, object);
+    if (temp)
+      object = build_indirect_ref (temp, NULL);
+  }
 
   /* In [expr.ref], there is an explicit list of the valid choices for
      MEMBER.  We check for each of those cases here.  */