This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH for reference/qualified member confusion
- To: egcs-patches at cygnus dot com
- Subject: PATCH for reference/qualified member confusion
- From: Mark Mitchell <mark at markmitchell dot com>
- Date: Thu, 3 Sep 1998 19:40:34 -0700
- Cc: Jason Merrill <jason at cygnus dot com>
- Reply-to: mark at markmitchell dot com
We used to crash on the following code. Now we don't.
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com
1998-09-03 Mark Mitchell <mark@markmitchell.com>
* init.c (resolve_offset_ref): Call convert_from_reference to
handle members of reference type. Improve error recovery.
Index: testsuite/g++.old-deja/g++.other/crash5.C
===================================================================
RCS file: crash5.C
diff -N crash5.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- crash5.C Thu Sep 3 19:21:49 1998
***************
*** 0 ****
--- 1,21 ----
+ // Build don't link:
+
+ class TecMesh {};
+
+ extern TecMesh& m;
+
+ struct X {
+ X(TecMesh&);
+ };
+
+ struct D {
+ D();
+ TecMesh& Mesh;
+ };
+
+
+ D::D ()
+ : Mesh(m)
+ {
+ X x(D::Mesh);
+ }
Index: cp/init.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/init.c,v
retrieving revision 1.62
diff -c -p -r1.62 init.c
*** init.c 1998/08/27 17:33:33 1.62
--- init.c 1998/09/04 02:22:58
*************** resolve_offset_ref (exp)
*** 1798,1804 ****
|| (TREE_CODE (base) == NOP_EXPR
&& TREE_OPERAND (base, 0) == error_mark_node)))
{
! tree basetype_path, access;
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
basetype = TYPE_OFFSET_BASETYPE (type);
--- 1798,1806 ----
|| (TREE_CODE (base) == NOP_EXPR
&& TREE_OPERAND (base, 0) == error_mark_node)))
{
! tree basetype_path;
! tree access;
! tree expr;
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
basetype = TYPE_OFFSET_BASETYPE (type);
*************** resolve_offset_ref (exp)
*** 1816,1837 ****
convert_pointer_to will bash it. */
access = compute_access (basetype_path, member);
addr = convert_pointer_to (basetype, base);
! if (access == access_public_node)
! return build (COMPONENT_REF, TREE_TYPE (member),
! build_indirect_ref (addr, NULL_PTR), member);
! if (access == access_protected_node)
! {
! cp_error_at ("member `%D' is protected", member);
! error ("in this context");
! return error_mark_node;
! }
! if (access == access_private_node)
{
! cp_error_at ("member `%D' is private", member);
! error ("in this context");
! return error_mark_node;
! }
! my_friendly_abort (55);
}
/* Ensure that we have an object. */
--- 1818,1840 ----
convert_pointer_to will bash it. */
access = compute_access (basetype_path, member);
addr = convert_pointer_to (basetype, base);
!
! /* Issue errors if there was an access violation. */
! if (access != access_public_node)
{
! cp_error_at ("member `%D' is %s",
! access == access_private_node
! ? "private" : "protected",
! member);
! cp_error ("in this context");
! }
!
! /* Even in the case of illegal access, we form the
! COMPONENT_REF; that will allow better error recovery than
! just feeding back error_mark_node. */
! expr = build (COMPONENT_REF, TREE_TYPE (member),
! build_indirect_ref (addr, NULL_PTR), member);
! return convert_from_reference (expr);
}
/* Ensure that we have an object. */
*************** resolve_offset_ref (exp)
*** 1839,1851 ****
&& TREE_OPERAND (base, 0) == error_mark_node)
addr = error_mark_node;
else
! {
! /* If this is a reference to a member function, then return the
! address of the member function (which may involve going
! through the object's vtable), otherwise, return an expression
! for the dereferenced pointer-to-member construct. */
! addr = build_unary_op (ADDR_EXPR, base, 0);
! }
if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)
{
--- 1842,1852 ----
&& TREE_OPERAND (base, 0) == error_mark_node)
addr = error_mark_node;
else
! /* If this is a reference to a member function, then return the
! address of the member function (which may involve going
! through the object's vtable), otherwise, return an expression
! for the dereferenced pointer-to-member construct. */
! addr = build_unary_op (ADDR_EXPR, base, 0);
if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)
{
Index: cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.131
diff -c -p -r1.131 cp-tree.h
*** cp-tree.h 1998/09/03 16:09:56 1.131
--- cp-tree.h 1998/09/04 02:22:49
*************** extern tree finish_this_expr
*** 2932,2938 ****
extern tree finish_object_call_expr PROTO((tree, tree, tree));
extern tree finish_qualified_object_call_expr PROTO((tree, tree, tree));
extern tree finish_pseudo_destructor_call_expr PROTO((tree, tree, tree));
! extern tree finish_globally_qualified_member_call_expr PROTO ((tree, tree));
extern tree finish_label_address_expr PROTO((tree));
extern tree finish_unary_op_expr PROTO((enum tree_code, tree));
extern tree finish_id_expr PROTO((tree));
--- 2932,2938 ----
extern tree finish_object_call_expr PROTO((tree, tree, tree));
extern tree finish_qualified_object_call_expr PROTO((tree, tree, tree));
extern tree finish_pseudo_destructor_call_expr PROTO((tree, tree, tree));
! extern tree finish_qualified_call_expr PROTO ((tree, tree));
extern tree finish_label_address_expr PROTO((tree));
extern tree finish_unary_op_expr PROTO((enum tree_code, tree));
extern tree finish_id_expr PROTO((tree));
Index: cp/method.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/method.c,v
retrieving revision 1.72
diff -c -p -r1.72 method.c
*** method.c 1998/08/27 02:04:26 1.72
--- method.c 1998/09/04 02:23:04
*************** hack_identifier (value, name)
*** 1954,1960 ****
return value;
}
! if (TREE_CODE (type) == REFERENCE_TYPE && ! processing_template_decl)
value = convert_from_reference (value);
return value;
}
--- 1954,1960 ----
return value;
}
! if (! processing_template_decl)
value = convert_from_reference (value);
return value;
}
Index: cp/parse.y
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/parse.y,v
retrieving revision 1.86
diff -c -p -r1.86 parse.y
*** parse.y 1998/08/28 15:43:56 1.86
--- parse.y 1998/09/04 02:23:38
*************** primary:
*** 1491,1499 ****
| overqualified_id %prec HYPERUNARY
{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
| overqualified_id '(' nonnull_exprlist ')'
! { $$ = finish_globally_qualified_member_call_expr ($1, $3); }
| overqualified_id LEFT_RIGHT
! { $$ = finish_globally_qualified_member_call_expr ($1, NULL_TREE); }
| object object_template_id %prec UNARY
{
$$ = build_x_component_ref ($$, $2, NULL_TREE, 1);
--- 1491,1499 ----
| overqualified_id %prec HYPERUNARY
{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
| overqualified_id '(' nonnull_exprlist ')'
! { $$ = finish_qualified_call_expr ($1, $3); }
| overqualified_id LEFT_RIGHT
! { $$ = finish_qualified_call_expr ($1, NULL_TREE); }
| object object_template_id %prec UNARY
{
$$ = build_x_component_ref ($$, $2, NULL_TREE, 1);
Index: cp/semantics.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/semantics.c,v
retrieving revision 1.26
diff -c -p -r1.26 semantics.c
*** semantics.c 1998/09/01 11:51:41 1.26
--- semantics.c 1998/09/04 02:23:41
*************** finish_pseudo_destructor_call_expr (obje
*** 995,1001 ****
ARGS. Returns an expression for the call. */
tree
! finish_globally_qualified_member_call_expr (fn, args)
tree fn;
tree args;
{
--- 995,1001 ----
ARGS. Returns an expression for the call. */
tree
! finish_qualified_call_expr (fn, args)
tree fn;
tree args;
{