This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] work around non-canonical ptr-to-member
- From: Richard Henderson <rth at redhat dot com>
- To: law at redhat dot com
- Cc: Jason Merrill <jason at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Tue, 20 Jan 2004 09:41:08 -0800
- Subject: [tree-ssa] work around non-canonical ptr-to-member
- References: <200401192216.i0JMGXQv028490@speedy.slc.redhat.com>
On Mon, Jan 19, 2004 at 03:16:33PM -0700, law@redhat.com wrote:
> FAIL: 27_io/basic_filebuf/underflow/wchar_t/9178.cc execution test
Ugliness. The C++ front end is creating two different ptr-to-member
structures, in this case at
#4 0x0806c339 in build_ptrmemfunc_type (type=0x401b1ef4)
at ../../../src-ssa/gcc/cp/decl.c:5916
#5 0x080ff4dc in build_unary_op (code=ADDR_EXPR, xarg=0x402e5e60,
noconvert=1075519220) at ../../../src-ssa/gcc/cp/typeck.c:4058
#6 0x081007c1 in unary_complex_lvalue (code=ADDR_EXPR, arg=0x402d6a8c)
at ../../../src-ssa/gcc/cp/typeck.c:4165
#7 0x080ff431 in build_unary_op (code=ADDR_EXPR, xarg=0x402d6a8c,
noconvert=1126607108) at ../../../src-ssa/gcc/cp/typeck.c:3975
#8 0x080fedde in build_x_unary_op (code=ADDR_EXPR, xarg=0x402d6a8c)
at ../../../src-ssa/gcc/cp/typeck.c:3558
#9 0x080e3fec in cp_parser_unary_expression (parser=0x4026cf00,
address_p=false) at ../../../src-ssa/gcc/cp/parser.c:4308
and at
#4 0x0806c339 in build_ptrmemfunc_type (type=0x401af488)
at ../../../src-ssa/gcc/cp/decl.c:5916
#5 0x0809a3c6 in tsubst (t=0x42cd128c, args=0x402e5f20, complain=tf_none,
in_decl=0x0) at ../../../src-ssa/gcc/cp/pt.c:6877
#6 0x08099d38 in tsubst (t=0x431895c4, args=0x402e5f20, complain=tf_none,
in_decl=0x0) at ../../../src-ssa/gcc/cp/pt.c:6557
#7 0x0809977e in tsubst_arg_types (arg_types=0x4353ea88, args=0x402e5f20,
complain=tf_none, in_decl=0x0) at ../../../src-ssa/gcc/cp/pt.c:6371
#8 0x08099930 in tsubst_function_type (t=0x430ffd64, args=0x402e5f20,
complain=tf_none, in_decl=0x0) at ../../../src-ssa/gcc/cp/pt.c:6433
#9 0x0809a522 in tsubst (t=0x430ffd64, args=0x402e5f20, complain=tf_none,
in_decl=0x0) at ../../../src-ssa/gcc/cp/pt.c:6943
#10 0x080a4311 in fn_type_unification (fn=0x4310001c, explicit_targs=0x0,
targs=0x402e5f20, args=0x402ea180, return_type=0x0, strict=116, len=-1)
at ../../../src-ssa/gcc/cp/pt.c:8776
and then builds an assignment between the two structures. I can work
around this for now, but it really seems to me like the C++ front end
should build a canonical ptr-to-member for any one type and remember it.
r~
* tree-sra.c (get_scalar_for_field): Validate field.
(create_scalar_copies): Iterate over rhs fields too.
Index: tree-sra.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-sra.c,v
retrieving revision 1.1.2.16
diff -c -p -d -r1.1.2.16 tree-sra.c
*** tree-sra.c 18 Jan 2004 23:09:08 -0000 1.1.2.16
--- tree-sra.c 20 Jan 2004 17:13:22 -0000
*************** get_scalar_for_field (tree var, tree fie
*** 210,215 ****
--- 210,227 ----
{
struct sra_elt key;
+ #ifdef ENABLE_CHECKING
+ /* Validate that FIELD actually exists in VAR's type. */
+ {
+ tree f;
+ for (f = TYPE_FIELDS (TREE_TYPE (var)); f ; f = TREE_CHAIN (f))
+ if (f == field)
+ goto found;
+ abort ();
+ found:;
+ }
+ #endif
+
key.kind = COMPONENT_REF;
key.base = var;
key.field = field;
*************** create_scalar_copies (tree lhs, tree rhs
*** 686,710 ****
}
else
{
! tree f;
! for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f))
{
tree lhs_var, rhs_var;
/* Only copy FIELD_DECLs. */
! if (TREE_CODE (f) != FIELD_DECL)
continue;
if (mode == FIELD_SCALAR)
! lhs_var = csc_build_component_ref (lhs, f);
else
! lhs_var = get_scalar_for_field (lhs, f);
if (mode == SCALAR_FIELD)
! rhs_var = csc_build_component_ref (rhs, f);
else
! rhs_var = get_scalar_for_field (rhs, f);
csc_assign (&tsi, lhs_var, rhs_var);
}
--- 698,729 ----
}
else
{
! tree lf, rf;
! /* ??? C++ generates copies between different pointer-to-member
! structures of different types. To combat this, we must track
! the field of both the left and right structures, so that we
! index the variables with fields of their own type. */
!
! for (lf = TYPE_FIELDS (type), rf = TYPE_FIELDS (TREE_TYPE (rhs));
! lf;
! lf = TREE_CHAIN (lf), rf = TREE_CHAIN (rf))
{
tree lhs_var, rhs_var;
/* Only copy FIELD_DECLs. */
! if (TREE_CODE (lf) != FIELD_DECL)
continue;
if (mode == FIELD_SCALAR)
! lhs_var = csc_build_component_ref (lhs, lf);
else
! lhs_var = get_scalar_for_field (lhs, lf);
if (mode == SCALAR_FIELD)
! rhs_var = csc_build_component_ref (rhs, rf);
else
! rhs_var = get_scalar_for_field (rhs, rf);
csc_assign (&tsi, lhs_var, rhs_var);
}