This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, c++ diagnostics] Fix c++ front end i18n problems


On 12/11/2009 04:34 AM, Shujing Zhao wrote:
  if (!spaces)
    {
      /* String owned by the owner, it should not be freed.  */
      *str = NULL;
    }

In order to print " "<repeat n times> from the second candidate at


error ("%s %+#D", *str, OVL_CURRENT (fn));

The *str is changed at print_overloaded_functions first. When the
OVL_NEXT loop is over, and back to print_chained_functions, call
print_overloaded_functions will transfer " "<repeat n times> to
print_overloaded_functions. That is also why the argument of
print_overloaded_functions is **str not *str.
Since the pointer spaces and *str point the same place after assign
spaces to *str, *str can't be assign NULL. Otherwise it will produce
"segment fault".

Yes, understood. I think your patch from yesterday would be almost okay, except for the wrong "fns == NULL_TREE && !TREE_VALUE (fns)" condition. The correct one would be "fns == NULL_TREE || !TREE_CHAIN (fns)", I think.


However, the whole interaction between print_overloaded_functions, print_chained_functions and print_candidates is messy. I tried doing it with a single recursive function. Here is what it may look like:

/* Print the list of functions at FNS, going through all the overloads
   for each element of the list.  Alternatively, FNS can not be a
   TREE_LIST, in which case it will be printed together with all the
   overloads.

   MORE and *STR should respectively be 0 and point to NULL
   when the function is called from the outside.  They are used
   internally on recursive calls.  print_candidates manages the
   two parameters.  */

static void
print_candidates_1 (tree fns, int more, const char **str)
{
  tree fn;
  char *spaces = NULL;

  for (fn = fns; fn; fn = OVL_NEXT (fn))
    if (TREE_CODE (fn) == TREE_LIST)
      {
        tree fn2;
        for (fn2 = fn; fn2 != NULL_TREE; fn2 = TREE_CHAIN (fn))
          print_candidates_1 (TREE_VALUE (fn2),
                              TREE_CHAIN (fn2) || more, str);
      }
    else
      {
        if (!*str)
          {
            /* Pick the prefix string.  */
            if !more && !OVL_NEXT (fns))
              {
                error ("candidate is: %+#D", OVL_CURRENT (fn));
                continue;
              }

            *str = _("candidates are:");
            spaces = get_spaces (*str);
          }
        error ("%s %+#D", *str, OVL_CURRENT (fn));
        *str = spaces ? spaces : *str;
      }

  if (!more && spaces)
    {
      free (spaces);
      *str = NULL;
    }
}

static void
print_candidates (tree fns)
{
  char *str = NULL;
  gcc_assert (!(is_overloaded_fn (fns)
                && TREE_CODE (fns) == TREE_LIST));
  print_overloaded_functions (fns, 0, &str);
  gcc_assert (str == NULL);
}

What do you think?

Paolo


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]