Commit 61402b80 by Nathan Sidwell Committed by Nathan Sidwell

typeck.c (get_delta_difference): If via a virtual base, return zero.

cp:
	* typeck.c (get_delta_difference): If via a virtual base,
	return zero.
	* cvt.c (cp_convert_to_pointer): If via a virtual base, do no
	adjustment.
testsuite:
	* g++.old-deja/g++.mike/pmf5.C: Remove test.

From-SVN: r38039
parent 4839149c
2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
* typeck.c (get_delta_difference): If via a virtual base,
return zero.
* cvt.c (cp_convert_to_pointer): If via a virtual base, do no
adjustment.
2000-12-04 Richard Henderson <rth@redhat.com> 2000-12-04 Richard Henderson <rth@redhat.com>
* error.c (dump_tree): Use output_add_string not OB_PUTS. * error.c (dump_tree): Use output_add_string not OB_PUTS.
......
...@@ -209,10 +209,9 @@ cp_convert_to_pointer (type, expr, force) ...@@ -209,10 +209,9 @@ cp_convert_to_pointer (type, expr, force)
if (virt_binfo) if (virt_binfo)
{ {
if (force) if (force)
cp_warning ("pointer to member cast via virtual base `%T' of `%T' will only work for objects of dynamic type `%T'", cp_warning ("pointer to member cast via virtual base `%T' of `%T'",
BINFO_TYPE (virt_binfo), BINFO_TYPE (virt_binfo),
BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)), BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
code == MINUS_EXPR ? b2 : b1);
else else
{ {
cp_error ("pointer to member cast via virtual base `%T' of `%T'", cp_error ("pointer to member cast via virtual base `%T' of `%T'",
...@@ -220,13 +219,16 @@ cp_convert_to_pointer (type, expr, force) ...@@ -220,13 +219,16 @@ cp_convert_to_pointer (type, expr, force)
BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo))); BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
return error_mark_node; return error_mark_node;
} }
/* This is a reinterpret cast, whose result is unspecified.
We choose to do nothing. */
return build1 (NOP_EXPR, type, expr);
} }
if (TREE_CODE (expr) == PTRMEM_CST) if (TREE_CODE (expr) == PTRMEM_CST)
expr = cplus_expand_constant (expr); expr = cplus_expand_constant (expr);
if (binfo && ! TREE_VIA_VIRTUAL (binfo)) if (binfo)
expr = size_binop (code, convert (sizetype,expr), expr = size_binop (code, convert (sizetype, expr),
BINFO_OFFSET (binfo)); BINFO_OFFSET (binfo));
} }
else if (TYPE_PTRMEMFUNC_P (type)) else if (TYPE_PTRMEMFUNC_P (type))
......
...@@ -5936,31 +5936,39 @@ get_delta_difference (from, to, force) ...@@ -5936,31 +5936,39 @@ get_delta_difference (from, to, force)
virt_binfo = binfo_from_vbase (binfo); virt_binfo = binfo_from_vbase (binfo);
if (virt_binfo) if (virt_binfo)
cp_warning ("pointer to member cast via virtual base `%T' of `%T' will only work for objects of dynamic type `%T'", {
BINFO_TYPE (virt_binfo), /* This is a reinterpret cast, we choose to do nothing. */
BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)), from); cp_warning ("pointer to member cast via virtual base `%T' of `%T'",
BINFO_TYPE (virt_binfo),
BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
return delta;
}
delta = BINFO_OFFSET (binfo); delta = BINFO_OFFSET (binfo);
delta = cp_convert (ptrdiff_type_node, delta); delta = cp_convert (ptrdiff_type_node, delta);
delta = cp_build_binary_op (MINUS_EXPR,
return cp_build_binary_op (MINUS_EXPR,
integer_zero_node, integer_zero_node,
delta); delta);
return delta;
} }
virt_binfo = binfo_from_vbase (binfo); virt_binfo = binfo_from_vbase (binfo);
if (virt_binfo) if (virt_binfo)
{ {
/* This is a reinterpret cast, we choose to do nothing. */
if (force) if (force)
cp_warning ("pointer to member cast via virtual base `%T' of `%T' will only work for objects of dynamic type `%T'", cp_warning ("pointer to member cast via virtual base `%T' of `%T'",
BINFO_TYPE (virt_binfo), BINFO_TYPE (virt_binfo),
BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)), to); BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
else else
cp_error ("pointer to member conversion via virtual base `%T' of `%T'", cp_error ("pointer to member conversion via virtual base `%T' of `%T'",
BINFO_TYPE (virt_binfo), BINFO_TYPE (virt_binfo),
BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo))); BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
return delta;
} }
delta = BINFO_OFFSET (binfo);
return BINFO_OFFSET (binfo); return cp_convert (ptrdiff_type_node, delta);
} }
/* Return a constructor for the pointer-to-member-function TYPE using /* Return a constructor for the pointer-to-member-function TYPE using
......
2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.mike/pmf5.C: Remove test.
2000-12-05 Richard Henderson <rth@redhat.com> 2000-12-05 Richard Henderson <rth@redhat.com>
* gcc.c-torture/compile/20001205-1.c: New. * gcc.c-torture/compile/20001205-1.c: New.
......
// Special g++ Options: -w
class A {
int j;
};
class Space {
int j;
};
typedef int (A::*pma)();
class B : public Space, virtual public A {
public:
int i;
int foo () {
return i!=42;
}
B() {
i = 42;
}
};
int call_base (A* ap, pma pmf) {
return (ap->*pmf)();
}
int main() {
B b;
return call_base ((A*)&b, (pma)&B::foo);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment