On Wed, 21 Feb 2024, Nathaniel Shead wrote:
> 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.
Seems reasonable to me.
Aside from reverting, I suppose a couple of other options (which you've
probably already considered) are to restrict that defer_p condition
to non-templates by checking !DECL_USE_TEMPLATE (so in particular
explicit specializations aren't deferred), or to call
note_vague_linkage_variable for inline explicit specializations (e.g.
from make_rtl_for_nonlocal_decl upon deferring, or from
check_explicit_specialization). These should help with PR114013, no
idea about PR113970 though..
>
> 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
>
>