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