[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: member with constructor not allowed in union
From: |
Paul Eggert |
Subject: |
Re: member with constructor not allowed in union |
Date: |
Mon, 18 Mar 2002 14:09:55 -0800 (PST) |
> From: Akim Demaille <address@hidden>
> Date: 18 Mar 2002 11:31:23 +0100
> We cannot afford to put YYSTYPE (and actually YYLTYPE) into a union,
> as it makes it impossible for C++ users to use any useful structure
> in it.
OK, but (as you know) the code was broken at runtime, because it used
memcpy to copy the C++ objects when growing the stack, and bypassing
the constructors and destructors led to "pyrotechnical" behavior as
described in the Debian bug report at:
<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=130914>
> would you handle the reversal in 1.3x?
I've installed the following patch in 1.3x. It is not quite a
reversal, though, because it also fixes the "pyrotechnical" problem,
by disabling stack growth for C++ parsers that define YYSTYPE.
This should fix the compile-time problems that C++ users are
complaining about. It should also fix the more-serious (and less
obvious) run-time problems with C++ parsers.
If I understand things correctly this change is not needed for the
1.4x version, as it has a separate C++ template. But if I'm wrong
please let me know, so that I can install it there too.
This patch passes "make check" with Bison, but "make check" doesn't
have any C++ examples so I'd appreciate it if you C++ aficionados try
it out.
2002-03-18 Paul Eggert <address@hidden>
Fix the problem with union yyalloc and C++ (Debian bug 130914).
* src/bison.simple (union yyalloc, YYSTACK_GAP_MAX, YYSTACK_BYTES,
YYSTACK_RELOCATE): Do not define if yyoverflow is defined, or if
this is a C++ parser and YYSTYPE or YYLTYPE has nontrivial
constructors or destructors.
(yymemcpy) [! defined YYSTACK_RELOCATE]: Do not define; not needed.
(yyparse) [! defined YYSTACK_RELOCATE]: Do not relocate the stack.
* src/reader.c (parse_union_decl): Define YYSTYPE_IS_TRIVIAL if we
use our YYSTYPE. It must be trivial, or our own union wouldn't be
valid C++ anyway.
(readgram): Define YYSTYPE_IS_TRIVIAL if it is int.
(reader_output_yylsp): Define YYLTYPE_IS_TRIVIAL if we use our
YYLTYPE.
Index: src/bison.simple
===================================================================
RCS file: /cvsroot/bison/bison/src/Attic/bison.simple,v
retrieving revision 1.53.2.19
diff -p -u -r1.53.2.19 bison.simple
--- src/bison.simple 25 Feb 2002 18:02:06 -0000 1.53.2.19
+++ src/bison.simple 18 Mar 2002 21:44:03 -0000
@@ -66,6 +66,12 @@
# define YYSTACK_ALLOC malloc
# define YYSTACK_FREE free
# endif
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
@@ -109,7 +115,7 @@ union yyalloc
}
\
while (0)
-#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+#endif
#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
@@ -236,7 +242,7 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
-#if ! defined (yyoverflow) && ! defined (yymemcpy)
+#if defined (YYSTACK_RELOCATE) && ! defined (yymemcpy)
# if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
# define yymemcpy __builtin_memcpy
# else /* not GNU C or C++ */
@@ -504,6 +510,9 @@ yyparse (YYPARSE_PARAM_ARG)
yyvs = yyvs1;
}
#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
/* Extend the stack our own way. */
if (yystacksize >= YYMAXDEPTH)
goto yyoverflowlab;
@@ -526,6 +535,7 @@ yyparse (YYPARSE_PARAM_ARG)
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
+# endif
#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
Index: src/reader.c
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.c,v
retrieving revision 1.72.2.30
diff -p -u -r1.72.2.30 reader.c
--- src/reader.c 4 Mar 2002 16:59:51 -0000 1.72.2.30
+++ src/reader.c 18 Mar 2002 21:44:03 -0000
@@ -745,6 +745,7 @@ typedef union";
const char *epilogue = "\
yystype;\n\
# define YYSTYPE yystype\n\
+# define YYSTYPE_IS_TRIVIAL 1\n\
#endif\n";
if (typed)
@@ -1617,12 +1618,16 @@ readgram (void)
/* We used to use `unsigned long' as YYSTYPE on MSDOS,
but it seems better to be consistent.
Most programs should declare their own type anyway. */
- obstack_sgrow (&attrs_obstack,
- "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
+ obstack_sgrow (&attrs_obstack, "\
+#ifndef YYSTYPE\n\
+# define YYSTYPE int\n\
+# define YYSTYPE_IS_TRIVIAL 1\n\
+#endif\n");
if (defines_flag)
obstack_sgrow (&defines_obstack, "\
# ifndef YYSTYPE\n\
# define YYSTYPE int\n\
+# define YYSTYPE_IS_TRIVIAL 1\n\
# endif\n");
}
@@ -2043,6 +2048,7 @@ typedef struct yyltype\n\
} yyltype;\n\
\n\
# define YYLTYPE yyltype\n\
+# define YYLTYPE_IS_TRIVIAL 1\n\
#endif\n\
\n");
}
- Re: member with constructor not allowed in union,
Paul Eggert <=