aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2003-01-13 04:14:47 -0500
committerJason Merrill <jason@gcc.gnu.org>2003-01-13 04:14:47 -0500
commitf576dfc407d1c68d514c2be8c8505c33b00ccee6 (patch)
tree1ac795ce86106645cb0dc296028567adf1a9970e /gcc/cp
parente308bc5ad33c3ee703fbc4b1860ecd1caa5fb353 (diff)
downloadgcc-f576dfc407d1c68d514c2be8c8505c33b00ccee6.zip
gcc-f576dfc407d1c68d514c2be8c8505c33b00ccee6.tar.gz
gcc-f576dfc407d1c68d514c2be8c8505c33b00ccee6.tar.bz2
re PR c++/8748 (ICE in cp_expr_size at cp/cp-lang.c: 307)
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/call.c7
-rw-r--r--gcc/cp/class.c14
-rw-r--r--gcc/cp/typeck.c35
4 files changed, 34 insertions, 35 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4111b95..b209ca4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index cd93f7b..5340356 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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;
}
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index bace3f4..6d492f9 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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;
{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index e7921c5..2c896d4 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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. */