The use of YY_IGNORE_NULL_DEREFERENCE_BEGIN/END in `check_` is to please GCC 10:
glr-regr8.cc: In member function 'YYRESULTTAG glr_stack::yyresolveValue(glr_state&)': glr-regr8.cc:1433:21: error: potential null pointer dereference [-Werror=null-dereference] 1433 | YYASSERT (this->magic_ == MAGIC); | ~~~~~~^~~~~~ glr-regr8.cc:905:40: note: in definition of macro 'YYASSERT' 905 | # define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0))) | ^~~~~~~~~ * data/skeletons/glr2.cc (glr_state::check_): New. Use it in the member functions. --- data/skeletons/glr2.cc | 72 ++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/data/skeletons/glr2.cc b/data/skeletons/glr2.cc index 07a162dc..8f245ffc 100644 --- a/data/skeletons/glr2.cc +++ b/data/skeletons/glr2.cc @@ -774,7 +774,8 @@ public: : yyresolved(false) , yylrState(0) , yyposn(0) - , yypred(0) + , yypred(0)]b4_parse_assert_if([[ + , magic_ (MAGIC)]])[ {} /// Build with a semantic value. @@ -783,7 +784,8 @@ public: , yylrState(lrState) , yyposn(posn) , yypred(0)]b4_locations_if([[ - , yyloc(loc)]])[ + , yyloc(loc)]])[]b4_parse_assert_if([[ + , magic_ (MAGIC)]])[ { semanticVal() = sval; } @@ -794,10 +796,13 @@ public: , yylrState(lrState) , yyposn(posn) , yypred(0) - , yyfirstVal(0) + , yyfirstVal(0)]b4_parse_assert_if([[ + , magic_ (MAGIC)]])[ {} - void copyFrom(const glr_state& other) { + void copyFrom(const glr_state& other) + {]b4_parse_assert_if([[ + other.check_ ();]])[ *this = other; setPred(other.pred()); if (other.yyresolved) { @@ -826,11 +831,15 @@ public: const semantic_option* firstVal() const; void setFirstVal(const semantic_option* option); - YYSTYPE& semanticVal() { + YYSTYPE& semanticVal() + {]b4_parse_assert_if([[ + check_ ();]])[ return yysval; } - const YYSTYPE& semanticVal() const { + const YYSTYPE& semanticVal() const + {]b4_parse_assert_if([[ + check_ ();]])[ return yysval; } @@ -840,7 +849,8 @@ public: /* DEBUGGING ONLY */ #if ]b4_api_PREFIX[DEBUG void yy_yypstack() const - { + {]b4_parse_assert_if([[ + check_ ();]])[ if (pred() != YY_NULLPTR) { pred()->yy_yypstack(); @@ -852,7 +862,9 @@ public: std::ptrdiff_t indexIn(glr_stack_item* array); - glr_stack_item* asItem() { + glr_stack_item* asItem() + {]b4_parse_assert_if([[ + check_ ();]])[ return asItem(this); } @@ -875,9 +887,24 @@ public: /** Semantic value for this state. */ YYSTYPE yysval; };]b4_locations_if([[ + // FIXME: Why public? public: /** Source location for this state. */ YYLTYPE yyloc;]])[ + +]b4_parse_assert_if([[ +private: + // Check invariants. + void check_ () const + { + YY_IGNORE_NULL_DEREFERENCE_BEGIN + YYASSERT (this->magic_ == MAGIC); + YY_IGNORE_NULL_DEREFERENCE_END + } + + // A magic number to check our pointer arithmetics is sane. + enum { MAGIC = 0x713705 }; + unsigned int magic_;]])[ }; /** A stack of GLRState representing the different heads during @@ -1255,36 +1282,48 @@ public: }; glr_state* glr_state::pred () -{ +{]b4_parse_assert_if([[ + check_ ();]])[ 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 -{ +{]b4_parse_assert_if([[ + check_ ();]])[ 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) { +void glr_state::setPred (const glr_state* state) +{]b4_parse_assert_if([[ + check_ ();]])[ yypred = state ? asItem(this) - asItem(state) : 0; } -semantic_option* glr_state::firstVal() { +semantic_option* glr_state::firstVal () +{]b4_parse_assert_if([[ + check_ ();]])[ return yyfirstVal ? &(asItem(this) - yyfirstVal)->getOption() : YY_NULLPTR; } -const semantic_option* glr_state::firstVal() const { +const semantic_option* glr_state::firstVal () const +{]b4_parse_assert_if([[ + check_ ();]])[ return yyfirstVal ? &(asItem(this) - yyfirstVal)->getOption() : YY_NULLPTR; } -void glr_state::setFirstVal(const semantic_option* option) { +void glr_state::setFirstVal(const semantic_option* option) +{]b4_parse_assert_if([[ + check_ ();]])[ yyfirstVal = option ? asItem(this) - asItem(option) : 0; } -std::ptrdiff_t glr_state::indexIn(glr_stack_item* array) { +std::ptrdiff_t glr_state::indexIn(glr_stack_item* array) +{]b4_parse_assert_if([[ + check_ ();]])[ return asItem(this) - array; } @@ -1315,7 +1354,8 @@ void semantic_option::setNext(const semantic_option* s) { } void glr_state::destroy (char const *yymsg, ]b4_namespace_ref[::]b4_parser_class[& yyparser]b4_user_formals[) -{ +{]b4_parse_assert_if([[ + check_ ();]])[ if (yyresolved) yyparser.yy_destroy_ (yymsg, static_cast<yysymbol_kind_t>(yystos[yylrState]), &semanticVal()]b4_locations_if([, &yyloc])[); -- 2.29.2