My earlier patch appears to have caused some regressions. I've taken a quick look to see if there are obvious workarounds, but given the time frame and the fact that I still don't really understand all the details of how and when symbols get emitted, I felt it was safer to revert the non-modules parts of this change instead.
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 -- This is a (partial) reversion of r14-8987-gdd9d14f7d53 to return to eagerly emitting inline variables to the middle-end when they are declared. 'import_export_decl' will still continue to accept them, as allowing this is a pure extension and doesn't seem to cause issues with modules, but otherwise deferring the emission of inline variables appears to cause issues on some targets and prevents some code using inline variable templates from correctly linking. There might be a more targetted way to fix this, but due to the complexity of handling linkage I'd prefer to wait till GCC 15 to explore our options. PR c++/113970 PR c++/114013 gcc/cp/ChangeLog: * decl.cc (make_rtl_for_nonlocal_decl): Don't defer inline variables. * decl2.cc (import_export_decl): Only support inline variables imported from a module. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/inline-var10.C: New test. --- gcc/cp/decl.cc | 4 --- gcc/cp/decl2.cc | 6 +++-- gcc/testsuite/g++.dg/cpp1z/inline-var10.C | 33 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/inline-var10.C diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index e47f694e4e5..d19d09adde4 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -7954,10 +7954,6 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) && DECL_IMPLICIT_INSTANTIATION (decl)) defer_p = 1; - /* Defer vague-linkage variables. */ - if (DECL_INLINE_VAR_P (decl)) - defer_p = 1; - /* If we're not deferring, go ahead and assemble the variable. */ if (!defer_p) rest_of_decl_compilation (decl, toplev, at_eof); diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 1dddbaab38b..24a9332ccb1 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -3362,7 +3362,7 @@ import_export_decl (tree decl) * inline functions - * inline variables + * inline variables (from modules) * implicit instantiations of static data members of class templates @@ -3385,7 +3385,9 @@ import_export_decl (tree decl) || DECL_DECLARED_INLINE_P (decl)); else gcc_assert (DECL_IMPLICIT_INSTANTIATION (decl) - || DECL_INLINE_VAR_P (decl) + || (DECL_INLINE_VAR_P (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_MODULE_IMPORT_P (decl)) || DECL_VTABLE_OR_VTT_P (decl) || DECL_TINFO_P (decl)); /* Check that a definition of DECL is available in this translation diff --git a/gcc/testsuite/g++.dg/cpp1z/inline-var10.C b/gcc/testsuite/g++.dg/cpp1z/inline-var10.C new file mode 100644 index 00000000000..8a198556778 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/inline-var10.C @@ -0,0 +1,33 @@ +// PR c++/114013 +// { dg-do link { target c++17 } } + +struct S { int a, b; }; + +template <int N> +constexpr struct S var[8] = {}; + +template <> +constexpr inline struct S var<6>[8] = { + { 1, 1 }, { 2, 0 }, { 3, 1 }, { 4, 0 }, + { 5, 1 }, { 6, 0 }, { 7, 1 }, { 8, 0 } +}; + +[[gnu::noipa]] void +foo (S) +{ +} + +template <int N> +void +bar (int x) +{ + foo (var<N>[x]); +} + +volatile int x; + +int +main () +{ + bar <6> (x); +} -- 2.43.0