Merge branch 'maint'

* origin/maint:
  NEWS: warnings with clang
  warnings: avoid warnings from clang
  tests: no longer disable -O compiler options
  yacc.c: initialize yylval in pure-parser mode
  skeletons: style changes
  lalr1.cc: document exception safety
  lalr1.cc: check exception safety of error handling
  lalr1.cc: check (and fix) %printer exception safety
  lalr1.cc: check (and fix) %initial-action exception safety
  lalr1.cc: fix exception safety
  lalr1.cc: check exception safety.
  lalr1.cc: indentation fixes.
  lalr1.cc: don't leave macros define to nothing
  tests: minor improvements
  tests: use $PERL instead of perl
  build: look for Perl in configure.
  tests: fix sed portability issues
  tests: diff -u is not portable

Conflicts:
	data/c.m4
	data/glr.c
	data/lalr1.cc
	data/yacc.c
	doc/Makefile.am
	tests/atlocal.in
	tests/calc.at
This commit is contained in:
Akim Demaille
2012-10-10 17:31:25 +02:00
18 changed files with 388 additions and 71 deletions

View File

@@ -29,16 +29,10 @@ CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@"
# Is the compiler GCC?
GCC='@GCC@'
# We want no optimization, as they uncover warnings (therefore,
# failures) about uninitialized variables in the test suite. FIXME:
# fix the warnings, not the flags.
O0CFLAGS=`echo '@CFLAGS@' | sed 's/-O[0-9s] *//g'`
O0CXXFLAGS=`echo '@CXXFLAGS@' | sed 's/-O[0-9s] *//g'`
# Sometimes a test group needs to ignore gcc warnings, so it locally
# sets CFLAGS to this.
NO_WERROR_CFLAGS="$O0CFLAGS @WARN_CFLAGS@ @WARN_CFLAGS_TEST@"
NO_WERROR_CXXFLAGS="$O0CXXFLAGS @WARN_CXXFLAGS@ @WARN_CXXFLAGS_TEST@"
NO_WERROR_CFLAGS='@CFLAGS@ @WARN_CFLAGS@ @WARN_CFLAGS_TEST@'
NO_WERROR_CXXFLAGS='@CXXFLAGS@ @WARN_CXXFLAGS@ @WARN_CXXFLAGS_TEST@'
# But most of the time, we want -Werror.
CFLAGS="$NO_WERROR_CFLAGS @WERROR_CFLAGS@"
@@ -51,7 +45,6 @@ BISON_CXX_WORKS='@BISON_CXX_WORKS@'
if "$at_arg_compile_c_with_cxx"; then
CC_IS_CXX=1
CC=$CXX
O0CFLAGS=$O0CXXFLAGS
NO_WERROR_CFLAGS=$NO_WERROR_CXXFLAGS
CFLAGS=$CXXFLAGS
else
@@ -63,21 +56,12 @@ fi
## Other. ##
## ------- ##
# Are special link options needed?
LDFLAGS='@LDFLAGS@'
# Are special libraries needed?
LIBS="$abs_top_builddir/lib/libbison.a @LIBS@ @INTLLIBS@"
# Empty if no javac was found
CONF_JAVAC='@CONF_JAVAC@'
# Empty if no Java VM was found
CONF_JAVA='@CONF_JAVA@'
# Empty if no xsltproc was found
: ${XSLTPROC='@XSLTPROC@'}
# We need egrep and perl.
: ${EGREP='@EGREP@'}
: ${PERL='@PERL@'}
@@ -86,6 +70,15 @@ CONF_JAVA='@CONF_JAVA@'
LC_CTYPE=C
export LC_CTYPE
# Are special link options needed?
LDFLAGS='@LDFLAGS@'
# Are special libraries needed?
LIBS="$abs_top_builddir/lib/libbison.a @LIBS@ @INTLLIBS@"
# Empty if no xsltproc was found
: ${XSLTPROC='@XSLTPROC@'}
# Handle --compile-c-with-cxx here, once CXX and CXXFLAGS are known.
if "$at_arg_compile_c_with_cxx"; then

View File

@@ -1,4 +1,4 @@
# Checking the output filenames. -*- Autotest -*-
# Checking the C++ Features. -*- Autotest -*-
# Copyright (C) 2004-2005, 2007-2012 Free Software Foundation, Inc.
@@ -216,6 +216,7 @@ m4_define([AT_CHECK_DOXYGEN],
[m4_fatal([invalid argument: $1])])
AT_SETUP([Doxygen $1 Documentation])
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
AT_DATA([input.yy],
[[%skeleton "lalr1.cc"
%locations
@@ -224,10 +225,7 @@ AT_DATA([input.yy],
%%
exp:;
%%
yy::parser::error (const location& l, const std::string& m)
{
std::cerr << l << s << std::endl;
}
]AT_YYERROR_DEFINE[
]])
AT_BISON_CHECK([-o input.cc input.yy], 0)
@@ -280,6 +278,7 @@ EXTRACT_STATIC = AT_DOXYGEN_PRIVATE
AT_CHECK([doxygen --version || exit 77], 0, ignore)
AT_CHECK([doxygen], 0, [], [ignore])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
m4_popdef([AT_DOXYGEN_PRIVATE])
@@ -531,3 +530,236 @@ caught error
]])
AT_CLEANUP
## ------------------ ##
## Exception safety. ##
## ------------------ ##
AT_SETUP([[Exception safety]])
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
AT_DATA_GRAMMAR([[input.yy]],
[[%skeleton "lalr1.cc"
%defines // FIXME: Mandated in 2.6.
%debug
%error-verbose
%code requires
{
#include <cassert>
#include <cstdlib> // size_t and getenv.
#include <iostream>
#include <list>
bool debug = false;
/// A class that counts its number of instances.
struct Object
{
typedef std::list<const Object*> objects;
static objects instances;
char val;
static bool
empty ()
{
return instances.empty();
}
static void
log (Object const *o, const std::string& msg)
{
if (debug)
{
if (o)
std::cerr << o << "->";
std::cerr << msg << " {";
const char* sep = " ";
for (objects::const_iterator i = instances.begin(),
i_end = instances.end();
i != i_end;
++i)
{
std::cerr << sep << *i;
sep = ", ";
}
std::cerr << " }" << std::endl;
}
}
Object (char v)
: val (v)
{
instances.push_back(this);
log (this, "Object::Object");
}
~Object ()
{
instances.remove(this);
log (this, "Object::~Object");
}
};
}
%code
{
#include <cassert>
#include <cstring> // strchr
#include <stdexcept>
int yylex (yy::parser::semantic_type *);
Object::objects Object::instances;
static char const *input;
}
%union
{
Object *obj;
}
%initial-action
{
if (strchr (input, 'i'))
throw std::runtime_error ("initial-action");
}
%destructor { delete $$; } <obj>;
%printer
{
yyo << $$ << " '" << $$->val << '\'';
if ($$->val == 'p')
throw std::runtime_error ("printer");
} <obj>;
%token <obj> 'a' 'E' 'e' 'p' 'R' 's' 'T'
%type <obj> list item
%%
start: list { delete $1; };
list:
item { $$ = $1; }
| item list { $$ = $1; delete $2; } // Right recursion to load the stack.
;
item:
'a' { $$ = $1; }
| 'e' { YYUSE ($$); YYUSE($1); error ("syntax error"); }
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and
// then the stack is emptied, defeating the point of the test.
| 'E' 'a' { YYUSE($1); $$ = $2; }
| 'R' { $$ = YY_NULL; delete $1; YYERROR; }
| 'p' { $$ = $1; }
| 's' { $$ = $1; throw std::runtime_error ("reduction"); }
| 'T' { $$ = YY_NULL; delete $1; YYABORT; }
| error { $$ = YY_NULL; yyerrok; }
;
%%
int
yylex (yy::parser::semantic_type *lvalp)
{
// 'a': no error.
// 'e': user action calls error.
// 'E': syntax error, with yyerror that throws.
// 'i': initial action throws.
// 'l': yylex throws.
// 'R': call YYERROR in the action
// 's': reduction throws.
// 'T': call YYABORT in the action
switch (int res = *input++)
{
case 'l':
throw std::runtime_error ("yylex");
default:
lvalp->obj = new Object (res);
// Fall through.
case 0:
return res;
}
}
/* A C++ error reporting function. */
void
yy::parser::error (const std::string& m)
{
throw std::runtime_error (m);
}
int
main (int argc, const char *argv[])
{
switch (argc)
{
case 2:
input = argv[1];
break;
case 3:
assert (!strcmp (argv[1], "--debug"));
debug = 1;
input = argv[2];
break;
default:
abort ();
}
yy::parser parser;
debug |= !!getenv ("YYDEBUG");
parser.set_debug_level (debug);
int res = 2;
try
{
res = parser.parse ();
}
catch (const std::exception& e)
{
std::cerr << "exception caught: " << e.what () << std::endl;
}
catch (...)
{
std::cerr << "unknown exception caught" << std::endl;
}
Object::log (YY_NULL, "end");
assert (Object::empty());
return res;
}
]])
AT_BISON_CHECK([[-o input.cc --report=all input.yy]])
AT_COMPILE_CXX([[input]])
AT_PARSER_CHECK([[./input aaaas]], [[2]], [[]],
[[exception caught: reduction
]])
AT_PARSER_CHECK([[./input aaaal]], [[2]], [[]],
[[exception caught: yylex
]])
AT_PARSER_CHECK([[./input i]], [[2]], [[]],
[[exception caught: initial-action
]])
AT_PARSER_CHECK([[./input aaaap]])
AT_PARSER_CHECK([[./input --debug aaaap]], [[2]], [[]], [[stderr]])
AT_PARSER_CHECK([[grep '^exception caught: printer$' stderr]], [], [ignore])
AT_PARSER_CHECK([[./input aaaae]], [[2]], [[]],
[[exception caught: syntax error
]])
AT_PARSER_CHECK([[./input aaaaE]], [[2]], [[]],
[[exception caught: syntax error, unexpected $end, expecting 'a'
]])
AT_PARSER_CHECK([[./input aaaaT]], [[1]])
# There is error-recovery, so exit success.
AT_PARSER_CHECK([[./input aaaaR]], [[0]])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP

View File

@@ -503,14 +503,17 @@ AT_CHECK([cat stderr], 0, [expout])
# Make sure we did not introduce bad spaces. Checked here because all
# the skeletons are (or should be) exercized here.
m4_define([AT_CHECK_SPACES],
[# No initial empty lines.
AT_CHECK([sed -ne '/./q;=;p;' $1])
# No trailing spaces.
AT_CHECK([sed -ne '/[ ]$/{=;p;}' $1])
# No tabulations.
AT_CHECK([sed -ne '/[ ]/{=;p;}' $1])
# No final empty lines.
AT_CHECK([sed -ne '${/^$/{=;p;};}' $1])
[AT_CHECK([$PERL -ne '
chomp;
print "$.: {$_}\n"
if (# No starting/ending empty lines.
(eof || $. == 1) && /^\s*$/
# No trailing space.
|| /\s$/
# No tabs.
|| /\t/
)' $1
])dnl
])

View File

@@ -35,7 +35,10 @@ dnl time comes, just use sed to drop the line numbers. For now, as LR(1)
dnl support is rapidly evolving, let's keep that information to be careful.
dnl However, we don't do diffs for canonical LR(1) because the diff is huge.
m4_pushdef([AT_LALR1_DIFF_CHECK],
[AT_CHECK([[sed 's/^%define lr.type .*$//' input.y > input-lalr.y]])
[dnl We need diff -u, which is not portable.
AT_CHECK([diff -u /dev/null /dev/null || exit 77], [0], [ignore])
AT_CHECK([[sed 's/^%define lr.type .*$//' input.y > input-lalr.y]])
AT_BISON_CHECK([[--report=all input-lalr.y]], [[0]], [ignore], [ignore])
AT_CHECK([[diff -u input-lalr.output input.output \
| sed -n '/^@@/,$p' | sed 's/^ $//']],

View File

@@ -1321,7 +1321,7 @@ AT_DATA([empty.y],
start: '';
start: '
]])
AT_CHECK([[perl -e "print 'start: \'';" >> empty.y || exit 77]])
AT_CHECK([[$PERL -e "print 'start: \'';" >> empty.y || exit 77]])
AT_BISON_CHECK([empty.y], [1], [],
[[empty.y:2.8-9: warning: empty character literal [-Wother]
@@ -1336,7 +1336,7 @@ AT_DATA([two.y],
start: 'ab';
start: 'ab
]])
AT_CHECK([[perl -e "print 'start: \'ab';" >> two.y || exit 77]])
AT_CHECK([[$PERL -e "print 'start: \'ab';" >> two.y || exit 77]])
AT_BISON_CHECK([two.y], [1], [],
[[two.y:2.8-11: warning: extra characters in character literal [-Wother]
@@ -1351,7 +1351,7 @@ AT_DATA([three.y],
start: 'abc';
start: 'abc
]])
AT_CHECK([[perl -e "print 'start: \'abc';" >> three.y || exit 77]])
AT_CHECK([[$PERL -e "print 'start: \'abc';" >> three.y || exit 77]])
AT_BISON_CHECK([three.y], [1], [],
[[three.y:2.8-12: warning: extra characters in character literal [-Wother]
@@ -1380,7 +1380,7 @@ start: '\777' '\0' '\xfff' '\x0'
# Beside we cannot even expect "echo '\0'" to output two characters
# (well three with \n): at least Bash 3.2 converts the two-character
# sequence "\0" into a single NUL character.
AT_CHECK([[perl -e 'print "start: \"\\\t\\\f\\\0\\\1\" ;";' >> input.y \
AT_CHECK([[$PERL -e 'print "start: \"\\\t\\\f\\\0\\\1\" ;";' >> input.y \
|| exit 77]])
AT_BISON_CHECK([input.y], [1], [],

View File

@@ -38,7 +38,7 @@ m4_define([m4_null_if],
# Expect COUNT matches of the PERL-REGEXP in FILE. The file is
# taken in "slurp" mode, i.e., one can match end-of-lines.
m4_define([AT_MATCHES_CHECK],
[AT_CHECK([perl -0777 -ne '
[AT_CHECK([$PERL -0777 -ne '
my $count = 0;
s{$2}{ ++$count; "" }gem;
printf "$count\n";' $1], [0], [$3
@@ -408,7 +408,8 @@ void
public void yyerror (String s)
{
System.err.println (s);
}]])])dnl
}]])],
[m4_fatal([$0: invalid language: ]AT_LANG)])dnl
])

View File

@@ -1474,17 +1474,17 @@ AT_CHECK([[grep 'syntax error,' stderr.txt]], [[0]],
# Check number of default reductions in inconsistent states to be sure
# syntax error is detected before unnecessary reductions are performed.
AT_CHECK([[perl -0777 -ne 'print s/inconsistent default reduction//g;' \
AT_CHECK([[$PERL -0777 -ne 'print s/inconsistent default reduction//g;' \
< stdout.txt || exit 77]], [[0]], [[14]])
# Check number of default reductions in consistent states to be sure
# it is performed before the syntax error is detected.
AT_CHECK([[perl -0777 -ne 'print s/\bconsistent default reduction//g;' \
AT_CHECK([[$PERL -0777 -ne 'print s/\bconsistent default reduction//g;' \
< stdout.txt || exit 77]], [[0]], [[2]])
# Check number of reallocs to be sure reallocated memory isn't somehow
# lost between LAC invocations.
AT_CHECK([[perl -0777 -ne 'print s/\(realloc//g;' < stderr.txt \
AT_CHECK([[$PERL -0777 -ne 'print s/\(realloc//g;' < stderr.txt \
|| exit 77]], [[0]], [[3]])
AT_BISON_OPTION_POPDEFS

View File

@@ -315,7 +315,7 @@ print '@output(@,@)', "\n";
(print "garbage"x10, "\n") for (1..1000);
print "${M4}_divert_pop(0)\n";
]])
AT_CHECK([[perl gen-skel.pl > skel.c || exit 77]])
AT_CHECK([[$PERL gen-skel.pl > skel.c || exit 77]])
AT_DATA([[input.y]],
[[%skeleton "./skel.c"

View File

@@ -64,7 +64,7 @@ m4_define([AT_SYNCLINES_COMPILE],
# distcc[35882] (dcc_connect_by_name) ERROR: failed to look up host "chrisimac": Unknown host
# distcc[35882] Warning: failed to distribute input.c to chrisimac/4, running locally instead
AT_CHECK([[perl -p -0777 - stderr <<\EOF
AT_CHECK([[$PERL -p -0777 - stderr <<\EOF
s/^distcc\[\d+\] .*\n//gm;
s/^([^:]+:\d+)[.:][^:]+:(.+)$/$][1:$][2/gm;
s/^([^:]+:\d+):[^#]*( #error)/$][1:$][2/gm;

View File

@@ -125,7 +125,7 @@ EOF
]])
AT_BISON_OPTION_POPDEFS
AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
AT_CHECK([$PERL -w ./gengram.pl $2 || exit 77], 0, [stdout])
mv stdout $1
])
@@ -214,7 +214,7 @@ main (void)
EOF
]])
AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
AT_CHECK([$PERL -w ./gengram.pl $2 || exit 77], 0, [stdout])
mv stdout $1
AT_BISON_OPTION_POPDEFS
])
@@ -350,7 +350,7 @@ main (void)
EOF
]])
AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
AT_CHECK([$PERL -w ./gengram.pl $2 || exit 77], 0, [stdout])
mv stdout $1
AT_BISON_OPTION_POPDEFS
])