From cf8f805d364bec32aa6aa781bcb715a3c0c57f10 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 13 Sep 2020 09:52:53 +0200 Subject: [PATCH] glr2.cc: disable incorrect warnings from GCC6 to 9 For instance with GCC8: 616. regression.at:1560: testing Lex and parse params: glr2.cc ... tests/regression.at:1560: COLUMNS=1000; export COLUMNS; NO_TERM_HYPERLINKS=1; export NO_TERM_HYPERLINKS; bison --color=no -fno-caret -o input.cc input.y tests/regression.at:1560: $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o input input.cc $LIBS stderr: input.cc: In member function 'YYRESULTTAG glr_stack::yyresolveValue(glr_state*)': input.cc:1796:10: error: potential null pointer dereference [-Werror=null-dereference] return yypred ? &(asItem(this) - yypred)->getState() : YY_NULLPTR; ^~~~~~ input.cc:1796:10: error: potential null pointer dereference [-Werror=null-dereference] return yypred ? &(asItem(this) - yypred)->getState() : YY_NULLPTR; ^~~~~~ cc1plus: all warnings being treated as errors It complains that the implicit this in yypred might be null. It fears it because of loops such as for (glr_state* yys = firstTopState(); yys != yystateStack.yysplitPoint; yys = yys->pred()) yyn += 1; that could possibly set yys to null, since yys->pred might return null. However, the warning is incorrect, since in C++ `this` cannot be null. GCC 10 no longer emits this warning. GCC 7 also complains many times about glr_stack::yyresolveLocations when NDEBUG is enabled (when it is not, YYASSERT (yyoption != YY_NULLPTR) is probably enough to pacify GCC): 616. regression.at:1560: testing Lex and parse params: glr2.cc ... tests/regression.at:1560: COLUMNS=1000; export COLUMNS; NO_TERM_HYPERLINKS=1; export NO_TERM_HYPERLINKS; bison --color=no -fno-caret -o input.cc input.y tests/regression.at:1560: $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS -o input input.cc $LIBS stderr: input.cc: In member function 'void glr_stack::yyresolveLocations(glr_state*, int)': input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ input.cc: In member function 'YYRESULTTAG glr_stack::yyresolveValue(glr_state*)': input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ input.cc:3061:46: error: potential null pointer dereference [-Werror=null-dereference] yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ * data/skeletons/glr2.cc (YY_IGNORE_NULL_DEREFERENCE_BEGIN) (YY_IGNORE_NULL_DEREFERENCE_BEGIN): New. (glr_state::pred, glr_stack::yyresolveLocations): Use them. --- TODO | 13 ++++++++++--- data/skeletons/glr2.cc | 27 +++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 3f4d1978..c692b9f9 100644 --- a/TODO +++ b/TODO @@ -158,9 +158,12 @@ Les catégories d'avertissements incluent : Line -1 and -3 should mention CATEGORIE, not CATEGORY. * Bison 3.8 -** Rewrite glr.cc -*** glr.c -Get rid of scaffolding in glr.c. +** Rewrite glr.cc (currently glr2.cc) +*** Remove jumps +We can probably replace setjmp/longjmp with exceptions. That would help +tremendously other languages such as D and Java that probably have no +similar feature. If we remove jumps, we probably no longer need _Noreturn, +so simplify `b4_attribute_define([noreturn])` into `b4_attribute_define`. *** Coding style Move to our coding conventions. In particular names such as yy_glr_stack, @@ -178,6 +181,10 @@ There are many places where pointers should be replaced with references. Don't use YYSTYPE and YYLTYPE but parser::semantic_type and parser::location_type. Undefine YYSTYPE and YYLTYPE. +*** glr.c +When glr2.cc fully replaces glr.cc, get rid of the glr.cc scaffolding in +glr.c. + * Chains ** Unit rules / Injection rules (Akim Demaille) Maybe we could expand unit rules (or "injections", see diff --git a/data/skeletons/glr2.cc b/data/skeletons/glr2.cc index a7f2d129..e463ffb3 100644 --- a/data/skeletons/glr2.cc +++ b/data/skeletons/glr2.cc @@ -126,6 +126,17 @@ b4_percent_code_get([[requires]])[ ]b4_cast_define[ ]b4_null_define[ +#if defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ && __GNUC__ <= 9 +# define YY_IGNORE_NULL_DEREFERENCE_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wnull-dereference\"") +# define YY_IGNORE_NULL_DEREFERENCE_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_IGNORE_NULL_DEREFERENCE_BEGIN +# define YY_IGNORE_NULL_DEREFERENCE_END +#endif + // Whether we are compiled with exception support. #ifndef YY_EXCEPTIONS # if defined __GNUC__ && !defined __EXCEPTIONS @@ -1271,12 +1282,18 @@ public: bool is_state_; }; -glr_state* glr_state::pred() { - return yypred ? &(asItem(this) - yypred)->getState() : YY_NULLPTR; +glr_state* glr_state::pred () +{ + YY_IGNORE_NULL_DEREFERENCE_BEGIN + return yypred ? &(asItem (this) - yypred)->getState () : YY_NULLPTR; + YY_IGNORE_NULL_DEREFERENCE_END } -const glr_state* glr_state::pred() const { - return yypred ? &(asItem(this) - yypred)->getState() : YY_NULLPTR; +const glr_state* glr_state::pred () const +{ + YY_IGNORE_NULL_DEREFERENCE_BEGIN + return yypred ? &(asItem (this) - yypred)->getState () : YY_NULLPTR; + YY_IGNORE_NULL_DEREFERENCE_END } void glr_state::setPred(const glr_state* state) { @@ -2606,7 +2623,9 @@ class glr_stack { detected. Thus the location of the previous state (but not necessarily the previous state itself) is guaranteed to be resolved already. */ + YY_IGNORE_NULL_DEREFERENCE_BEGIN yyrhsloc[0].getState().yyloc = yyoption->state()->yyloc; + YY_IGNORE_NULL_DEREFERENCE_END } YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs); }