OSDN Git Service

* lex.c (handle_cp_pragma): Remove #pragma vtable.
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 936dcb6..bb0b71a 100644 (file)
@@ -883,6 +883,9 @@ standard_conversion (to, from, expr)
        /* OK */;
       else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from)))
        conv = build_conv (QUAL_CONV, to, conv);
+      else if (expr && string_conv_p (to, expr, 0))
+       /* converting from string constant to char *.  */
+       conv = build_conv (QUAL_CONV, to, conv);
       else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from)))
        {
          conv = build_conv (PTR_CONV, to, conv);
@@ -1144,15 +1147,9 @@ add_function_candidate (candidates, fn, arglist, flags)
   for (i = 0; i < len; ++i)
     {
       tree arg = TREE_VALUE (argnode);
-      tree argtype = TREE_TYPE (arg);
+      tree argtype = lvalue_type (arg);
       tree t;
 
-      /* An overloaded function does not have an argument type */
-      if (TREE_CODE (arg) == OVERLOAD)
-       argtype = unknown_type_node;
-      argtype = cp_build_type_variant
-       (argtype, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg));
-
       if (parmnode == void_list_node)
        break;
       else if (parmnode)
@@ -3178,6 +3175,11 @@ convert_like (convs, expr)
     case LVALUE_CONV:
       return decay_conversion (expr);
 
+    case QUAL_CONV:
+      /* Warn about deprecated conversion if appropriate.  */
+      string_conv_p (TREE_TYPE (convs), expr, 1);
+      break;
+      
     default:
       break;
     }
@@ -3289,6 +3291,7 @@ build_over_call (cand, args, flags)
     {
       tree parmtype = TREE_VALUE (parm);
       tree argtype = TREE_TYPE (TREE_VALUE (arg));
+      tree t;
       if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i)))
        {
          int dv = (TYPE_VOLATILE (TREE_TYPE (parmtype))
@@ -3301,9 +3304,18 @@ build_over_call (cand, args, flags)
          cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards %s",
                      TREE_TYPE (argtype), fn, p);
        }
-      converted_args = expr_tree_cons
-       (NULL_TREE, convert_force (TREE_VALUE (parm), TREE_VALUE (arg), CONV_C_CAST),
-        converted_args);
+      /* [class.mfct.nonstatic]: If a nonstatic member function of a class
+        X is called for an object that is not of type X, or of a type
+        derived from X, the behavior is undefined.
+
+         So we can assume that anything passed as 'this' is non-null, and
+        optimize accordingly.  */
+      if (TREE_CODE (parmtype) == POINTER_TYPE)
+       t = convert_pointer_to_real (TREE_TYPE (parmtype), TREE_VALUE (arg));
+      else
+       /* This happens with signatures.  */
+       t = convert_force (parmtype, TREE_VALUE (arg), CONV_C_CAST);
+      converted_args = expr_tree_cons (NULL_TREE, t, converted_args);
       parm = TREE_CHAIN (parm);
       arg = TREE_CHAIN (arg);
       ++i;
@@ -3337,7 +3349,14 @@ build_over_call (cand, args, flags)
             "argument passing", fn, i - is_method);
        }
       else
-       val = convert_like (conv, TREE_VALUE (arg));
+       {
+         /* Issue warnings about peculiar, but legal, uses of NULL.  */
+         if (ARITHMETIC_TYPE_P (TREE_VALUE (parm))
+             && TREE_VALUE (arg) == null_node)
+           cp_warning ("converting NULL to non-pointer type");
+           
+         val = convert_like (conv, TREE_VALUE (arg));
+       }
 
 #ifdef PROMOTE_PROTOTYPES
       if ((TREE_CODE (type) == INTEGER_TYPE
@@ -3372,7 +3391,7 @@ build_over_call (cand, args, flags)
          arg = tsubst_expr (arg, DECL_TI_ARGS (fn), NULL_TREE);
 
          if (DECL_CLASS_SCOPE_P (fn))
-           popclass (0);
+           popclass (1);
        }
       converted_args = expr_tree_cons
        (NULL_TREE, convert_default_arg (TREE_VALUE (parm), arg),
@@ -3390,8 +3409,11 @@ build_over_call (cand, args, flags)
 
   /* Avoid actually calling copy constructors and copy assignment operators,
      if possible.  */
-  if (DECL_CONSTRUCTOR_P (fn)
-      && TREE_VEC_LENGTH (convs) == 1
+
+  if (! flag_elide_constructors)
+    /* Do things the hard way.  */;
+  else if (DECL_CONSTRUCTOR_P (fn)
+          && TREE_VEC_LENGTH (convs) == 1
       && copy_args_p (fn))
     {
       tree targ;