OSDN Git Service

* typeck.c (get_member_function_from_ptrfunc): Reorganize.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 May 2002 17:27:37 +0000 (17:27 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 May 2002 17:27:37 +0000 (17:27 +0000)
        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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53335 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/cp/pt.c
gcc/cp/typeck.c

index 6102f84..aa6dff6 100644 (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.
index b5306c1..fc57dd3 100644 (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))
index 7551df7..c4e119e 100644 (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:
index a1050bb..329bc33 100644 (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;