aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-05-09 13:27:37 -0400
committerJason Merrill <jason@gcc.gnu.org>2002-05-09 13:27:37 -0400
commitc87978aa20c2807f8654f16ac3668ea67e9e5a9a (patch)
tree8de79106bf22e9d38596fd2528e50ab966541607 /gcc
parentff431459927172204c448438bf7de202480a9d87 (diff)
downloadgcc-c87978aa20c2807f8654f16ac3668ea67e9e5a9a.zip
gcc-c87978aa20c2807f8654f16ac3668ea67e9e5a9a.tar.gz
gcc-c87978aa20c2807f8654f16ac3668ea67e9e5a9a.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cvt.c3
-rw-r--r--gcc/cp/pt.c13
-rw-r--r--gcc/cp/typeck.c111
4 files changed, 67 insertions, 68 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6102f84..aa6dff6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index b5306c1..fc57dd3 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -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))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7551df7..c4e119e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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:
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index a1050bb..329bc33 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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;