From a049509d0437046e57a0e96f71452ddb33f8eecc Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 14 Jan 2019 19:57:02 +0100 Subject: [PATCH] c++: avoid -Wundefined-func-template warnings from clang Reported by Derek Clegg. http://lists.gnu.org/archive/html/bug-bison/2019-01/msg00006.html Clang does not like this: template struct basic_symbol : D { basic_symbol(); }; struct by_type {}; struct symbol_type : basic_symbol { symbol_type(){} }; It gives: $ clang++-mp-7.0 -Wundefined-func-template foo.cc -c foo.cc:11:3: warning: instantiation of function 'basic_symbol::basic_symbol' required here, but no definition is available [-Wundefined-func-template] symbol_type(){} ^ foo.cc:4:3: note: forward declaration of template entity is here basic_symbol(); ^ foo.cc:11:3: note: add an explicit instantiation declaration to suppress this warning if 'basic_symbol::basic_symbol' is explicitly instantiated in another translation unit symbol_type(){} ^ 1 warning generated. The same applies for the basic_symbol's destructor and `clear()`. * configure.ac (warn_cxx): Add -Wundefined-func-template. This triggered one failure in the test suite: * tests/headers.at (Sane headers): here, where we check that we can compile the generated headers in other compilation units than the parser's. Add a variant type to make sure that basic_symbol and symbol_type are properly generated in this case. * data/skeletons/c++.m4 (basic_symbol): Inline the definitions of the destructor and of `clear` in the class definition. --- configure.ac | 3 ++- data/skeletons/c++.m4 | 60 ++++++++++++++++++------------------------- tests/headers.at | 2 +- 3 files changed, 28 insertions(+), 37 deletions(-) diff --git a/configure.ac b/configure.ac index e60af602..b7ba45dc 100644 --- a/configure.ac +++ b/configure.ac @@ -96,7 +96,8 @@ AM_CONDITIONAL([ENABLE_GCC_WARNINGS], [test "$enable_gcc_warnings" = yes]) if test "$enable_gcc_warnings" = yes; then warn_common='-Wall -Wextra -Wno-sign-compare -Wcast-align -fparse-all-comments -Wdocumentation - -Wformat -Wnull-dereference -Wpointer-arith -Wshadow -Wwrite-strings' + -Wformat -Wnull-dereference -Wpointer-arith -Wshadow + -Wundefined-func-template -Wwrite-strings' warn_c='-Wbad-function-cast -Wstrict-prototypes' warn_cxx='-Wextra-semi -Wnoexcept' # Warnings for the test suite only. diff --git a/data/skeletons/c++.m4 b/data/skeletons/c++.m4 index c985cb98..6f2d75d2 100644 --- a/data/skeletons/c++.m4 +++ b/data/skeletons/c++.m4 @@ -260,7 +260,10 @@ m4_define([b4_symbol_type_define], typedef Base super_type; /// Default constructor. - basic_symbol (); + basic_symbol () + : value ()]b4_locations_if([ + , location ()])[ + {} #if 201103L <= YY_CPLUSPLUS /// Move constructor. @@ -282,10 +285,29 @@ m4_define([b4_symbol_type_define], YY_RVREF (location_type) l])[); ]])[ /// Destroy the symbol. - ~basic_symbol (); + ~basic_symbol () + { + clear (); + } /// Destroy contents, and record that is empty. - void clear (); + void clear () + {]b4_variant_if([[ + // User destructor. + symbol_number_type yytype = this->type_get (); + basic_symbol& yysym = *this; + (void) yysym; + switch (yytype) + { +]b4_symbol_foreach([b4_symbol_destructor])dnl +[ default: + break; + } + + // Type destructor. +]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[ + Base::clear (); + } /// Whether empty. bool empty () const YY_NOEXCEPT; @@ -365,12 +387,6 @@ m4_define([b4_symbol_type_define], # Provide the implementation needed by the public types. m4_define([b4_public_types_define], [[ // basic_symbol. - template - ]b4_parser_class[::basic_symbol::basic_symbol () - : value ()]b4_locations_if([ - , location ()])[ - {} - #if 201103L <= YY_CPLUSPLUS template ]b4_parser_class[::basic_symbol::basic_symbol (basic_symbol&& that) @@ -416,32 +432,6 @@ m4_define([b4_public_types_define], (void) v; ]b4_symbol_variant([this->type_get ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[ - template - ]b4_parser_class[::basic_symbol::~basic_symbol () - { - clear (); - } - - template - void - ]b4_parser_class[::basic_symbol::clear () - {]b4_variant_if([[ - // User destructor. - symbol_number_type yytype = this->type_get (); - basic_symbol& yysym = *this; - (void) yysym; - switch (yytype) - { -]b4_symbol_foreach([b4_symbol_destructor])dnl -[ default: - break; - } - - // Type destructor. - ]b4_symbol_variant([[yytype]], [[value]], [[template destroy]])])[ - Base::clear (); - } - template bool ]b4_parser_class[::basic_symbol::empty () const YY_NOEXCEPT diff --git a/tests/headers.at b/tests/headers.at index 32c8d856..a58074fe 100644 --- a/tests/headers.at +++ b/tests/headers.at @@ -125,7 +125,7 @@ AT_BISON_OPTION_PUSHDEFS([$1]) AT_DATA_GRAMMAR([input.y], [[$1 %define parse.error verbose -]AT_VARIANT_IF([], [%union {int integer;}])[ +]AT_VARIANT_IF([%token 'x'], [%union {int integer;}])[ %code { ]AT_PUSH_IF([[ #if defined __GNUC__ && 7 == __GNUC__