Suppress "unused variable" warnings with older versions of flex.

Versions of flex before 2.5.36 might generate code that results in an
"unused variable" warning, when using %option reentrant.  Historically
we've worked around that by specifying -Wno-error, but that's an
unsatisfying solution.  The official "fix" for this was just to insert a
dummy reference to the variable, so write a small perl script that edits
the generated C code similarly.

The MSVC side of this is untested, but the buildfarm should soon reveal
if I broke that.

Discussion: https://postgr.es/m/25456.1487437842@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2017-02-19 13:04:30 -05:00
parent a3dc8e495b
commit 65d508fd4d
6 changed files with 82 additions and 23 deletions

View File

@ -627,6 +627,7 @@ TAS = @TAS@
ifdef FLEX
$(FLEX) $(if $(FLEX_NO_BACKUP),-b) $(FLEXFLAGS) -o'$@' $<
@$(if $(FLEX_NO_BACKUP),if [ `wc -l <lex.backup` -eq 1 ]; then rm lex.backup; else echo "Scanner requires backup; see lex.backup." 1>&2; exit 1; fi)
$(if $(FLEX_FIX_WARNING),$(PERL) $(top_srcdir)/src/tools/fix-flex-warning.pl '$@')
else
@$(missing) flex $< '$@'
endif

View File

@ -20,12 +20,6 @@ OBJS= analyze.o gram.o scan.o parser.o \
include $(top_srcdir)/src/backend/common.mk
# Latest flex causes warnings in this file.
ifeq ($(GCC),yes)
scan.o: CFLAGS += -Wno-error
endif
# There is no correct way to write a rule that generates two files.
# Rules with two targets don't have that meaning, they are merely
# shorthand for two otherwise separate rules. To be safe for parallel
@ -41,6 +35,7 @@ gram.c: BISON_CHECK_CMD = $(PERL) $(srcdir)/check_keywords.pl $< $(top_srcdir)/s
scan.c: FLEXFLAGS = -CF -p -p
scan.c: FLEX_NO_BACKUP=yes
scan.c: FLEX_FIX_WARNING=yes
# Force these dependencies to be known even without dependency info built:

View File

@ -41,11 +41,7 @@ sql_help.h: create_help.pl $(wildcard $(REFDOCDIR)/*.sgml)
psqlscanslash.c: FLEXFLAGS = -Cfe -p -p
psqlscanslash.c: FLEX_NO_BACKUP=yes
# Latest flex causes warnings in this file.
ifeq ($(GCC),yes)
psqlscanslash.o: CFLAGS += -Wno-error
endif
psqlscanslash.c: FLEX_FIX_WARNING=yes
distprep: sql_help.h psqlscanslash.c

View File

@ -29,11 +29,7 @@ libpgfeutils.a: $(OBJS)
psqlscan.c: FLEXFLAGS = -Cfe -p -p
psqlscan.c: FLEX_NO_BACKUP=yes
# Latest flex causes warnings in this file.
ifeq ($(GCC),yes)
psqlscan.o: CFLAGS += -Wno-error
endif
psqlscan.c: FLEX_FIX_WARNING=yes
distprep: psqlscan.c

View File

@ -0,0 +1,65 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
#
# fix-flex-warning.pl
#
# flex versions before 2.5.36, with certain option combinations, produce
# code that causes an "unused variable" warning. That's annoying, so
# let's suppress it by inserting a dummy reference to the variable.
# (That's exactly what 2.5.36 and later do ...)
#
# Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# src/tools/fix-flex-warning.pl
#
#----------------------------------------------------------------------
use strict;
use warnings;
# Get command line argument.
usage() if $#ARGV != 0;
my $filename = shift;
# Suck in the whole file.
local $/ = undef;
my $cfile;
open($cfile, $filename) || die "opening $filename for reading: $!";
my $ccode = <$cfile>;
close($cfile);
# No need to do anything if it's not flex 2.5.x for x < 36.
exit 0 if $ccode !~ m/^#define YY_FLEX_MAJOR_VERSION 2$/m;
exit 0 if $ccode !~ m/^#define YY_FLEX_MINOR_VERSION 5$/m;
exit 0 if $ccode !~ m/^#define YY_FLEX_SUBMINOR_VERSION (\d+)$/m;
exit 0 if $1 >= 36;
# Apply the desired patch.
$ccode =~ s|(struct yyguts_t \* yyg = \(struct yyguts_t\*\)yyscanner; /\* This var may be unused depending upon options. \*/
.*?)
return yy_is_jam \? 0 : yy_current_state;
|$1
(void) yyg;
return yy_is_jam ? 0 : yy_current_state;
|s;
# Write the modified file back out.
open($cfile, ">$filename") || die "opening $filename for writing: $!";
print $cfile $ccode;
close($cfile);
exit 0;
sub usage
{
die <<EOM;
Usage: fix-flex-warning.pl c-file-name
fix-flex-warning.pl modifies a flex output file to suppress
an unused-variable warning that occurs with older flex versions.
Report bugs to <pgsql-bugs\@postgresql.org>.
EOM
}

View File

@ -51,23 +51,29 @@ my $flexflags = ($make =~ /^$basetarg:\s*FLEXFLAGS\s*=\s*(\S.*)/m ? $1 : '');
system("flex $flexflags -o$output $input");
if ($? == 0)
{
# For non-reentrant scanners we need to fix up the yywrap macro definition
# to keep the MS compiler happy.
# For reentrant scanners (like the core scanner) we do not
# need to (and must not) change the yywrap definition.
# Check for "%option reentrant" in .l file.
my $lfile;
open($lfile, $input) || die "opening $input for reading: $!";
my $lcode = <$lfile>;
close($lfile);
if ($lcode !~ /\%option\sreentrant/)
if ($lcode =~ /\%option\sreentrant/)
{
# Reentrant scanners usually need a fix to prevent
# "unused variable" warnings with older flex versions.
system("perl src\\tools\\fix-flex-warning.pl $output");
}
else
{
# For non-reentrant scanners we need to fix up the yywrap
# macro definition to keep the MS compiler happy.
# For reentrant scanners (like the core scanner) we do not
# need to (and must not) change the yywrap definition.
my $cfile;
open($cfile, $output) || die "opening $output for reading: $!";
my $ccode = <$cfile>;
close($cfile);
$ccode =~ s/yywrap\(n\)/yywrap()/;
open($cfile, ">$output") || die "opening $output for reading: $!";
open($cfile, ">$output") || die "opening $output for writing: $!";
print $cfile $ccode;
close($cfile);
}