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
> 
> 

Reply via email to