On Fri, 27 Jul 2007, Joel E. Denny wrote: > On Fri, 27 Jul 2007, Brandon Lucia wrote: > > > I've been using the push_parse features in 2.3a+ HEAD from cvs and I think > > I've discovered a memory leak. > > Thanks for the bug report. Are you finding that this yyss memory leak > only occurs when you call yypstate_delete while yypush_parse is still > returning YYPUSH_MORE?
I committed the following to fix the above scenario. > If you are finding that it happens even after the > parse completes (syntax error, success, or even memory exhaustion) As far as I can tell, the above scenario never happens. Please let us know if you find any other problems. Push parsing definitely needs more testing... especially in scenarios that, like yours, are impossible for pull parsing. Index: ChangeLog =================================================================== RCS file: /sources/bison/bison/ChangeLog,v retrieving revision 1.1713 diff -p -u -r1.1713 ChangeLog --- ChangeLog 17 Jul 2007 06:56:35 -0000 1.1713 +++ ChangeLog 28 Jul 2007 04:22:07 -0000 @@ -1,3 +1,15 @@ +2007-07-27 Joel E. Denny <[EMAIL PROTECTED]> + + Fix push parsing memory leak reported by Brandon Lucia at + <http://lists.gnu.org/archive/html/bug-bison/2007-07/msg00032.html>. + * THANKS: Add Brandon Lucia. + * data/push.c (yypstate_delete): Free the stack if it was reallocated + but the parse never completed and thus freed it. + * tests/Makefile.am (TESTSUITE_AT): Add push.at. + * tests/testsuite.at: Include push.at. + * test/push.at: New. + (Push Parsing: Memory Leak for Early Deletion): New test case. + 2007-07-17 Joel E. Denny <[EMAIL PROTECTED]> Improve handling of multiple S/R conflicts in the same state and of S/R Index: THANKS =================================================================== RCS file: /sources/bison/bison/THANKS,v retrieving revision 1.74 diff -p -u -r1.74 THANKS --- THANKS 26 May 2007 19:10:43 -0000 1.74 +++ THANKS 28 Jul 2007 04:22:07 -0000 @@ -15,6 +15,7 @@ Baron Schwartz [EMAIL PROTECTED] Benoit Perrot [EMAIL PROTECTED] Bert Deknuydt [EMAIL PROTECTED] Bob Rossi [EMAIL PROTECTED] +Brandon Lucia [EMAIL PROTECTED] Bruce Lilly [EMAIL PROTECTED] Bruno Haible [EMAIL PROTECTED] Charles-Henri de Boysson [EMAIL PROTECTED] Index: data/push.c =================================================================== RCS file: /sources/bison/bison/data/push.c,v retrieving revision 1.38 diff -p -u -r1.38 push.c --- data/push.c 24 Feb 2007 05:43:35 -0000 1.38 +++ data/push.c 28 Jul 2007 04:22:07 -0000 @@ -1124,6 +1124,12 @@ b4_push_if( ]b4_c_function_def([[yypstate_delete]], [[void]], [[[yypstate *yyps]], [[yyps]]])[ { +#ifndef yyoverflow + /* If the stack was reallocated but the parse did not complete, then the + stack still needs to be freed. */ + if (!yyps->yynew && yyps->yyss != yyps->yyssa) + YYSTACK_FREE (yyps->yyss); +#endif free (yyps); } Index: tests/Makefile.am =================================================================== RCS file: /sources/bison/bison/tests/Makefile.am,v retrieving revision 1.46 diff -p -u -r1.46 Makefile.am --- tests/Makefile.am 29 Jan 2007 10:54:42 -0000 1.46 +++ tests/Makefile.am 28 Jul 2007 04:22:07 -0000 @@ -53,7 +53,8 @@ TESTSUITE_AT = \ torture.at existing.at regression.at \ c++.at \ java.at \ - cxx-type.at glr-regression.at + cxx-type.at glr-regression.at \ + push.at TESTSUITE = $(srcdir)/testsuite Index: tests/push.at =================================================================== RCS file: tests/push.at diff -N tests/push.at --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tests/push.at 28 Jul 2007 04:22:07 -0000 @@ -0,0 +1,82 @@ +# Checking Push Parsing. -*- Autotest -*- +# Copyright (C) 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +AT_BANNER([[Push Parsing Tests]]) + +## ---------------------------------------------- ## +## Push Parsing: Memory Leak for Early Deletion. ## +## ---------------------------------------------- ## + +AT_SETUP([[Push Parsing: Memory Leak for Early Deletion]]) + +# Requires Valgrind. + +AT_DATA_GRAMMAR([[input.y]], +[[ +%{ + #include <assert.h> + #include <stdio.h> + #define YYINITDEPTH 1 + void yyerror (char const *msg); +%} + +%pure-parser %push-parser + +%% + +start: 'a' 'b' 'c' ; + +%% + +void +yyerror (char const *msg) +{ + fprintf (stderr, "%s\n", msg); +} + +int +main (void) +{ + yypstate *yyps; + YYSTYPE yylval; + + /* Make sure we don't try to free yyps->yyss in this case. */ + yyps = yypstate_new (); + yypstate_delete (yyps); + + /* yypstate_delete used to leak yyps->yyss if the stack was reallocated but + the parse did not return on success, syntax error, or memory + exhaustion. */ + yyps = yypstate_new (); + assert (yypush_parse (yyps, 'a', &yylval) == YYPUSH_MORE); + yypstate_delete (yyps); + + yyps = yypstate_new (); + assert (yypush_parse (yyps, 'a', &yylval) == YYPUSH_MORE); + assert (yypush_parse (yyps, 'b', &yylval) == YYPUSH_MORE); + yypstate_delete (yyps); + + return 0; +} +]]) + +AT_CHECK([[bison -o input.c input.y]]) +AT_COMPILE([[input]]) +AT_PARSER_CHECK([[./input]]) + +AT_CLEANUP Index: tests/testsuite.at =================================================================== RCS file: /sources/bison/bison/tests/testsuite.at,v retrieving revision 1.34 diff -p -u -r1.34 testsuite.at --- tests/testsuite.at 29 Jan 2007 10:54:42 -0000 1.34 +++ tests/testsuite.at 28 Jul 2007 04:22:07 -0000 @@ -80,5 +80,8 @@ m4_include([cxx-type.at]) # Regression tests m4_include([glr-regression.at]) +# Push parsing specific tests. +m4_include([push.at]) + m4_popdef([AT_CHECK]) m4_popdef([ORIGINAL_AT_CHECK])
