https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79061
--- Comment #28 from Maxim Ostapenko <m.ostapenko at samsung dot com> --- (In reply to Jakub Jelinek from comment #27) > I think the problem is in the vnode->dynamically_initialized handling, as > well as in get_translation_unit_decl being totally unreliable. > When LTO merges VAR_DECLs from multiple TUs, it either should clear the > dynamically_initialized flag, or should make sure that the decl that is used > for the vnode actually is going to have get_translation_unit_decl the TU > that it contained the definition. > The #c20 testcase has in the end 3 globals: > name = "__ioinit", module_name = 0x400f3c "/tmp/ccoQRMfD.ltrans0.o", > has_dynamic_init = 1 > name = 0x400f5d "xptimer_clean", module_name = 0x400de0 "xptimer.cc", > has_dynamic_init = 1 > name = 0x400f6b "xptimer_sweep", module_name = 0x400de0 "xptimer.cc", > has_dynamic_init = 1 > > xptimer_clean and xptimer_sweep are both defined in xptiming.cc and declared > in xptiming.h, xptimer.cc TU doesn't see any traces of it, yet > get_translation_unit_decl returns for it the xptimer.cc TU, because > DECL_CONTEXT of those 2 vars is a NAMESPACE_DECL and LTO merges > NAMESPACE_DECLs too. > Similarly, __ioinit has DECL_CONTEXT of std namespace and that, being > prebuilt by the compiler, doesn't have surrounding TU. > Even when considering only VAR_DECLs that have DECL_CONTEXT of > TRANSLATION_UNIT_DECL directly, I believe this doesn't work right: > 1) if the VAR_DECL has more than one definition (comdat, inline var, ...?), > then I think we'd need to merge the two definitions with > dynamically_initialized 1 as dynamically_initialized 0 > 2) wonder if we ever merge external decl with decl definition using the > external decl's context > > In short, the easiest fix is just to disable the initialization order > checking altogether for LTO (by forcing dynamically_initialized = 0 in LTO). Yeah, that's what I thought about. Should I revert the whole bunch of related patches or just force vnode->dynamically_initialized = 0 for LTO leaving a comment with link to this PR? > Or at least clear it when merging multiple varpool nodes that have > dynamically_initialized = 1, and otherwise (if there is just one TU with > vnode->dynamically_initialized == 1), make sure get_translation_unit_decl > will return that TU for it and if we can't ensure that, clear > dynamically_initialized too. Which can be done e.g. by clearing it whenever > DECL_CONTEXT actually isn't a TRANSLATION_UNIT_DECL directly or is some > other TU, or by say adding TRANSLATION_UNIT_DECL tree into the vnode (grows > memory usage though!) and looking it up from there.