OSDN Git Service

PR c++/10471
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 09a0656..200aae7 100644 (file)
@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "expr.h"
 #include "diagnostic.h"
+#include "intl.h"
 
 extern int inhibit_warnings;
 
@@ -56,6 +57,7 @@ static void op_error (enum tree_code, enum tree_code, tree, tree,
 static tree build_object_call (tree, tree);
 static tree resolve_args (tree);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
+static void print_z_candidate (const char *, struct z_candidate *);
 static void print_z_candidates (struct z_candidate *);
 static tree build_this (tree);
 static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
@@ -2275,7 +2277,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
   if (i != 0)
     return NULL;
 
-  fn = instantiate_template (tmpl, targs);
+  fn = instantiate_template (tmpl, targs, tf_none);
   if (fn == error_mark_node)
     return NULL;
 
@@ -2435,34 +2437,39 @@ equal_functions (tree fn1, tree fn2)
   return fn1 == fn2;
 }
 
-/* Print information about one overload candidate CANDIDATE.  STR is the
-   text to print before the candidate itself and ERRFN is the routine
-   (i.e. error, warning or pedwarn) used to do the printing.  */
+/* Print information about one overload candidate CANDIDATE.  MSGSTR
+   is the text to print before the candidate itself.
+
+   NOTE: Unlike most diagnostic functions in GCC, MSGSTR is expected
+   to have been run through gettext by the caller.  This wart makes
+   life simpler in print_z_candidates and for the translators.  */
 
 static void
-print_z_candidate (const char *str, struct z_candidate *candidate,
-                  void (*errfn)(const char *, ...))
+print_z_candidate (const char *msgstr, struct z_candidate *candidate)
 {
   if (TREE_CODE (candidate->fn) == IDENTIFIER_NODE)
     {
       if (TREE_VEC_LENGTH (candidate->convs) == 3)
-       errfn ("%s %D(%T, %T, %T) <built-in>", str, candidate->fn,
-              TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
-              TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)),
-              TREE_TYPE (TREE_VEC_ELT (candidate->convs, 2)));
+       inform ("%s %D(%T, %T, %T) <built-in>", msgstr, candidate->fn,
+               TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
+               TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)),
+               TREE_TYPE (TREE_VEC_ELT (candidate->convs, 2)));
       else if (TREE_VEC_LENGTH (candidate->convs) == 2)
-       errfn ("%s %D(%T, %T) <built-in>", str, candidate->fn,
-              TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
-              TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)));
+       inform ("%s %D(%T, %T) <built-in>", msgstr, candidate->fn,
+               TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
+               TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)));
       else
-       errfn ("%s %D(%T) <built-in>", str, candidate->fn,
-              TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)));
+       inform ("%s %D(%T) <built-in>", msgstr, candidate->fn,
+               TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)));
     }
   else if (TYPE_P (candidate->fn))
-    errfn ("%s %T <conversion>", str, candidate->fn);
+    inform ("%s %T <conversion>", msgstr, candidate->fn);
+  else if (candidate->viable == -1)
+    inform ("%H%s %+#D <near match>",
+           &DECL_SOURCE_LOCATION (candidate->fn), msgstr, candidate->fn);
   else
-    errfn ("%H%s %+#D%s", &DECL_SOURCE_LOCATION (candidate->fn), str,
-          candidate->fn, candidate->viable == -1 ? " <near match>" : "");
+    inform ("%H%s %+#D",
+           &DECL_SOURCE_LOCATION (candidate->fn), msgstr, candidate->fn);
 }
 
 static void
@@ -2494,11 +2501,27 @@ print_z_candidates (struct z_candidate *candidates)
        }
     }
 
-  str = "candidates are:";
-  for (; candidates; candidates = candidates->next)
+  if (!candidates)
+    return;
+
+  str = _("candidates are:");
+  print_z_candidate (str, candidates);
+  if (candidates->next)
     {
-      print_z_candidate (str, candidates, error);
-      str = "               "; 
+      /* Indent successive candidates by the width of the translation
+        of the above string.  */
+      size_t len = gcc_gettext_width (str) + 1;
+      char *spaces = alloca (len);
+      memset (spaces, ' ', len-1);
+      spaces[len] = '\0';
+
+      candidates = candidates->next;
+      do
+       {
+         print_z_candidate (spaces, candidates);
+         candidates = candidates->next;
+       }
+      while (candidates);
     }
 }
 
@@ -3416,18 +3439,10 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
      We use ocp_convert rather than build_user_type_conversion because the
      latter returns NULL_TREE on failure, while the former gives an error.  */
 
-  if (IS_AGGR_TYPE (TREE_TYPE (arg2)))
-    arg2 = ocp_convert (TREE_TYPE (arg2), arg2,
-                       CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
-  else
-    arg2 = decay_conversion (arg2);
+  arg2 = force_rvalue (arg2);
   arg2_type = TREE_TYPE (arg2);
 
-  if (IS_AGGR_TYPE (TREE_TYPE (arg3)))
-    arg3 = ocp_convert (TREE_TYPE (arg3), arg3,
-                       CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
-  else
-    arg3 = decay_conversion (arg3);
+  arg3 = force_rvalue (arg3);
   arg3_type = TREE_TYPE (arg3);
 
   if (arg2 == error_mark_node || arg3 == error_mark_node)
@@ -4692,10 +4707,22 @@ build_over_call (struct z_candidate *cand, int flags)
   else
     fn = build_addr_func (fn);
 
+  return build_cxx_call (fn, args, converted_args);
+}
+
+/* Build and return a call to FN, using the the CONVERTED_ARGS.  ARGS
+   gives the original form of the arguments.  This function performs
+   no overload resolution, conversion, or other high-level
+   operations.  */
+
+tree
+build_cxx_call(tree fn, tree args, tree converted_args)
+{
+  tree fndecl;
+
   /* Recognize certain built-in functions so we can make tree-codes
      other than CALL_EXPR.  We do this when it enables fold-const.c
      to do something useful.  */
-
   if (TREE_CODE (fn) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
       && DECL_BUILT_IN (TREE_OPERAND (fn, 0)))
@@ -4706,14 +4733,26 @@ build_over_call (struct z_candidate *cand, int flags)
        return exp;
     }
 
-  /* Some built-in function calls will be evaluated at
-     compile-time in fold ().  */
-  fn = fold (build_call (fn, converted_args));
+  fn = build_call (fn, converted_args);
+
+  /* If this call might throw an exception, note that fact.  */
+  fndecl = get_callee_fndecl (fn);
+  if ((!fndecl || !TREE_NOTHROW (fndecl)) 
+      && at_function_scope_p ()
+      && cfun)
+    cp_function_chain->can_throw = 1;
+
+  /* Some built-in function calls will be evaluated at compile-time in
+     fold ().  */
+  fn = fold (fn);
+
   if (VOID_TYPE_P (TREE_TYPE (fn)))
     return fn;
+
   fn = require_complete_type (fn);
   if (fn == error_mark_node)
     return error_mark_node;
+
   if (IS_AGGR_TYPE (TREE_TYPE (fn)))
     fn = build_cplus_new (TREE_TYPE (fn), fn);
   return convert_from_reference (fn);
@@ -5872,10 +5911,12 @@ tweak:
         {
          if (warn)
            {
-             print_z_candidate ("ISO C++ says that ", w, pedwarn);
-             print_z_candidate ("              and ", l, pedwarn);
-             pedwarn ("are ambiguous even though the worst conversion \
-for the former is better than the worst conversion for the latter");
+             pedwarn ("\
+ISO C++ says that these are ambiguous, even \
+though the worst conversion for the first is better than \
+the worst conversion for the second:");
+             print_z_candidate (_("candidate 1:"), w);
+             print_z_candidate (_("candidate 2:"), l);
            }
          else
            add_warning (w, l);