Hi! I'd like to ping this patch, which has been successfully bootstrapped/regtested on x86_64-linux and i686-linux:
https://gcc.gnu.org/pipermail/gcc-patches/2023-February/611180.html - PR108634 - P3 - tree: Use comdat tree_code_{type,length} even for C++11/14 Thanks Jakub On Thu, Feb 02, 2023 at 03:30:29PM +0100, Jakub Jelinek via Gcc-patches wrote: > The recent change to undo the tree_code_type/tree_code_length > excessive duplication apparently broke building the Linux kernel > plugin. While it is certainly desirable that GCC plugins are built > with the same compiler as GCC has been built and with the same options > (at least the important ones), it might be hard to arrange that, > e.g. if gcc is built using a cross-compiler but the plugin then built > natively, or GCC isn't bootstrapped for other reasons, or just as in > the kernel case they were building the plugin with -std=gnu++11 while > the bootstrapped GCC has been built without any such option and so with > whatever the compiler defaulted to. > > For C++17 and later tree_code_{type,length} are UNIQUE symbols with > those assembler names, while for C++11/14 they were > _ZL14tree_code_type and _ZL16tree_code_length. > > The following patch uses a comdat var for those even for C++11/14 > as suggested by Maciej Cencora. Relying on weak attribute is not an > option because not all hosts support it and there are non-GNU system > compilers. While we could use it unconditionally, > I think defining a template just to make it comdat is weird, and > the compiler itself is always built with the same compiler. > Plugins, being separate shared libraries, will have a separate copy of > the arrays if they are ODR-used in the plugin, so there is not a big > deal if e.g. cc1plus uses tree_code_type while plugin uses > _ZN19tree_code_type_tmplILi0EE14tree_code_typeE or vice versa. > > Tested in non-bootstrapped build with both -std=gnu++17 and -std=gnu++11, > ok for trunk if it passes full bootstrap/regtest? > > 2023-02-02 Jakub Jelinek <ja...@redhat.com> > > PR plugins/108634 > * tree-core.h (tree_code_type, tree_code_length): For C++11 or > C++14, don't declare as extern const arrays. > (tree_code_type_tmpl, tree_code_length_tmpl): New types with > static constexpr member arrays for C++11 or C++14. > * tree.h (TREE_CODE_CLASS): For C++11 or C++14 use > tree_code_type_tmpl <0>::tree_code_type instead of tree_code_type. > (TREE_CODE_LENGTH): For C++11 or C++14 use > tree_code_length_tmpl <0>::tree_code_length instead of > tree_code_length. > * tree.cc (tree_code_type, tree_code_length): Remove. > > --- gcc/tree-core.h.jj 2023-01-27 10:51:27.575399052 +0100 > +++ gcc/tree-core.h 2023-02-02 15:06:05.048665279 +0100 > @@ -2285,19 +2285,27 @@ struct floatn_type_info { > extern bool tree_contains_struct[MAX_TREE_CODES][64]; > > /* Class of tree given its code. */ > -#if __cpp_inline_variables >= 201606L > #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, > #define END_OF_BASE_TREE_CODES tcc_exceptional, > > +#if __cpp_inline_variables < 201606L > +template <int N> > +struct tree_code_type_tmpl { > + static constexpr enum tree_code_class tree_code_type[] = { > +#include "all-tree.def" > + }; > +}; > + > +template <int N> > +constexpr enum tree_code_class tree_code_type_tmpl<N>::tree_code_type[]; > +#else > constexpr inline enum tree_code_class tree_code_type[] = { > #include "all-tree.def" > }; > +#endif > > #undef DEFTREECODE > #undef END_OF_BASE_TREE_CODES > -#else > -extern const enum tree_code_class tree_code_type[]; > -#endif > > /* Each tree code class has an associated string representation. > These must correspond to the tree_code_class entries. */ > @@ -2305,18 +2313,27 @@ extern const char *const tree_code_class > > /* Number of argument-words in each kind of tree-node. */ > > -#if __cpp_inline_variables >= 201606L > #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, > #define END_OF_BASE_TREE_CODES 0, > + > +#if __cpp_inline_variables < 201606L > +template <int N> > +struct tree_code_length_tmpl { > + static constexpr unsigned char tree_code_length[] = { > +#include "all-tree.def" > + }; > +}; > + > +template <int N> > +constexpr unsigned char tree_code_length_tmpl<N>::tree_code_length[]; > +#else > constexpr inline unsigned char tree_code_length[] = { > #include "all-tree.def" > }; > +#endif > > #undef DEFTREECODE > #undef END_OF_BASE_TREE_CODES > -#else > -extern const unsigned char tree_code_length[]; > -#endif > > /* Vector of all alias pairs for global symbols. */ > extern GTY(()) vec<alias_pair, va_gc> *alias_pairs; > --- gcc/tree.h.jj 2023-01-27 20:09:16.183970583 +0100 > +++ gcc/tree.h 2023-02-02 14:37:17.255004291 +0100 > @@ -177,7 +177,12 @@ code_helper::is_builtin_fn () const > #define TREE_CODE_CLASS_STRING(CLASS)\ > tree_code_class_strings[(int) (CLASS)] > > +#if __cpp_inline_variables < 201606L > +#define TREE_CODE_CLASS(CODE) \ > + tree_code_type_tmpl <0>::tree_code_type[(int) (CODE)] > +#else > #define TREE_CODE_CLASS(CODE) tree_code_type[(int) (CODE)] > +#endif > > /* Nonzero if NODE represents an exceptional code. */ > > @@ -271,7 +276,12 @@ code_helper::is_builtin_fn () const > > #define EXPR_P(NODE) IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE))) > > +#if __cpp_inline_variables < 201606L > +#define TREE_CODE_LENGTH(CODE) \ > + tree_code_length_tmpl <0>::tree_code_length[(int) (CODE)] > +#else > #define TREE_CODE_LENGTH(CODE) tree_code_length[(int) (CODE)] > +#endif > > > /* Helper macros for math builtins. */ > --- gcc/tree.cc.jj 2023-02-02 10:54:44.302473853 +0100 > +++ gcc/tree.cc 2023-02-02 14:20:58.712251654 +0100 > @@ -74,34 +74,6 @@ along with GCC; see the file COPYING3. > #include "asan.h" > #include "ubsan.h" > > -#if __cpp_inline_variables < 201606L > -/* Tree code classes. */ > - > -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, > -#define END_OF_BASE_TREE_CODES tcc_exceptional, > - > -const enum tree_code_class tree_code_type[] = { > -#include "all-tree.def" > -}; > - > -#undef DEFTREECODE > -#undef END_OF_BASE_TREE_CODES > - > -/* Table indexed by tree code giving number of expression > - operands beyond the fixed part of the node structure. > - Not used for types or decls. */ > - > -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, > -#define END_OF_BASE_TREE_CODES 0, > - > -const unsigned char tree_code_length[] = { > -#include "all-tree.def" > -}; > - > -#undef DEFTREECODE > -#undef END_OF_BASE_TREE_CODES > -#endif > - > /* Names of tree components. > Used for printing out the tree and error messages. */ > #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,