c++: don't leak 'arglist' in build_new_op

Message ID 20211210162156.3337828-1-ppalka@redhat.com
State Committed
Commit 336dc544ebca867794a8e57c65afe303fd8ecc66
Headers
Series c++: don't leak 'arglist' in build_new_op |

Commit Message

Patrick Palka Dec. 10, 2021, 4:21 p.m. UTC
  'arglist' can be captured by a conversion within 'candidates', but if we
use a releasing_vec then we'll be sure to free it only after
'candidates' is freed by obstack_free.

Bootstrapped and regtested in x86_64-pc-linux-gnu, does this look OK for
trunk?

gcc/cp/ChangeLog:

	* call.c (build_new_op): Use releasing_vec for arglist.  Declare
	conv in the scope it's used.
---
 gcc/cp/call.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
  

Comments

Jason Merrill Dec. 13, 2021, 3:03 p.m. UTC | #1
On 12/10/21 11:21, Patrick Palka wrote:
> 'arglist' can be captured by a conversion within 'candidates', but if we
> use a releasing_vec then we'll be sure to free it only after
> 'candidates' is freed by obstack_free.
> 
> Bootstrapped and regtested in x86_64-pc-linux-gnu, does this look OK for
> trunk?

OK.

> gcc/cp/ChangeLog:
> 
> 	* call.c (build_new_op): Use releasing_vec for arglist.  Declare
> 	conv in the scope it's used.
> ---
>   gcc/cp/call.c | 6 ++----
>   1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/cp/call.c b/gcc/cp/call.c
> index 28bd8e0c260..347df5da35d 100644
> --- a/gcc/cp/call.c
> +++ b/gcc/cp/call.c
> @@ -6461,13 +6461,12 @@ build_new_op (const op_location_t &loc, enum tree_code code, int flags,
>   	      tsubst_flags_t complain)
>   {
>     struct z_candidate *candidates = 0, *cand;
> -  vec<tree, va_gc> *arglist;
> +  releasing_vec arglist;
>     tree result = NULL_TREE;
>     bool result_valid_p = false;
>     enum tree_code code2 = ERROR_MARK;
>     enum tree_code code_orig_arg1 = ERROR_MARK;
>     enum tree_code code_orig_arg2 = ERROR_MARK;
> -  conversion *conv;
>     void *p;
>     bool strict_p;
>     bool any_viable_p;
> @@ -6543,7 +6542,6 @@ build_new_op (const op_location_t &loc, enum tree_code code, int flags,
>         arg2_type = integer_type_node;
>       }
>   
> -  vec_alloc (arglist, 3);
>     arglist->quick_push (arg1);
>     if (arg2 != NULL_TREE)
>       arglist->quick_push (arg2);
> @@ -6814,7 +6812,7 @@ build_new_op (const op_location_t &loc, enum tree_code code, int flags,
>   	     corresponding parameters of the selected operation function,
>   	     except that the second standard conversion sequence of a
>   	     user-defined conversion sequence (12.3.3.1.2) is not applied."  */
> -	  conv = cand->convs[0];
> +	  conversion *conv = cand->convs[0];
>   	  if (conv->user_conv_p)
>   	    {
>   	      conv = strip_standard_conversion (conv);
  

Patch

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 28bd8e0c260..347df5da35d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6461,13 +6461,12 @@  build_new_op (const op_location_t &loc, enum tree_code code, int flags,
 	      tsubst_flags_t complain)
 {
   struct z_candidate *candidates = 0, *cand;
-  vec<tree, va_gc> *arglist;
+  releasing_vec arglist;
   tree result = NULL_TREE;
   bool result_valid_p = false;
   enum tree_code code2 = ERROR_MARK;
   enum tree_code code_orig_arg1 = ERROR_MARK;
   enum tree_code code_orig_arg2 = ERROR_MARK;
-  conversion *conv;
   void *p;
   bool strict_p;
   bool any_viable_p;
@@ -6543,7 +6542,6 @@  build_new_op (const op_location_t &loc, enum tree_code code, int flags,
       arg2_type = integer_type_node;
     }
 
-  vec_alloc (arglist, 3);
   arglist->quick_push (arg1);
   if (arg2 != NULL_TREE)
     arglist->quick_push (arg2);
@@ -6814,7 +6812,7 @@  build_new_op (const op_location_t &loc, enum tree_code code, int flags,
 	     corresponding parameters of the selected operation function,
 	     except that the second standard conversion sequence of a
 	     user-defined conversion sequence (12.3.3.1.2) is not applied."  */
-	  conv = cand->convs[0];
+	  conversion *conv = cand->convs[0];
 	  if (conv->user_conv_p)
 	    {
 	      conv = strip_standard_conversion (conv);