On Tue, Feb 14, 2017 at 10:05:04AM -0500, Nathan Sidwell wrote:
> On 02/13/2017 10:46 AM, Jakub Jelinek wrote:
> > Hi!
> > 
> > I'd like to ping a couple of patches:
> 
> > - C++ P1 PR79288 - wrong default TLS model for __thread static data members
> >   http://gcc.gnu.org/ml/gcc-patches/2017-01/msg02349.html
> 
> This is ok, but don't you think the changelog is misleading?  In your
> description you say it needs DECL_EXTERNAL set, but the changelog says
> 'inline', which isn't something static member vars have (although I can see
> how it's involved in DECL_EXTERNAL setting).

It is something static member vars can have (explicitly or implicitly).

In 6.x we had:
                /* Even if there is an in-class initialization, DECL
                   is considered undefined until an out-of-class
                   definition is provided.  */
                DECL_EXTERNAL (decl) = 1;

                if (thread_p)
                  {
                    CP_DECL_THREAD_LOCAL_P (decl) = true;
                    if (!processing_template_decl)
                      set_decl_tls_model (decl, decl_default_tls_model (decl));
                    if (declspecs->gnu_thread_keyword_p)
                      SET_DECL_GNU_TLS_P (decl);
                  }
...
With the addition of C++17 inline vars I changed that to:
                if (thread_p)
                  {
                    CP_DECL_THREAD_LOCAL_P (decl) = true;
                    if (!processing_template_decl)
                      set_decl_tls_model (decl, decl_default_tls_model (decl));
                    if (declspecs->gnu_thread_keyword_p)
                      SET_DECL_GNU_TLS_P (decl);
                  }
...

                if (inlinep)
                  mark_inline_variable (decl);

                if (!DECL_VAR_DECLARED_INLINE_P (decl)
                    && !(cxx_dialect >= cxx1z && constexpr_p))
                  /* Even if there is an in-class initialization, DECL
                     is considered undefined until an out-of-class
                     definition is provided, unless this is an inline
                     variable.  */
                  DECL_EXTERNAL (decl) = 1;
because inline static data members, explicit or implicit, really shouldn't
be marked DECL_EXTERNAL, they have in-class definition rather than a mere
declaration.
The patch just changes that back to:
...
                if (inlinep)
                  mark_inline_variable (decl);

                if (!DECL_VAR_DECLARED_INLINE_P (decl)
                    && !(cxx_dialect >= cxx1z && constexpr_p))
                  /* Even if there is an in-class initialization, DECL
                     is considered undefined until an out-of-class
                     definition is provided, unless this is an inline
                     variable.  */
                  DECL_EXTERNAL (decl) = 1;

                if (thread_p)
                  {
                    CP_DECL_THREAD_LOCAL_P (decl) = true;
                    if (!processing_template_decl)
                      set_decl_tls_model (decl, decl_default_tls_model (decl));
                    if (declspecs->gnu_thread_keyword_p)
                      SET_DECL_GNU_TLS_P (decl);
                  }

        Jakub

Reply via email to