bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/3] c++: issue a compile-time warning when #define YYSTYPE is us


From: Akim Demaille
Subject: [PATCH 3/3] c++: issue a compile-time warning when #define YYSTYPE is used
Date: Mon, 1 Feb 2021 06:34:39 +0100

Using #define YYSTYPE has always been strongly discouraged in C++.
Macros are dangerous and can result in subtle bugs.
https://lists.gnu.org/r/bug-bison/2020-12/msg00007.html

Maybe some people are currently using #define YYSTYPE.  Instead of
dropping support right now, first issue a warning.  Bison can "see" if
YYDEBUG is defined (it could even be on the command line), only the
compiler knows.  Unfortunately `#warning` is non-portable, and
actually GCC even dies on it when `-pedantic` is enabled.  So we need
to use `#pragma message`.  We must make it conditional as some
compilers might not support it, but it doesn't matter if only _some_
compilers emit the warning: it should be enough to catch the attention
of the developers.

* data/skeletons/c++.m4: Issue a warning when the user defined
YYSTYPE.
* tests/actions.at: Don't #define YYSTYPE.
* tests/headers.at (Several parsers): Ignore the YYSTYPE in the
warning.
---
 data/skeletons/c++.m4 |  9 ++++++---
 tests/actions.at      |  4 ++--
 tests/headers.at      | 17 ++++++++++-------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/data/skeletons/c++.m4 b/data/skeletons/c++.m4
index 212978a28..cd6fdb039 100644
--- a/data/skeletons/c++.m4
+++ b/data/skeletons/c++.m4
@@ -227,10 +227,13 @@ m4_define([b4_value_type_declare],
 # Define the public types: token, semantic value, location, and so forth.
 # Depending on %define token_lex, may be output in the header or source file.
 m4_define([b4_public_types_declare],
-[[#ifndef ]b4_api_PREFIX[STYPE
-]b4_value_type_declare[
-#else
+[[#ifdef ]b4_api_PREFIX[STYPE
+# ifdef __GNUC__
+#  pragma GCC message "bison: do not #define ]b4_api_PREFIX[STYPE in C++, use 
%define api.value.type"
+# endif
     typedef ]b4_api_PREFIX[STYPE value_type;
+#else
+]b4_value_type_declare[
 #endif
     /// Backward compatibility (Bison 3.8).
     typedef value_type semantic_type;]b4_locations_if([
diff --git a/tests/actions.at b/tests/actions.at
index ed1e8d681..e08734b54 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -1777,8 +1777,6 @@ AT_DATA_GRAMMAR([[input.y]],
     float fval;
   } sem_type;
 
-# define YYSTYPE sem_type
-
 ]AT_CXX_IF([[
 # include <cstdio> // EOF.
 # include <iostream>
@@ -1800,6 +1798,8 @@ AT_DATA_GRAMMAR([[input.y]],
 ]])[
 }
 
+%define api.value.type {sem_type}
+
 %code
 {
   ]AT_YYERROR_DECLARE[
diff --git a/tests/headers.at b/tests/headers.at
index b3262fad7..57a5591f5 100644
--- a/tests/headers.at
+++ b/tests/headers.at
@@ -328,15 +328,18 @@ AT_TEST([xb], [%locations %define api.location.file none 
%language "c++" %define
 #   C++ output relies on namespaces and still uses yy a lot.
 #
 # - no 'YY' left.
-#   Ignore comments, YYChar (template parameter), YYPUSH_MORE(_DEFINED)?
-#   (constant definition), YY_\w+_INCLUDED (header guards).
+#   Ignore YYPUSH_MORE(_DEFINED)? (constant definition),
 #   YYDEBUG (not renamed) can be read, but not changed.
 AT_PERL_CHECK([[-n -0777 -e '
+  # Ignore comments.
   s{/\*.*?\*/}{}gs;
   s{//.*}{}g;
+  # Ignore warnings.
+  s{# *pragma .* message ".*"}{}g;
+
   s{\b((defined|if)\ YYDEBUG
-      |YYChar
-      |YYNTOKENS  # This is actual scoped in a C++ class.
+      |YYChar     # Template parameter.
+      |YYNTOKENS  # This is actually scoped in a C++ class.
       |YYPUSH_MORE(?:_DEFINED)?
       |S_(YY(ACCEPT|EMPTY|EOF|error|UNDEF))  # These guys are scoped.
       |YY(?:_REINTERPRET)?_CAST
@@ -354,9 +357,9 @@ AT_PERL_CHECK([[-n -0777 -e '
       |YY_NULLPTR
       |YY_RVREF
       |YY_USE
-      |YY_\w+_INCLUDED
-      |FILE\ \*yyo   # Function argument.
-      |const\ yylocp # Function argument.
+      |YY_\w+_INCLUDED  # Header guards.
+      |FILE\ \*yyo      # Function argument.
+      |const\ yylocp    # Function argument.
       )\b}{}gx;
   while (/^(.*YY.*)$/gm)
   {
-- 
2.30.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]