call.c (convert_like): Macrofy.
authorNathan Sidwell <nathan@codesourcery.com>
Sun, 5 Mar 2000 10:22:16 +0000 (10:22 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Sun, 5 Mar 2000 10:22:16 +0000 (10:22 +0000)
* call.c (convert_like): Macrofy.
(convert_like_with_context): New macro.
(convert_like_real): Renamed from convert_like.  Add calling
context parameters, for diagnostics. Add recursive flag.  Call
dubious_conversion_warnings for outer conversion.
(build_user_type_conversion): Use convert_like_with_context.
(build_over_call): Likewise. Don't warn about dubious
conversions here. Adjust convert_default_arg calls.
(convert_default_arg): Add context parameters for diagnostics.
Pass throught to convert_like_with_context.
* cp-tree.h (convert_default_arg): Add context parameters.
(dubious_conversion_warnings): Prototype new function.
* typeck.c (convert_arguments): Adjust convert_default_arg call.
(dubious_conversion_warnings): New function, broken
out of convert_for_assignment.
(convert_for_assignment): Adjust.

From-SVN: r32341

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/typeck.c

index b97b555..2213278 100644 (file)
@@ -1,3 +1,22 @@
+2000-03-05  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * call.c (convert_like): Macrofy.
+       (convert_like_with_context): New macro.
+       (convert_like_real): Renamed from convert_like.  Add calling
+       context parameters, for diagnostics. Add recursive flag.  Call 
+       dubious_conversion_warnings for outer conversion.
+       (build_user_type_conversion): Use convert_like_with_context.
+       (build_over_call): Likewise. Don't warn about dubious
+       conversions here. Adjust convert_default_arg calls.
+       (convert_default_arg): Add context parameters for diagnostics.
+       Pass throught to convert_like_with_context.
+       * cp-tree.h (convert_default_arg): Add context parameters.
+       (dubious_conversion_warnings): Prototype new function.
+       * typeck.c (convert_arguments): Adjust convert_default_arg call.
+       (dubious_conversion_warnings): New function, broken
+       out of convert_for_assignment. 
+       (convert_for_assignment): Adjust.
+
 2000-03-03  Jason Merrill  <jason@casey.cygnus.com>
 
        * decl2.c (key_method): Break out from...
index 72c4ccb..0589cfd 100644 (file)
@@ -49,7 +49,9 @@ static int equal_functions PARAMS ((tree, tree));
 static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
 static int compare_ics PARAMS ((tree, tree));
 static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
-static tree convert_like PARAMS ((tree, tree));
+#define convert_like(CONV, EXPR) convert_like_real (CONV, EXPR, NULL_TREE, 0, 0)
+#define convert_like_with_context(CONV, EXPR, FN, ARGNO) convert_like_real (CONV, EXPR, FN, ARGNO, 0)
+static tree convert_like_real PARAMS ((tree, tree, tree, int, int));
 static void op_error PARAMS ((enum tree_code, enum tree_code, tree, tree,
                            tree, const char *));
 static tree build_object_call PARAMS ((tree, tree));
@@ -2450,7 +2452,9 @@ build_user_type_conversion (totype, expr, flags)
     {
       if (TREE_CODE (cand->second_conv) == AMBIG_CONV)
        return error_mark_node;
-      return convert_from_reference (convert_like (cand->second_conv, expr));
+      return convert_from_reference
+              (convert_like_with_context
+                (cand->second_conv, expr, cand->fn, 0));
     }
   return NULL_TREE;
 }
@@ -2654,7 +2658,8 @@ build_object_call (obj, args)
       && DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR])
     return build_over_call (cand, mem_args, LOOKUP_NORMAL);
 
-  obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj);
+  obj = convert_like_with_context
+          (TREE_VEC_ELT (cand->convs, 0), obj, cand->fn, -1);
 
   /* FIXME */
   return build_function_call (obj, args);
@@ -3593,11 +3598,17 @@ enforce_access (basetype_path, decl)
   return 1;
 }
 
-/* Perform the conversions in CONVS on the expression EXPR.  */
+/* Perform the conversions in CONVS on the expression EXPR. 
+   FN and ARGNUM are used for diagnostics.  ARGNUM is zero based, -1
+   indicates the `this' argument of a method.  INNER is non-zero when
+   being called to continue a conversion chain. */
 
 static tree
-convert_like (convs, expr)
+convert_like_real (convs, expr, fn, argnum, inner)
      tree convs, expr;
+     tree fn;
+     int argnum;
+     int inner;
 {
   if (ICS_BAD_FLAG (convs)
       && TREE_CODE (convs) != USER_CONV
@@ -3609,19 +3620,22 @@ convert_like (convs, expr)
        {
          if (TREE_CODE (t) == USER_CONV)
            {
-             expr = convert_like (t, expr);
+             expr = convert_like_real (t, expr, fn, argnum, 1);
              break;
            }
          else if (TREE_CODE (t) == AMBIG_CONV)
-           return convert_like (t, expr);
+           return convert_like_real (t, expr, fn, argnum, 1);
          else if (TREE_CODE (t) == IDENTITY_CONV)
            break;
        }
       return convert_for_initialization
        (NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL,
-        "conversion", NULL_TREE, 0);
+        "conversion", fn, argnum);
     }
-
+  
+  if (!inner)
+    expr = dubious_conversion_warnings
+             (TREE_TYPE (convs), expr, "argument", fn, argnum);
   switch (TREE_CODE (convs))
     {
     case USER_CONV:
@@ -3665,7 +3679,7 @@ convert_like (convs, expr)
       break;
     };
 
-  expr = convert_like (TREE_OPERAND (convs, 0), expr);
+  expr = convert_like_real (TREE_OPERAND (convs, 0), expr, fn, argnum, 1);
   if (expr == error_mark_node)
     return error_mark_node;
 
@@ -3840,10 +3854,11 @@ convert_type_from_ellipsis (type)
    conversions.  Return the converted value.  */
 
 tree
-convert_default_arg (type, arg, fn)
+convert_default_arg (type, arg, fn, parmnum)
      tree type;
      tree arg;
      tree fn;
+     int parmnum;
 {
   if (fn && DECL_TEMPLATE_INFO (fn))
     arg = tsubst_default_argument (fn, type, arg);
@@ -3854,7 +3869,7 @@ convert_default_arg (type, arg, fn)
     {
       arg = digest_init (type, arg, 0);
       arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
-                                       "default argument", 0, 0);
+                                       "default argument", fn, parmnum);
     }
   else
     {
@@ -3863,7 +3878,7 @@ convert_default_arg (type, arg, fn)
        arg = copy_node (arg);
 
       arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
-                                       "default argument", 0, 0);
+                                       "default argument", fn, parmnum);
       if (PROMOTE_PROTOTYPES
          && (TREE_CODE (type) == INTEGER_TYPE
              || TREE_CODE (type) == ENUMERAL_TYPE)
@@ -3956,7 +3971,7 @@ build_over_call (cand, args, flags)
              if (TREE_CODE (t) == USER_CONV
                  || TREE_CODE (t) == AMBIG_CONV)
                {
-                 val = convert_like (t, val);
+                 val = convert_like_with_context (t, val, fn, i - is_method);
                  break;
                }
              else if (TREE_CODE (t) == IDENTITY_CONV)
@@ -3964,16 +3979,13 @@ build_over_call (cand, args, flags)
            }
          val = convert_for_initialization
            (NULL_TREE, type, val, LOOKUP_NORMAL,
-            "argument passing", fn, i - is_method);
+            "argument", fn, i - is_method);
        }
       else
        {
-         /* 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));
+         val = TREE_VALUE (arg);
+         val = convert_like_with_context
+                 (conv, TREE_VALUE (arg), fn, i - is_method);
        }
 
       if (PROMOTE_PROTOTYPES
@@ -3985,12 +3997,12 @@ build_over_call (cand, args, flags)
     }
 
   /* Default arguments */
-  for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm))
+  for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++)
     converted_args 
       = tree_cons (NULL_TREE, 
                   convert_default_arg (TREE_VALUE (parm), 
                                        TREE_PURPOSE (parm),
-                                       fn),
+                                       fn, i - is_method),
                   converted_args);
 
   /* Ellipsis */
index ce2b94c..9086292 100644 (file)
@@ -3616,7 +3616,7 @@ extern tree build_op_delete_call          PARAMS ((enum tree_code, tree, tree, int, tree
 extern int can_convert                         PARAMS ((tree, tree));
 extern int can_convert_arg                     PARAMS ((tree, tree, tree));
 extern int enforce_access                       PARAMS ((tree, tree));
-extern tree convert_default_arg                 PARAMS ((tree, tree, tree));
+extern tree convert_default_arg                 PARAMS ((tree, tree, tree, int));
 extern tree convert_arg_to_ellipsis             PARAMS ((tree));
 extern tree build_x_va_arg                      PARAMS ((tree, tree));
 extern tree convert_type_from_ellipsis          PARAMS ((tree));
@@ -4407,6 +4407,7 @@ extern tree build_const_cast                      PARAMS ((tree, tree));
 extern tree build_c_cast                       PARAMS ((tree, tree));
 extern tree build_x_modify_expr                        PARAMS ((tree, enum tree_code, tree));
 extern tree build_modify_expr                  PARAMS ((tree, enum tree_code, tree));
+extern tree dubious_conversion_warnings         PARAMS ((tree, tree, const char *, tree, int));
 extern tree convert_for_initialization         PARAMS ((tree, tree, tree, int, const char *, tree, int));
 extern void c_expand_asm_operands              PARAMS ((tree, tree, tree, tree, int, char *, int));
 extern void c_expand_return                    PARAMS ((tree));
index 400d930..219ca39 100644 (file)
@@ -3215,7 +3215,7 @@ convert_arguments (typelist, values, fndecl, flags)
              tree parmval 
                = convert_default_arg (TREE_VALUE (typetail), 
                                       TREE_PURPOSE (typetail), 
-                                      fndecl);
+                                      fndecl, i);
 
              if (parmval == error_mark_node)
                return error_mark_node;
@@ -6421,6 +6421,59 @@ pfn_from_ptrmemfunc (t)
             pfn_identifier, NULL_TREE, 0)); 
 }
 
+/* Expression EXPR is about to be implicitly converted to TYPE.  Warn
+   if this is a potentially dangerous thing to do.  Returns a possibly
+   marked EXPR.  */
+
+tree
+dubious_conversion_warnings (type, expr, errtype, fndecl, parmnum)
+     tree type;
+     tree expr;
+     const char *errtype;
+     tree fndecl;
+     int parmnum;
+{
+  /* Issue warnings about peculiar, but legal, uses of NULL.  */
+  if (ARITHMETIC_TYPE_P (type) && expr == null_node)
+    {
+      if (fndecl)
+        cp_warning ("passing NULL used for non-pointer %s %P of `%D'",
+                    errtype, parmnum, fndecl);
+      else
+        cp_warning ("%s to non-pointer type `%T' from NULL", errtype, type);
+    }
+  
+  /* Warn about assigning a floating-point type to an integer type.  */
+  if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+      && TREE_CODE (type) == INTEGER_TYPE)
+    {
+      if (fndecl)
+       cp_warning ("passing `%T' for %s %P of `%D'",
+                   TREE_TYPE (expr), errtype, parmnum, fndecl);
+      else
+       cp_warning ("%s to `%T' from `%T'", errtype, type, TREE_TYPE (expr));
+    }
+  /* And warn about assigning a negative value to an unsigned
+     variable.  */
+  else if (TREE_UNSIGNED (type) && TREE_CODE (type) != BOOLEAN_TYPE)
+    {
+      if (TREE_CODE (expr) == INTEGER_CST
+         && TREE_NEGATED_INT (expr))
+       {
+         if (fndecl)
+           cp_warning ("passing negative value `%E' for %s %P of `%D'",
+                       expr, errtype, parmnum, fndecl);
+         else
+           cp_warning ("%s of negative value `%E' to `%T'",
+                       errtype, expr, type);
+       }
+      overflow_warning (expr);
+      if (TREE_CONSTANT (expr))
+       expr = fold (expr);
+    }
+  return expr;
+}
+
 /* Convert value RHS to type TYPE as preparation for an assignment to
    an lvalue of type TYPE.  ERRTYPE is a string to use in error
    messages: "assignment", "return", etc.  If FNDECL is non-NULL, we
@@ -6456,12 +6509,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
   if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
     return error_mark_node;
 
-  /* Issue warnings about peculiar, but legal, uses of NULL.  We
-     do this *before* the call to decl_constant_value so as to
-     avoid duplicate warnings on code like `const int I = NULL;
-     f(I);'.  */
-  if (ARITHMETIC_TYPE_P (type) && rhs == null_node)
-    cp_warning ("converting NULL to non-pointer type");
+  rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum);
 
   /* The RHS of an assignment cannot have void type.  */
   if (coder == VOID_TYPE)
@@ -6476,34 +6524,6 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
   else if (TREE_READONLY_DECL_P (rhs))
     rhs = decl_constant_value (rhs);
 
-  /* Warn about assigning a floating-point type to an integer type.  */
-  if (coder == REAL_TYPE && codel == INTEGER_TYPE)
-    {
-      if (fndecl)
-       cp_warning ("`%T' used for argument %P of `%D'",
-                   rhstype, parmnum, fndecl);
-      else
-       cp_warning ("%s to `%T' from `%T'", errtype, type, rhstype);
-    }
-  /* And warn about assigning a negative value to an unsigned
-     variable.  */
-  else if (TREE_UNSIGNED (type) && codel != BOOLEAN_TYPE)
-    {
-      if (TREE_CODE (rhs) == INTEGER_CST
-         && TREE_NEGATED_INT (rhs))
-       {
-         if (fndecl)
-           cp_warning ("negative value `%E' passed as argument %P of `%D'",
-                       rhs, parmnum, fndecl);
-         else
-           cp_warning ("%s of negative value `%E' to `%T'",
-                       errtype, rhs, type);
-       }
-      overflow_warning (rhs);
-      if (TREE_CONSTANT (rhs))
-       rhs = fold (rhs);
-    }
-
   /* [expr.ass]
 
      The expression is implicitly converted (clause _conv_) to the