Considering this snippet: ------------------------------------------------------- namespace { struct X { X() { } }; thread_local X x; } int main() { x; } ----------------------------------------------------- Compiling with "c++ -std=c++0x" results in: ---------------------------------------------------- /tmp/cceAUNGB.o: In function `_ZTWN12_GLOBAL__N_11xE': thread_local.link_failure.with_main.cc:(.text+0x55): undefined reference to `_ZTHN12_GLOBAL__N_11xE' collect2: error: ld returned 1 exit status ------------------------------------------------------ Output of c++ -v is: ----------------------------------------------------------- Using built-in specs. COLLECT_GCC=/home/lima/vanilla_installs/gcc_and_tools/bin/c++ COLLECT_LTO_WRAPPER=/home/lima/vanilla_installs/gcc_and_tools/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../gcc_svn/configure --prefix=/home/lima/vanilla_installs/gcc_and_tools --enable-__cxa_atexit --enable-languages=c,c++ --disable-nls --disable-multilib Thread model: posix gcc version 4.8.0 20121223 (experimental) (GCC) -----------------------------------------------------------
Confirmed for 4.8.1 (using -std=c++11). Seems to be the same as bug #57163.
I have encountered a similar problem output of gcc -v: Using built-in specs. COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.1/g++ COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.8.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /var/tmp/portage/sys-devel/gcc-4.8.1-r1/work/gcc-4.8.1/configure --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.1 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.1 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.1/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.1/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4 --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --disable-altivec --disable-fixed-point --with-cloog --disable-isl-version-check --enable-lto --enable-nls --without-included-gettext --with-system-zlib --enable-obsolete --disable-werror --enable-secureplt --enable-multilib --with-multilib-list=m32,m64 --enable-libmudflap --disable-libssp --enable-libgomp --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.8.1/python --enable-checking=release --disable-libgcj --enable-libstdcxx-time --enable-languages=c,c++,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-targets=all --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.8.1-r1 p1.2, pie-0.5.7' Thread model: posix gcc version 4.8.1 (Gentoo 4.8.1-r1 p1.2, pie-0.5.7) ========================================================================= Here's a simplified version of the code I was using: ========================================================================= main.cpp: #include "xyz.hpp" int main() { return *xyz::getBla(); } ========================================================================= xyz.hpp: #include <memory> class xyz { private: static thread_local std::unique_ptr<int> bla; public: static int* getBla() { if(!bla.get()) { bla.reset(new int(4)); } return bla.get(); } }; ========================================================================= xyz.cpp: #include "xyz.hpp" thread_local std::unique_ptr<int> xyz::bla; ========================================================================= If I try to compile this with g++ -std=c++11 main.cpp xyz.cpp /tmp/ccLJmEUa.o: In function `_ZTWN3xyz3blaE': main.cpp:(.text._ZTWN3xyz3blaE[_ZTWN3xyz3blaE]+0x5): undefined reference to `_ZTHN3xyz3blaE' collect2: error: ld returned 1 exit status I don't know if the following is any help: I messed with the assembly output of g++ when compiling xyz.cpp and it looks that _ZTWN3xyz3blaE should be where __tls_init begins - at least adding .globl _ZTWN3xyz3blaE _ZTWN3xyz3blaE = __tls_init manually at the end of the assembly seems to make the code do what it is supposed to.
Works for me with 4.8.0 and later.
The code from comment 2 still doesn't work with GCC 4.8.2 ========================================================================= gcc -v: Using built-in specs. COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.2/gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.8.2/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /var/tmp/portage/sys-devel/gcc-4.8.2/work/gcc-4.8.2/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.8.2 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.2 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.2/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.8.2/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4 --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.8.2/python --enable-languages=c,c++,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.8.2 p1.3, pie-0.5.8' --enable-libstdcxx-time --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-altivec --disable-fixed-point --enable-targets=all --disable-libgcj --enable-libgomp --enable-libmudflap --disable-libssp --enable-lto --with-cloog --disable-isl-version-check Thread model: posix gcc version 4.8.2 (Gentoo 4.8.2 p1.3, pie-0.5.8) ========================================================================= output of compiling code from Comment 2: g++ -std=c++11 main.cpp xyz.cpp /tmp/cccXvzux.o: In function `TLS wrapper function for xyz::bla': main.cpp:(.text._ZTWN3xyz3blaE[_ZTWN3xyz3blaE]+0x5): undefined reference to `TLS init function for xyz::bla' collect2: error: ld returned 1 exit status =========================================================================
Works with 4.9 though.
*** Bug 59364 has been marked as a duplicate of this bug. ***
Fixed for 4.8.3.
Author: jason Date: Fri Jan 31 16:25:55 2014 New Revision: 207360 URL: http://gcc.gnu.org/viewcvs?rev=207360&root=gcc&view=rev Log: PR c++/55800 * decl2.c (get_tls_init_fn): Copy DECL_EXTERNAL from the variable. Added: trunk/gcc/testsuite/g++.dg/tls/thread_local8.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/decl2.c
Author: jason Date: Fri Jan 31 16:26:02 2014 New Revision: 207361 URL: http://gcc.gnu.org/viewcvs?rev=207361&root=gcc&view=rev Log: PR c++/55800 * decl2.c (get_tls_init_fn): Copy DECL_EXTERNAL from the variable. Added: branches/gcc-4_8-branch/gcc/testsuite/g++.dg/tls/thread_local8.C Modified: branches/gcc-4_8-branch/gcc/cp/ChangeLog branches/gcc-4_8-branch/gcc/cp/decl2.c