Use “least” types for integers in Yacc tables

This changes the Yacc skeleton to use “least” integer types to
keep tables smaller on some platforms, which should lessen cache
pressure.  Since Bison uses the Yacc skeleton, it follows suit.
* data/skeletons/yacc.c: Include limits.h and stdint.h if this
seems to be needed.
(yytype_uint8, yytype_int8, yytype_uint16, yytype_int16):
If available, use GCC predefined macros __INT_MAX__ etc. to select
a “least” type, as this avoids namespace hassles.  Otherwise, if
available fall back on selecting a “least” type via the C99 macros
INT_MAX, INT_LEAST8_MAX, etc.  Otherwise, fall further back on one of
the builtin C99 types signed char, short, and int.  Make sure that
any selected type promotes to int.  Ignore any macros YYTYPE_INT16,
YYTYPE_INT8, YYTYPE_UINT16, YYTYPE_UINT8 defined by the user.
(ptrdiff_t, PTRDIFF_MAX): Simplify in the light of the above.
(yytype_uint8, yytype_uint16): Do not assume that unsigned char
and unsigned short promote to int, as this isn’t true on some
platforms (e.g., TI TMS320C55x).
* src/parse-gram.y (YYTYPE_INT16, YYTYPE_INT8, YYTYPE_UINT16)
(YYTYPE_UINT8): Remove, as these are no longer effective.
This commit is contained in:
Paul Eggert
2019-10-05 13:06:40 -07:00
parent 6373b90fc8
commit 5463291a91
4 changed files with 54 additions and 30 deletions

6
NEWS
View File

@@ -69,7 +69,11 @@ GNU Bison NEWS
Bison templates now prefer signed to unsigned integer types when
either will do, as the signed types are less error-prone and allow
for better checking with 'gcc -fsanitize=undefined'.
for better checking with 'gcc -fsanitize=undefined'. Also, the
types chosen are now portable to unusual machines where char, short and
int are all the same width. On non-GNU platforms this may entail
including <limits.h> and (if available) <stdint.h> to define integer types
and constants.
* Noteworthy changes in release 3.4.2 (2019-09-12) [stable]

View File

@@ -114,7 +114,7 @@ m4_ifset([b4_parse_param], [b4_args(b4_parse_param), ])])
# ---------------------
# Return a narrow int type able to handle numbers ranging from
# MIN to MAX (included). Overwrite the version from c.m4,
# so that the user can override the shorter types.
# so that the code can use C99 types if available.
m4_define([b4_int_type],
[m4_if(b4_ints_in($@, [-127], [127]), [1], [yytype_int8],
b4_ints_in($@, [0], [255]), [1], [yytype_uint8],
@@ -388,26 +388,54 @@ m4_if(b4_api_prefix, [yy], [],
# undef short
#endif
#ifdef YYTYPE_UINT8
typedef YYTYPE_UINT8 yytype_uint8;
#else
typedef unsigned char yytype_uint8;
/* On compilers that do not define __PTRDIFF_MAX__ etc., include
<limits.h> and (if available) <stdint.h> so that the code can
choose integer types of a good width. */
#ifndef __PTRDIFF_MAX__
# include <limits.h> /* INFRINGES ON USER NAME SPACE */
# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
# endif
#endif
#ifdef YYTYPE_INT8
typedef YYTYPE_INT8 yytype_int8;
/* Narrow types that promote to a signed type and that can represent a
signed or unsigned integer of at least N bits. In tables they can
save space and decrease cache pressure. Promoting to a signed type
helps avoid bugs in integer arithmetic. */
#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
#elif defined UINT_LEAST8_MAX && UINT_LEAST8_MAX <= INT_MAX
typedef uint_least8_t yytype_uint8;
#elif UCHAR_MAX <= INT_MAX
typedef unsigned char yytype_uint8;
#else
typedef short yytype_uint8;
#endif
#if defined __INT_LEAST8_MAX__ && __INT_LEAST8_MAX__ <= __INT_MAX__
typedef __INT_LEAST8_TYPE__ yytype_int8;
#elif defined INT_LEAST8_MAX && INT_LEAST8_MAX <= INT_MAX
typedef int_least8_t yytype_int8;
#else
typedef signed char yytype_int8;
#endif
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
typedef __UINT_LEAST16_TYPE__ yytype_uint16;
#elif defined UINT_LEAST16_MAX && UINT_LEAST16_MAX <= INT_MAX
typedef uint_least16_t yytype_uint16;
#elif USHRT_MAX <= INT_MAX
typedef unsigned short yytype_uint16;
#else
typedef int yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#if defined __INT_LEAST16_MAX__ && __INT_LEAST16_MAX__ <= __INT_MAX__
typedef __INT_LEAST16_TYPE__ yytype_int16;
#elif defined INT_LEAST16_MAX && INT_LEAST16_MAX <= INT_MAX
typedef int_least16_t yytype_int16;
#else
typedef short yytype_int16;
#endif
@@ -416,17 +444,14 @@ typedef short yytype_int16;
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
# define YYPTRDIFF_T __PTRDIFF_TYPE__
# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
# elif defined ptrdiff_t && defined PTRDIFF_MAX
# elif defined PTRDIFF_MAX
# ifndef ptrdiff_t
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# endif
# define YYPTRDIFF_T ptrdiff_t
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYPTRDIFF_T ptrdiff_t
# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
# else
# define YYPTRDIFF_T long
# include <limits.h> /* INFRINGES ON USER NAME SPACE */
# define YYPTRDIFF_MAXIMUM LONG_MAX
# endif
#endif

View File

@@ -1447,13 +1447,13 @@ anything other than their usual meanings.
In some cases the Bison parser implementation file includes system
headers, and in those cases your code should respect the identifiers
reserved by those headers. On some non-GNU hosts, @code{<alloca.h>},
@code{<malloc.h>}, @code{<stddef.h>}, and @code{<stdlib.h>} are
included as needed to declare memory allocators and related types.
reserved by those headers. On some non-GNU hosts, @code{<limits.h>},
@code{<stddef.h>}, @code{<stdint.h>} (if available), and @code{<stdlib.h>}
are included to declare memory allocators and integer types and constants.
@code{<libintl.h>} is included if message translation is in use
(@pxref{Internationalization}). Other system headers may be included
if you define @code{YYDEBUG} to a nonzero value (@pxref{Tracing,
,Tracing Your Parser}).
if you define @code{YYDEBUG} (@pxref{Tracing, ,Tracing Your Parser}) or
@code{YYSTACK_USE_ALLOCA} (@pxref{Table of Symbols}) to a nonzero value.
@node Stages
@section Stages in Using Bison

View File

@@ -112,11 +112,6 @@
/* A string that describes a char (e.g., 'a' -> "'a'"). */
static char const *char_name (char);
#define YYTYPE_INT16 int_fast16_t
#define YYTYPE_INT8 int_fast8_t
#define YYTYPE_UINT16 uint_fast16_t
#define YYTYPE_UINT8 uint_fast8_t
/* Add style to semantic values in traces. */
static void tron (FILE *yyo);
static void troff (FILE *yyo);