Hi,

On 04/26/2012 03:27 PM, Gabriel Dos Reis wrote:
yes, it does. On the other hand, the program is going to exit soon... -- Gaby
In any case, a bit of sloppiness on my part. Sorry about that. Now, all in all I don't have a strong opinion, but we may want to apply something like the below (booted ant tested). Let me know if you want it...

Thanks!
Paolo.

////////////////////////////
2012-04-27  Paolo Carlini  <paolo.carl...@oracle.com>

        * call.c (op_error_string, op_error): Rework to avoid memory leaks
        due to missing free calls matching the concat calls.
Index: call.c
===================================================================
--- call.c      (revision 186887)
+++ call.c      (working copy)
@@ -4181,14 +4181,13 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsub
    function.  It concatenates a prefix (controlled by MATCH), ERRMSG,
    and a suffix (controlled by NTYPES).  */
 
-static const char *
+static char *
 op_error_string (const char *errmsg, int ntypes, bool match)
 {
-  const char *msg;
+  char *msg;
+  char *msgp = concat (match ? G_("ambiguous overload for ")
+                      : G_("no match for "), errmsg, NULL);
 
-  const char *msgp = concat (match ? G_("ambiguous overload for ")
-                                  : G_("no match for "), errmsg, NULL);
-
   if (ntypes == 3)
     msg = concat (msgp, G_(" (operand types are %qT, %qT, and %qT)"), NULL);
   else if (ntypes == 2)
@@ -4196,6 +4195,7 @@ op_error_string (const char *errmsg, int ntypes, b
   else
     msg = concat (msgp, G_(" (operand type is %qT)"), NULL);
 
+  free (msgp);
   return msg;
 }
 
@@ -4204,6 +4204,7 @@ op_error (enum tree_code code, enum tree_code code
          tree arg1, tree arg2, tree arg3, bool match)
 {
   const char *opname;
+  char *errstr;
 
   if (code == MODIFY_EXPR)
     opname = assignment_operator_name_info[code2].name;
@@ -4214,64 +4215,93 @@ op_error (enum tree_code code, enum tree_code code
     {
     case COND_EXPR:
       if (flag_diagnostics_show_caret)
-       error (op_error_string (G_("ternary %<operator?:%>"), 3, match),
-              TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+       {
+         errstr = op_error_string (G_("ternary %<operator?:%>"), 3, match);
+         error (errstr, TREE_TYPE (arg1), TREE_TYPE (arg2),
+                TREE_TYPE (arg3));
+       }
       else
-       error (op_error_string (G_("ternary %<operator?:%> "
-                                  "in %<%E ? %E : %E%>"), 3, match),
-              arg1, arg2, arg3,
-              TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+       {
+         errstr = op_error_string (G_("ternary %<operator?:%> "
+                                      "in %<%E ? %E : %E%>"), 3, match);
+         error (errstr, arg1, arg2, arg3,
+                TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+       }
       break;
 
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
       if (flag_diagnostics_show_caret)
-       error (op_error_string (G_("%<operator%s%>"), 1, match),
-              opname, TREE_TYPE (arg1));
+       {
+         errstr = op_error_string (G_("%<operator%s%>"), 1, match);
+         error (errstr, opname, TREE_TYPE (arg1));
+       }
       else
-       error (op_error_string (G_("%<operator%s%> in %<%E%s%>"), 1, match),
-              opname, arg1, opname, TREE_TYPE (arg1));
+       {
+         errstr = op_error_string (G_("%<operator%s%> in %<%E%s%>"),
+                                   1, match);
+         error (errstr, opname, arg1, opname, TREE_TYPE (arg1));
+       }
       break;
 
     case ARRAY_REF:
       if (flag_diagnostics_show_caret)
-       error (op_error_string (G_("%<operator[]%>"), 2, match),
-              TREE_TYPE (arg1), TREE_TYPE (arg2));
+       {
+         errstr = op_error_string (G_("%<operator[]%>"), 2, match);
+         error (errstr, TREE_TYPE (arg1), TREE_TYPE (arg2));
+       }
       else
-       error (op_error_string (G_("%<operator[]%> in %<%E[%E]%>"), 2, match),
-              arg1, arg2, TREE_TYPE (arg1), TREE_TYPE (arg2));
+       {
+         errstr = op_error_string (G_("%<operator[]%> in %<%E[%E]%>"),
+                                   2, match);
+         error (errstr, arg1, arg2, TREE_TYPE (arg1), TREE_TYPE (arg2));
+       }
       break;
 
     case REALPART_EXPR:
     case IMAGPART_EXPR:
       if (flag_diagnostics_show_caret)
-       error (op_error_string (G_("%qs"), 1, match),
-              opname, TREE_TYPE (arg1));
+       {
+         errstr = op_error_string (G_("%qs"), 1, match);
+         error (errstr, opname, TREE_TYPE (arg1));
+       }
       else
-       error (op_error_string (G_("%qs in %<%s %E%>"), 1, match),
-              opname, opname, arg1, TREE_TYPE (arg1));
+       {
+         errstr = op_error_string (G_("%qs in %<%s %E%>"), 1, match);
+         error (errstr, opname, opname, arg1, TREE_TYPE (arg1));
+       }
       break;
 
     default:
       if (arg2)
        if (flag_diagnostics_show_caret)
-         error (op_error_string (G_("%<operator%s%>"), 2, match),
-                opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
+         {
+           errstr = op_error_string (G_("%<operator%s%>"), 2, match);
+           error (errstr, opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
+         }
        else
-         error (op_error_string (G_("%<operator%s%> in %<%E %s %E%>"),
-                                 2, match),
-                opname, arg1, opname, arg2,
-                TREE_TYPE (arg1), TREE_TYPE (arg2));
+         {
+           errstr = op_error_string (G_("%<operator%s%> in %<%E %s %E%>"),
+                                     2, match);
+           error (errstr, opname, arg1, opname, arg2,
+                  TREE_TYPE (arg1), TREE_TYPE (arg2));
+         }
       else
        if (flag_diagnostics_show_caret)
-         error (op_error_string (G_("%<operator%s%>"), 1, match),
-                opname, TREE_TYPE (arg1));
+         {
+           errstr = op_error_string (G_("%<operator%s%>"), 1, match);
+           error (errstr, opname, TREE_TYPE (arg1));
+         }
        else
-         error (op_error_string (G_("%<operator%s%> in %<%s%E%>"),
-                                 1, match),
-                opname, opname, arg1, TREE_TYPE (arg1));
+         {
+           errstr = op_error_string (G_("%<operator%s%> in %<%s%E%>"),
+                                     1, match);
+           error (errstr, opname, opname, arg1, TREE_TYPE (arg1));
+         }
       break;
     }
+
+  free (errstr);
 }
 
 /* Return the implicit conversion sequence that could be used to

Reply via email to