From e1197fcc3d0576022a1856df500f9a57448527d9 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 16 Jan 2020 05:59:12 +0100 Subject: [PATCH] yacc.c: portability to G++ 4.8 Currently we get warnings with GCC 4.8 when running the maintainer-check-g++ tests: 143. skeletons.at:85: testing Installed skeleton file names ... ../../tests/skeletons.at:120: COLUMNS=1000; export COLUMNS; bison --color=no -fno-caret --skeleton=yacc.c -o input-cmd-line.c input-cmd-line.y ../../tests/skeletons.at:121: $CC $CFLAGS $CPPFLAGS $LDFLAGS -o input-cmd-line input-cmd-line.c $LIBS stderr: input-cmd-line.c: In function 'int yysyntax_error(long int*, char**, const yyparse_context_t*)': input-cmd-line.c:977:52: error: conversion to 'int' from 'long int' may alter its value [-Werror=conversion] YYSIZEOF (yyarg) / YYSIZEOF (*yyarg)); ^ cc1plus: all warnings being treated as errors stdout: ../../tests/skeletons.at:121: exit code was 1, expected 0 and 429. calc.at:823: testing Calculator parse.error=custom %locations api.prefix={calc} ... ../../tests/calc.at:823: COLUMNS=1000; export COLUMNS; bison --color=no -fno-caret -Wno-deprecated -o calc.c calc.y ../../tests/calc.at:823: $CC $CFLAGS $CPPFLAGS $LDFLAGS -o calc calc.c $LIBS stderr: calc.y: In function 'int yyreport_syntax_error(const yyparse_context_t*)': calc.y:157:58: error: conversion to 'int' from 'long unsigned int' may alter its value [-Werror=conversion] int n = yysyntax_error_arguments (ctx, arg, sizeof arg / sizeof *arg); ^ cc1plus: all warnings being treated as errors stdout: ../../tests/calc.at:823: exit code was 1, expected 0 We could use a cast to avoid the warning, but it becomes too cluttered. We can also use YYPTRDIFF_T, but that forces the user to use YYPTRDIFF_T too, although this is an array of tokens, which is limited by YYNTOKENS, an int. So let's completely avoid this warning. * data/skeletons/yacc.c, tests/local.at (yyreport_syntax_error): Avoid relying on sizeof to compute the array capacity. --- data/skeletons/yacc.c | 24 +++++++++--------------- tests/local.at | 2 +- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c index d71d44e1..23f078f4 100644 --- a/data/skeletons/yacc.c +++ b/data/skeletons/yacc.c @@ -1057,10 +1057,10 @@ yy_lac (yy_state_t *yyesa, yy_state_t **yyes, YYPTRDIFF_T *yyes_capacity_p;]])[ } yyparse_context_t; -/* Put in YYARG at most YYARGN of the expected tokens given - the current YYCTX, and return the number of tokens stored - in YYARG. - If YYARG is null, return the number of expected tokens. */ +/* Put in YYARG at most YYARGN of the expected tokens given the + current YYCTX, and return the number of tokens stored in YYARG. If + YYARG is null, return the number of expected tokens (guaranteed to + be less than YYNTOKENS). */ static int yyexpected_tokens (const yyparse_context_t *yyctx, int yyarg[], int yyargn) @@ -1286,20 +1286,14 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ int yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Actual size of YYARG. */ - int yycount = 0; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; - { - int yyn - = yysyntax_error_arguments (yyctx, yyarg, - YYSIZEOF (yyarg) / YYSIZEOF (*yyarg)); - if (yyn == -2) - return 2; - else - yycount = yyn; - } + /* Actual size of YYARG. */ + int yycount + = yysyntax_error_arguments (yyctx, yyarg, YYERROR_VERBOSE_ARGS_MAXIMUM); + if (yycount == -2) + return 2; switch (yycount) { diff --git a/tests/local.at b/tests/local.at index 30062a2e..ee5beddf 100644 --- a/tests/local.at +++ b/tests/local.at @@ -615,7 +615,7 @@ yyreport_syntax_error (const yyparse_context_t *ctx]AT_PARAM_IF([, AT_PARSE_PARA /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ int arg[YYNTOKENS]; - int n = yysyntax_error_arguments (ctx, arg, sizeof arg / sizeof *arg);]AT_PARAM_IF([m4_bpatsubst(m4_defn([AT_PARSE_PARAMS]), + int n = yysyntax_error_arguments (ctx, arg, YYNTOKENS);]AT_PARAM_IF([m4_bpatsubst(m4_defn([AT_PARSE_PARAMS]), [[^,]+[^A-Za-z_0-9]\([A-Za-z_][A-Za-z_0-9]*\),* *], [ YYUSE (\1);])])[]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[ ++global_nerrs;