re PR c++/29066 (ptrmemfunc_vbit_in_delta is broken)
2006-12-01 Ryan Mansfield <rmansfield@qnx.com> PR c++/29066 * typeck.c (build_binary_op): Fix pointer to member function comparison for ptrmemfunc_vbit_in_delta targets. 2006-12-01 Ryan Mansfield <rmansfield@qnx.com> PR c++/29066 * g++.dg/expr/pr29066.c: New. From-SVN: r119403
This commit is contained in:
parent
5308e94309
commit
c3a88be88a
4 changed files with 124 additions and 16 deletions
|
@ -1,3 +1,9 @@
|
|||
2006-12-01 Ryan Mansfield <rmansfield@qnx.com>
|
||||
|
||||
PR c++/29066
|
||||
* typeck.c (build_binary_op): Fix pointer to member function
|
||||
comparison for ptrmemfunc_vbit_in_delta targets.
|
||||
|
||||
2006-12-01 Dirk Mueller <dmueller@suse.de>
|
||||
|
||||
PR c++/18313
|
||||
|
|
|
@ -3266,8 +3266,28 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
|
|||
}
|
||||
else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1))
|
||||
{
|
||||
op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
|
||||
op1 = cp_convert (TREE_TYPE (op0), integer_zero_node);
|
||||
if (TARGET_PTRMEMFUNC_VBIT_LOCATION
|
||||
== ptrmemfunc_vbit_in_delta)
|
||||
{
|
||||
tree pfn0 = pfn_from_ptrmemfunc (op0);
|
||||
tree delta0 = build_ptrmemfunc_access_expr (op0,
|
||||
delta_identifier);
|
||||
tree e1 = cp_build_binary_op (EQ_EXPR,
|
||||
pfn0,
|
||||
fold_convert (TREE_TYPE (pfn0),
|
||||
integer_zero_node));
|
||||
tree e2 = cp_build_binary_op (BIT_AND_EXPR,
|
||||
delta0,
|
||||
integer_one_node);
|
||||
e2 = cp_build_binary_op (EQ_EXPR, e2, integer_zero_node);
|
||||
op0 = cp_build_binary_op (TRUTH_ANDIF_EXPR, e1, e2);
|
||||
op1 = cp_convert (TREE_TYPE (op0), integer_one_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
|
||||
op1 = cp_convert (TREE_TYPE (op0), integer_zero_node);
|
||||
}
|
||||
result_type = TREE_TYPE (op0);
|
||||
}
|
||||
else if (TYPE_PTRMEMFUNC_P (type1) && null_ptr_cst_p (op0))
|
||||
|
@ -3290,26 +3310,61 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
|
|||
if (TREE_SIDE_EFFECTS (op1))
|
||||
op1 = save_expr (op1);
|
||||
|
||||
/* We generate:
|
||||
|
||||
(op0.pfn == op1.pfn
|
||||
&& (!op0.pfn || op0.delta == op1.delta))
|
||||
|
||||
The reason for the `!op0.pfn' bit is that a NULL
|
||||
pointer-to-member is any member with a zero PFN; the
|
||||
DELTA field is unspecified. */
|
||||
pfn0 = pfn_from_ptrmemfunc (op0);
|
||||
pfn1 = pfn_from_ptrmemfunc (op1);
|
||||
delta0 = build_ptrmemfunc_access_expr (op0,
|
||||
delta_identifier);
|
||||
delta1 = build_ptrmemfunc_access_expr (op1,
|
||||
delta_identifier);
|
||||
e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1);
|
||||
e2 = cp_build_binary_op (EQ_EXPR,
|
||||
pfn0,
|
||||
cp_convert (TREE_TYPE (pfn0),
|
||||
integer_zero_node));
|
||||
e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2);
|
||||
if (TARGET_PTRMEMFUNC_VBIT_LOCATION
|
||||
== ptrmemfunc_vbit_in_delta)
|
||||
{
|
||||
/* We generate:
|
||||
|
||||
(op0.pfn == op1.pfn
|
||||
&& ((op0.delta == op1.delta)
|
||||
|| (!op0.pfn && op0.delta & 1 == 0
|
||||
&& op1.delta & 1 == 0))
|
||||
|
||||
The reason for the `!op0.pfn' bit is that a NULL
|
||||
pointer-to-member is any member with a zero PFN and
|
||||
LSB of the DELTA field is 0. */
|
||||
|
||||
e1 = cp_build_binary_op (BIT_AND_EXPR,
|
||||
delta0,
|
||||
integer_one_node);
|
||||
e1 = cp_build_binary_op (EQ_EXPR, e1, integer_zero_node);
|
||||
e2 = cp_build_binary_op (BIT_AND_EXPR,
|
||||
delta1,
|
||||
integer_one_node);
|
||||
e2 = cp_build_binary_op (EQ_EXPR, e2, integer_zero_node);
|
||||
e1 = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1);
|
||||
e2 = cp_build_binary_op (EQ_EXPR,
|
||||
pfn0,
|
||||
fold_convert (TREE_TYPE (pfn0),
|
||||
integer_zero_node));
|
||||
e2 = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1);
|
||||
e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1);
|
||||
e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We generate:
|
||||
|
||||
(op0.pfn == op1.pfn
|
||||
&& (!op0.pfn || op0.delta == op1.delta))
|
||||
|
||||
The reason for the `!op0.pfn' bit is that a NULL
|
||||
pointer-to-member is any member with a zero PFN; the
|
||||
DELTA field is unspecified. */
|
||||
|
||||
e1 = cp_build_binary_op (EQ_EXPR, delta0, delta1);
|
||||
e2 = cp_build_binary_op (EQ_EXPR,
|
||||
pfn0,
|
||||
fold_convert (TREE_TYPE (pfn0),
|
||||
integer_zero_node));
|
||||
e1 = cp_build_binary_op (TRUTH_ORIF_EXPR, e1, e2);
|
||||
}
|
||||
e2 = build2 (EQ_EXPR, boolean_type_node, pfn0, pfn1);
|
||||
e = cp_build_binary_op (TRUTH_ANDIF_EXPR, e2, e1);
|
||||
if (code == EQ_EXPR)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2006-12-01 Ryan Mansfield <rmansfield@qnx.com>
|
||||
|
||||
PR c++/29066
|
||||
* g++.dg/expr/pr29066.c: New.
|
||||
|
||||
2006-12-01 H.J. Lu <hongjiu.lu@intel.com>
|
||||
Zdenek Dvorak <dvorakz@suse.cz>
|
||||
|
||||
|
|
42
gcc/testsuite/g++.dg/expr/pr29066.C
Normal file
42
gcc/testsuite/g++.dg/expr/pr29066.C
Normal file
|
@ -0,0 +1,42 @@
|
|||
// PR c++/29066
|
||||
// Test pointer to member function comparison
|
||||
// { dg-do run }
|
||||
|
||||
extern "C" void abort (void);
|
||||
|
||||
struct X
|
||||
{
|
||||
virtual void a(void)=0;
|
||||
};
|
||||
|
||||
struct Z : public X
|
||||
{
|
||||
void a(void) {};
|
||||
};
|
||||
|
||||
|
||||
void f(X *obj)
|
||||
{
|
||||
void (X::*xp)(void) = 0;
|
||||
void (X::*xp2)(void) = 0;
|
||||
|
||||
xp = &X::a;
|
||||
|
||||
if (xp == xp2)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
if (xp == 0)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
Z myobj;
|
||||
|
||||
f(&myobj);
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue