typeck.c (get_member_function_from_ptrfunc): Reorganize.

* typeck.c (get_member_function_from_ptrfunc): Reorganize.
        Use subtraction rather than a bitmask to get the index.
        * cvt.c (cp_convert_to_pointer): Bail on an error_mark_node.

        * pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P.

From-SVN: r53335
This commit is contained in:
Jason Merrill 2002-05-09 13:27:37 -04:00 committed by Jason Merrill
parent ff43145992
commit c87978aa20
4 changed files with 67 additions and 68 deletions

View file

@ -1,3 +1,11 @@
2002-05-09 Jason Merrill <jason@redhat.com>
* typeck.c (get_member_function_from_ptrfunc): Reorganize.
Use subtraction rather than a bitmask to get the index.
* cvt.c (cp_convert_to_pointer): Bail on an error_mark_node.
* pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P.
2002-05-07 Neil Booth <neil@daikokuya.demon.co.uk>
* Make-lang.in (decl2.o): Update.

View file

@ -130,6 +130,9 @@ cp_convert_to_pointer (type, expr, force)
intype = TREE_TYPE (expr);
}
if (expr == error_mark_node)
return error_mark_node;
form = TREE_CODE (intype);
if (POINTER_TYPE_P (intype))

View file

@ -7541,12 +7541,13 @@ tsubst_expr (t, args, complain, in_decl)
case ASM_STMT:
prep_stmt (t);
finish_asm_stmt (ASM_CV_QUAL (t),
tsubst_expr (ASM_STRING (t), args, complain, in_decl),
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_CLOBBERS (t), args, complain,
in_decl));
tmp = finish_asm_stmt
(ASM_CV_QUAL (t),
tsubst_expr (ASM_STRING (t), args, complain, in_decl),
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_CLOBBERS (t), args, complain, in_decl));
ASM_INPUT_P (tmp) = ASM_INPUT_P (t);
break;
case TRY_BLOCK:

View file

@ -2821,7 +2821,14 @@ build_x_function_call (function, params, decl)
}
/* Resolve a pointer to member function. INSTANCE is the object
instance to use, if the member points to a virtual member. */
instance to use, if the member points to a virtual member.
This used to avoid checking for virtual functions if basetype
has no virtual functions, according to an earlier ANSI draft.
With the final ISO C++ rules, such an optimization is
incorrect: A pointer to a derived member can be static_cast
to pointer-to-base-member, as long as the dynamic object
later has the right member. */
tree
get_member_function_from_ptrfunc (instance_ptrptr, function)
@ -2833,21 +2840,26 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
{
tree fntype, idx, e1, delta, delta2, e2, e3, vtbl;
tree instance, basetype;
tree mask;
tree idx, delta, e1, e2, e3, vtbl, basetype;
tree fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
tree instance_ptr = *instance_ptrptr;
if (instance_ptr == error_mark_node
&& TREE_CODE (function) == PTRMEM_CST)
if (instance_ptr == error_mark_node)
{
/* Extracting the function address from a pmf is only
allowed with -Wno-pmf-conversions. It only works for
pmf constants. */
e1 = build_addr_func (PTRMEM_CST_MEMBER (function));
e1 = convert (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function)), e1);
return e1;
if (TREE_CODE (function) == PTRMEM_CST)
{
/* Extracting the function address from a pmf is only
allowed with -Wno-pmf-conversions. It only works for
pmf constants. */
e1 = build_addr_func (PTRMEM_CST_MEMBER (function));
e1 = convert (fntype, e1);
return e1;
}
else
{
error ("object missing in use of `%E'", function);
return error_mark_node;
}
}
if (TREE_SIDE_EFFECTS (instance_ptr))
@ -2856,64 +2868,47 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
if (TREE_SIDE_EFFECTS (function))
function = save_expr (function);
fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
/* Convert down to the right base, before using the instance. */
instance = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)), basetype,
ba_check, NULL);
instance = build_base_path (PLUS_EXPR, instance_ptr, instance, 1);
if (instance == error_mark_node && instance_ptr != error_mark_node)
return instance;
/* Start by extracting all the information from the PMF itself. */
e3 = PFN_FROM_PTRMEMFUNC (function);
vtbl = build1 (NOP_EXPR, build_pointer_type (ptr_type_node), instance);
TREE_CONSTANT (vtbl) = TREE_CONSTANT (instance);
delta = cp_convert (ptrdiff_type_node,
build_component_ref (function, delta_identifier,
NULL_TREE, 0));
/* This used to avoid checking for virtual functions if basetype
has no virtual functions, according to an earlier ANSI draft.
With the final ISO C++ rules, such an optimization is
incorrect: A pointer to a derived member can be static_cast
to pointer-to-base-member, as long as the dynamic object
later has the right member. */
delta = build_component_ref (function, delta_identifier, NULL_TREE, 0);
idx = build1 (NOP_EXPR, vtable_index_type, e3);
switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
{
case ptrmemfunc_vbit_in_pfn:
/* Mask out the virtual bit from the index. */
e1 = cp_build_binary_op (BIT_AND_EXPR, idx, integer_one_node);
mask = build1 (NOP_EXPR, vtable_index_type, build_int_2 (~1, ~0));
idx = cp_build_binary_op (BIT_AND_EXPR, idx, mask);
idx = cp_build_binary_op (MINUS_EXPR, idx, integer_one_node);
break;
case ptrmemfunc_vbit_in_delta:
e1 = cp_build_binary_op (BIT_AND_EXPR,
delta, integer_one_node);
delta = cp_build_binary_op (RSHIFT_EXPR,
build1 (NOP_EXPR, vtable_index_type,
delta),
integer_one_node);
e1 = cp_build_binary_op (BIT_AND_EXPR, delta, integer_one_node);
delta = cp_build_binary_op (RSHIFT_EXPR, delta, integer_one_node);
break;
default:
abort ();
}
/* DELTA2 is the amount by which to adjust the `this' pointer
to find the vtbl. */
delta2 = delta;
vtbl = build
(PLUS_EXPR,
build_pointer_type (build_pointer_type (vtable_entry_type)),
vtbl, cp_convert (ptrdiff_type_node, delta2));
/* Convert down to the right base before using the instance. First
use the type... */
basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
basetype, ba_check, NULL);
instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 1);
if (instance_ptr == error_mark_node)
return error_mark_node;
/* ...and then the delta in the PMF. */
instance_ptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr),
instance_ptr, delta);
/* Hand back the adjusted 'this' argument to our caller. */
*instance_ptrptr = instance_ptr;
/* Next extract the vtable pointer from the object. */
vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
instance_ptr);
vtbl = build_indirect_ref (vtbl, NULL);
/* Finally, extract the function pointer from the vtable. */
e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
e2 = build_indirect_ref (e2, NULL);
@ -2932,14 +2927,6 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
e1 = build (COMPOUND_EXPR, TREE_TYPE (e1),
instance_ptr, e1);
*instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr),
instance_ptr, delta);
if (instance_ptr == error_mark_node
&& TREE_CODE (e1) != ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (e1, 0)) != FUNCTION_DECL)
error ("object missing in `%E'", function);
function = e1;
}
return function;