[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ‘void free(void*)’ called on unallocated object ‘yyssa’ [-Wfree-nonh
From: |
Akim Demaille |
Subject: |
Re: ‘void free(void*)’ called on unallocated object ‘yyssa’ [-Wfree-nonheap-object] |
Date: |
Tue, 19 Jan 2021 06:40:52 +0100 |
[Paul, at the bottom of this message we have a warning from GCC11
that I guess you already had to keep quiet.]
Hi Christoph,
> Le 18 janv. 2021 à 22:01, Christoph Grüninger <foss@grueninger.de> a écrit :
>
> Dear Bison community,
> while compiling CMake using GCC 11 (not yet released), I came across several
> -Wfree-nonheap-object warnings. They came from a file generated by GNU Bison
> 3.4.2. [1]
>
> I was hoping the error might be fixed in a newer version, so
> 1. I downloaded your latest release 3.7.4
> 2. Re-generated the file cmCommandArgumentParser.y with
> bison --yacc --name-prefix=cmCommandArgument_yy
> --defines=cmCommandArgumentParserTokens.h -ocmCommandArgumentParser.cxx
> cmCommandArgumentParser.y
It makes little sense to use --yacc while using Bison features. Why
would you do that? Bison generates warnings for Bison features used
in Yacc mode.
> 3. I removed the lines 1717 and 1745 as the label yyerrlab1 must be defined.
Could you please clarify what you are doing here, and why?
> 4. I recompiled CMake and get the following error:
> Scanning dependencies of target CMakeLib
> [ 54%] Building CXX object
> Source/CMakeFiles/CMakeLib.dir/LexerParser/cmCommandArgumentParser.cxx.o
> cmCommandArgumentParser.cxx: In function ‘int
> cmCommandArgument_yyparse(yyscan_t)’:
> cmCommandArgumentParser.cxx:1838:18: warning: ‘void free(void*)’ called on
> unallocated object ‘yyssa’ [-Wfree-nonheap-object]
> cmCommandArgumentParser.cxx:1203:16: note: declared here
>
> I attached both the .y and he generated .cxx file.
>
> Is this a known issue?
Nope.
> Is the GCC 11 warning wrong (false positive)? I assume not, as yyssa is an
> array:
> yy_state_t yyssa[YYINITDEPTH];
>
> Can you change Bison that it will generate code that behaves correctly?
You can't seriously expect code used in the wild for many years to be
calling free on a stack-allocated value...
GCC 11 is wrong here. The full story (taken from your file) is:
> // Create.
> yy_state_t yyssa[YYINITDEPTH];
> yy_state_t *yyss = yyssa;
> [...]
> // Grow.
> yystacksize *= 2;
> {
> yy_state_t *yyss1 = yyss;
> union yyalloc *yyptr =
> YY_CAST (union yyalloc *,
> YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES
> (yystacksize))));
> if (! yyptr)
> goto yyexhaustedlab;
> YYSTACK_RELOCATE (yyss_alloc, yyss);
> if (yyss1 != yyssa)
> YYSTACK_FREE (yyss1);
> }
> [...]
> // Clean up
> if (yyss != yyssa)
> YYSTACK_FREE (yyss);
Or, in words, we use a stack-allocated stack until it's too small and
then we use a heap-allocated stack, and in that case, and that case
only, we free it at the end. Said another way: we never ever call
free(yyssa).
So GCC's warning is a false positive.
This is probably the kind of annoying warnings that Paul knows how
to defeat. I would use pragmas, but maybe there is something more
clever to do? Thanks in advance Paul!
Cheers!