Hi! The inline variable changes broke the default TLS model of non-inline static data members. The decl_default_tls_model call needs DECL_EXTERNAL for the !processing_template_decl be already set appropriately. The following patch moves the thread_p processing a few lines below, so that it is already set there.
Bootstrapped/regtested on x86_64-linux and i686-linux, additionally on both tested with make check-c++-all, ok for trunk? 2017-01-30 Jakub Jelinek <ja...@redhat.com> PR c++/79288 * decl.c (grokdeclarator): For static data members, handle thread_p only after handling inline. * g++.dg/tls/pr79288.C: New test. --- gcc/cp/decl.c.jj 2017-01-26 09:14:24.000000000 +0100 +++ gcc/cp/decl.c 2017-01-30 18:49:38.544438710 +0100 @@ -12049,14 +12049,6 @@ grokdeclarator (const cp_declarator *dec : input_location, VAR_DECL, unqualified_id, type); set_linkage_for_static_data_member (decl); - 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 (concept_p) error ("static data member %qE declared %<concept%>", unqualified_id); @@ -12077,6 +12069,15 @@ grokdeclarator (const cp_declarator *dec 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); + } } else { --- gcc/testsuite/g++.dg/tls/pr79288.C.jj 2017-01-30 18:55:05.754282818 +0100 +++ gcc/testsuite/g++.dg/tls/pr79288.C 2017-01-30 18:54:52.000000000 +0100 @@ -0,0 +1,28 @@ +// PR c++/79288 +// { dg-do compile { target nonpic } } +// { dg-require-effective-target tls } +// { dg-options "-O2" } +// { dg-final { scan-assembler-not "@tpoff" { target i?86-*-* x86_64-*-* } } } + +struct S +{ + static __thread int *p; +}; + +template <int N> +struct T +{ + static __thread int *p; +}; + +int * +foo () +{ + return S::p; +} + +int * +bar () +{ + return T<0>::p; +} Jakub