changeset 17632:bd0a84de3375

further reduce memory leaks from parse errors (bug #40231) * oct-parse.in.yy (colon_expr1): Delete operands on error. (function1, jump_command): No need to check for errors. (expression): Delete simple_expr on error. (return_list): Delete parameter list on error. (octave_base_parser::make_unwind_command, octave_base_parser::make_try_command, octave_base_parser::make_while_command, octave_base_parser::make_for_command, octave_base_parser::finish_if_command, octave_base_parser::finish_switch_command, octave_base_parser::make_index_expression): Delete component parse tree elements on error.
author John W. Eaton <jwe@octave.org>
date Fri, 11 Oct 2013 12:28:26 -0400
parents 94dd9bba06a0
children 382aaf2d533a
files libinterp/parse-tree/oct-parse.in.yy
diffstat 1 files changed, 139 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy	Fri Oct 11 09:20:06 2013 -0700
+++ b/libinterp/parse-tree/oct-parse.in.yy	Fri Oct 11 12:28:26 2013 -0400
@@ -377,7 +377,10 @@
                   {
                     $$ = parser.make_index_expression ($1, $2, '(');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1 and $2.
+                        ABORT_PARSE;
+                      }
                   }
                 ;
 
@@ -567,25 +570,37 @@
                   {
                     $$ = parser.make_index_expression ($1, 0, '(');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1.
+                        ABORT_PARSE;
+                      }
                   }
                 | oper_expr '(' arg_list ')'
                   {
                     $$ = parser.make_index_expression ($1, $3, '(');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1 and $3.
+                        ABORT_PARSE;
+                      }
                   }
                 | oper_expr '{' '}'
                   {
                     $$ = parser.make_index_expression ($1, 0, '{');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1.
+                        ABORT_PARSE;
+                      }
                   }
                 | oper_expr '{' arg_list '}'
                   {
                     $$ = parser.make_index_expression ($1, $3, '{');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1 and $3.
+                        ABORT_PARSE;
+                      }
                   }
                 | oper_expr HERMITIAN
                   { $$ = parser.make_postfix_op (HERMITIAN, $1, $2); }
@@ -641,25 +656,37 @@
                   {
                     $$ = parser.make_index_expression ($1, 0, '(');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1.
+                        ABORT_PARSE;
+                      }
                   }
                 | power_expr '(' arg_list ')'
                   {
                     $$ = parser.make_index_expression ($1, $3, '(');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1 and $3.
+                        ABORT_PARSE;
+                      }
                   }
                 | power_expr '{' '}'
                   {
                     $$ = parser.make_index_expression ($1, 0, '{');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1.
+                        ABORT_PARSE;
+                      }
                   }
                 | power_expr '{' arg_list '}'
                   {
                     $$ = parser.make_index_expression ($1, $3, '{');
                     if (! $$)
-                      ABORT_PARSE;
+                      {
+                        // make_index_expression deleted $1 and $3.
+                        ABORT_PARSE;
+                      }
                   }
                 | power_expr indirect_ref_op STRUCT_ELT
                   { $$ = parser.make_indirect_ref ($1, $3->text ()); }
@@ -686,7 +713,11 @@
                 | colon_expr1 ':' oper_expr
                   {
                     if (! ($$ = $1->append ($3)))
-                      ABORT_PARSE;
+                      {
+                        delete $1;
+                        delete $3;
+                        ABORT_PARSE;
+                      }
                   }
                 ;
 
@@ -861,7 +892,10 @@
 if_command      : IF stash_comment if_cmd_list END
                   {
                     if (! ($$ = parser.finish_if_command ($1, $3, $4, $2)))
-                      ABORT_PARSE;
+                      {
+                        // finish_if_command deleted $3.
+                        ABORT_PARSE;
+                      }
                   }
                 ;
 
@@ -906,7 +940,10 @@
 switch_command  : SWITCH stash_comment expression opt_sep case_list END
                   {
                     if (! ($$ = parser.finish_switch_command ($1, $3, $5, $6, $2)))
-                      ABORT_PARSE;
+                      {
+                        // finish_switch_command deleted $3 adn $5.
+                        ABORT_PARSE;
+                      }
                   }
                 ;
 
@@ -951,36 +988,50 @@
                     $3->mark_braindead_shortcircuit (lexer.fcn_file_full_name);
 
                     if (! ($$ = parser.make_while_command ($1, $3, $6, $7, $2)))
-                      ABORT_PARSE;
+                      {
+                        // make_while_command deleted $3 and $6.
+                        ABORT_PARSE;
+                      }
                   }
                 | DO stash_comment opt_sep opt_list UNTIL expression
                   {
-                    if (! ($$ = parser.make_do_until_command ($5, $4, $6, $2)))
-                      ABORT_PARSE;
+                    $$ = parser.make_do_until_command ($5, $4, $6, $2);
                   }
                 | FOR stash_comment assign_lhs '=' expression stmt_begin opt_sep opt_list END
                   {
                     if (! ($$ = parser.make_for_command (FOR, $1, $3, $5, 0,
-                                                  $8, $9, $2)))
-                      ABORT_PARSE;
+                                                         $8, $9, $2)))
+                      {
+                        // make_for_command deleted $3, $5, and $8.
+                        ABORT_PARSE;
+                      }
                   }
                 | FOR stash_comment '(' assign_lhs '=' expression ')' opt_sep opt_list END
                   {
                     if (! ($$ = parser.make_for_command (FOR, $1, $4, $6, 0,
-                                                  $9, $10, $2)))
-                      ABORT_PARSE;
+                                                         $9, $10, $2)))
+                      {
+                        // make_for_command deleted $4, $6, and $9.
+                        ABORT_PARSE;
+                      }
                   }
                 | PARFOR stash_comment assign_lhs '=' expression stmt_begin opt_sep opt_list END
                   {
                     if (! ($$ = parser.make_for_command (PARFOR, $1, $3, $5,
-                                                  0, $8, $9, $2)))
-                      ABORT_PARSE;
+                                                         0, $8, $9, $2)))
+                      {
+                        // make_for_command deleted $3, $5, and $8.
+                        ABORT_PARSE;
+                      }
                   }
                 | PARFOR stash_comment '(' assign_lhs '=' expression ',' expression ')' opt_sep opt_list END
                   {
                     if (! ($$ = parser.make_for_command (PARFOR, $1, $4, $6,
-                                                  $8, $11, $12, $2)))
-                      ABORT_PARSE;
+                                                         $8, $11, $12, $2)))
+                      {
+                        // make_for_command deleted $4, $6, $8, and $11.
+                        ABORT_PARSE;
+                      }
                   }
                 ;
 
@@ -989,20 +1040,11 @@
 // =======
 
 jump_command    : BREAK
-                  {
-                    if (! ($$ = parser.make_break_command ($1)))
-                      ABORT_PARSE;
-                  }
+                  { $$ = parser.make_break_command ($1); }
                 | CONTINUE
-                  {
-                    if (! ($$ = parser.make_continue_command ($1)))
-                      ABORT_PARSE;
-                  }
+                  { $$ = parser.make_continue_command ($1); }
                 | FUNC_RET
-                  {
-                    if (! ($$ = parser.make_return_command ($1)))
-                      ABORT_PARSE;
-                  }
+                  { $$ = parser.make_return_command ($1); }
                 ;
 
 // ==========
@@ -1013,18 +1055,27 @@
                   stash_comment opt_sep opt_list END
                   {
                     if (! ($$ = parser.make_unwind_command ($1, $4, $8, $9, $2, $6)))
-                      ABORT_PARSE;
+                      {
+                        // make_unwind_command deleted $4 and $8.
+                        ABORT_PARSE;
+                      }
                   }
                 | TRY stash_comment opt_sep opt_list CATCH stash_comment
                   opt_sep opt_list END
                   {
                     if (! ($$ = parser.make_try_command ($1, $4, $7, $8, $9, $2, $6)))
-                      ABORT_PARSE;
+                      {
+                        // make_try_command deleted $4 and $8.
+                        ABORT_PARSE;
+                      }
                   }
                 | TRY stash_comment opt_sep opt_list END
                   {
                     if (! ($$ = parser.make_try_command ($1, $4, 0, 0, $5, $2, 0)))
-                      ABORT_PARSE;
+                      {
+                        // make_try_command deleted $4.
+                        ABORT_PARSE;
+                      }
                   }
                 ;
 
@@ -1106,7 +1157,10 @@
                         $$ = $1;
                       }
                     else
-                      ABORT_PARSE;
+                      {
+                        delete $1;
+                        ABORT_PARSE;
+                      }
                   }
                 ;
 
@@ -1148,7 +1202,10 @@
                     if (tmp->validate (tree_parameter_list::out))
                       $$ = tmp;
                     else
-                      ABORT_PARSE;
+                      {
+                        delete tmp;
+                        ABORT_PARSE;
+                      }
                   }
                 | '[' return_list1 ']'
                   {
@@ -1160,7 +1217,10 @@
                     if ($2->validate (tree_parameter_list::out))
                       $$ = $2;
                     else
-                      ABORT_PARSE;
+                      {
+                        delete $2;
+                        ABORT_PARSE;
+                      }
                   }
                 ;
 
@@ -1259,8 +1319,7 @@
 
                     delete $1;
 
-                    if (! ($$ = parser.frob_function (fname, $2)))
-                      ABORT_PARSE;
+                    $$ = parser.frob_function (fname, $2);
                   }
                 ;
 
@@ -2249,6 +2308,11 @@
       retval = new tree_unwind_protect_command (body, cleanup_stmts,
                                                 lc, mc, tc, l, c);
     }
+  else
+    {
+      delete body;
+      delete cleanup_stmts;
+    }
 
   return retval;
 }
@@ -2295,6 +2359,11 @@
       retval = new tree_try_catch_command (body, cleanup_stmts, id,
                                            lc, mc, tc, l, c);
     }
+  else
+    {
+      delete body;
+      delete cleanup_stmts;
+    }
 
   return retval;
 }
@@ -2323,6 +2392,11 @@
 
       retval = new tree_while_command (expr, body, lc, tc, l, c);
     }
+  else
+    {
+      delete expr;
+      delete body;
+    }
 
   return retval;
 }
@@ -2335,8 +2409,6 @@
                                            tree_expression *expr,
                                            octave_comment_list *lc)
 {
-  tree_command *retval = 0;
-
   maybe_warn_assign_as_truth_value (expr);
 
   octave_comment_list *tc = octave_comment_buffer::get_comment ();
@@ -2346,9 +2418,7 @@
   int l = until_tok->line ();
   int c = until_tok->column ();
 
-  retval = new tree_do_until_command (expr, body, lc, tc, l, c);
-
-  return retval;
+  return new tree_do_until_command (expr, body, lc, tc, l, c);
 }
 
 // Build a for command.
@@ -2393,6 +2463,13 @@
                                                    lc, tc, l, c);
         }
     }
+  else
+    {
+      delete lhs;
+      delete expr;
+      delete maxproc;
+      delete body;
+    }
 
   return retval;
 }
@@ -2402,14 +2479,10 @@
 tree_command *
 octave_base_parser::make_break_command (token *break_tok)
 {
-  tree_command *retval = 0;
-
   int l = break_tok->line ();
   int c = break_tok->column ();
 
-  retval = new tree_break_command (l, c);
-
-  return retval;
+  return new tree_break_command (l, c);
 }
 
 // Build a continue command.
@@ -2417,14 +2490,10 @@
 tree_command *
 octave_base_parser::make_continue_command (token *continue_tok)
 {
-  tree_command *retval = 0;
-
   int l = continue_tok->line ();
   int c = continue_tok->column ();
 
-  retval = new tree_continue_command (l, c);
-
-  return retval;
+  return new tree_continue_command (l, c);
 }
 
 // Build a return command.
@@ -2432,14 +2501,10 @@
 tree_command *
 octave_base_parser::make_return_command (token *return_tok)
 {
-  tree_command *retval = 0;
-
   int l = return_tok->line ();
   int c = return_tok->column ();
 
-  retval = new tree_return_command (l, c);
-
-  return retval;
+  return new tree_return_command (l, c);
 }
 
 // Start an if command.
@@ -2485,6 +2550,8 @@
 
       retval = new tree_if_command (list, lc, tc, l, c);
     }
+  else
+    delete list;
 
   return retval;
 }
@@ -2536,6 +2603,11 @@
 
       retval = new tree_switch_command (expr, list, lc, tc, l, c);
     }
+  else
+    {
+      delete expr;
+      delete list;
+    }
 
   return retval;
 }
@@ -2917,6 +2989,10 @@
   if (args && args->has_magic_tilde ())
     {
       bison_error ("invalid use of empty argument (~) in index expression");
+
+      delete expr;
+      delete args;
+
       return retval;
     }