Patchwork [C++] PR 49152

login
register
mail settings
Submitter Paolo Carlini
Date April 27, 2012, 12:25 a.m.
Message ID <4F99E78F.4000905@oracle.com>
Download mbox | patch
Permalink /patch/155347/
State New
Headers show

Comments

Paolo Carlini - April 27, 2012, 12:25 a.m.
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.carlini@oracle.com>

	* call.c (op_error_string, op_error): Rework to avoid memory leaks
	due to missing free calls matching the concat calls.

Patch

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