title: Why does Apple clang disallow C++11 thread_local when 'official' clang supports it
body: <p>Below is a simple program that tests using a C++11 thread_local variable of non-POD type in a shared library.</p>
  
  <p>If I use homebrew clang, this works fine:</p>
  
  <pre><code>&gt; /usr/local/Cellar/llvm/3.5.0_2/bin/clang --version                                          
  clang version 3.5.0 (tags/RELEASE_350/final)
  Target: x86_64-apple-darwin14.0.0
  Thread model: posix
  
  &gt; cmake .. -G Ninja -DCMAKE_C_COMPILER=/usr/local/Cellar/llvm/3.5.0_2/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/Cellar/llvm/3.5.0_2/bin/clang++
  -- The C compiler identification is Clang 3.5.0
  -- The CXX compiler identification is Clang 3.5.0
  -- Check for working C compiler using: Ninja
  -- Check for working C compiler using: Ninja -- works
  -- Detecting C compiler ABI info
  -- Detecting C compiler ABI info - done
  -- Check for working CXX compiler using: Ninja
  -- Check for working CXX compiler using: Ninja -- works
  -- Detecting CXX compiler ABI info
  -- Detecting CXX compiler ABI info - done
  -- Configuring done
  -- Generating done
  &gt; ninja all
  ...                                                                                      
  
  &gt;  ./main                                                                                       
  XXX LifeCycle::LifeCycle 0x7fedc0c04b90
  X before: -17
  XXX LifeCycle::LifeCycle 0x7fedc0c04c10
  X before in thread: -17
  X after in thread: 2
  XXX LifeCycle::~LifeCycle 0x7fedc0c04c10
  X after: 1
  XXX LifeCycle::~LifeCycle 0x7fedc0c04b90
  </code></pre>
  
  <p>However, if I try to use Apple Clang, I get an error message saying that it is not supported:</p>
  
  <pre><code>&gt; /usr/bin/clang --version
  Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
  Target: x86_64-apple-darwin14.0.0
  Thread model: posix
  &gt; cmake .. -G Ninja -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
  -- The C compiler identification is AppleClang 6.0.0.6000056
  -- The CXX compiler identification is AppleClang 6.0.0.6000056
  -- Check for working C compiler using: Ninja
  -- Check for working C compiler using: Ninja -- works
  -- Detecting C compiler ABI info
  -- Detecting C compiler ABI info - done
  -- Check for working CXX compiler using: Ninja
  -- Check for working CXX compiler using: Ninja -- works
  -- Detecting CXX compiler ABI info
  -- Detecting CXX compiler ABI info - done
  -- Configuring done
  -- Generating done
  -- Build files have been written to:
  
  &gt; ninja all
  [1/4] Building CXX object CMakeFiles/lib.dir/lib.cpp.o
  FAILED: /usr/bin/clang++   -Dlib_EXPORTS -Wall -std=c++11 -mmacosx-version-min=10.7 -stdlib=libc++ -fPIC -MMD -MT CMakeFiles/lib.dir/lib.cpp.o -MF CMakeFiles/lib.dir/lib.cpp.o.d -o CMakeFiles/lib.dir/lib.cpp.o -c ../lib.cpp
  ../lib.cpp:23:5: error: thread-local storage is unsupported for the current target
      thread_local LifeCycle lc;
      ^
  1 error generated.
  ninja: build stopped: subcommand failed.
  </code></pre>
  
  <p>Can anyone offer any insight into why Apple's clang variant cowardly refuses to honor thread_local, despite the fact that the underlying compiler supports it, and the generated code appears to work?</p>
  
  <p>lib.h:</p>
  
  <pre><code>#pragma once
  
  int doit(int) __attribute__((__visibility__("default")));
  </code></pre>
  
  <p>lib.cpp:</p>
  
  <pre><code>#include "lib.h"
  
  #include &lt;thread&gt;
  #include &lt;cstdlib&gt;
  #include &lt;cstdio&gt;
  
  namespace {
  
      class LifeCycle {
      public:
          LifeCycle()
              : x(-17) {
              printf("XXX LifeCycle::LifeCycle %p\n", this);
          }
  
          ~LifeCycle() {
              printf("XXX LifeCycle::~LifeCycle %p\n", this);
          }
  
          int x;
      };
  
      thread_local LifeCycle lc;
  } // namespace
  
  int doit(int arg) {
      printf("X before: %d\n", lc.x);
      lc.x = arg;
      std::thread xwriter([arg]() {
              if (lc.x == arg)
                  abort();
              printf("X before in thread: %d\n", lc.x);
              lc.x = arg + 1;
              printf("X after in thread: %d\n", lc.x);
          });
      xwriter.join();
      printf("X after: %d\n", lc.x);
      return (lc.x == arg ? EXIT_SUCCESS : EXIT_FAILURE);
  }
  </code></pre>
  
  <p>main.cpp:</p>
  
  <pre><code>#include "lib.h"
  
  int main(int argc, char* argv[]) {
      return doit(argc);
  }
  </code></pre>
  
  <p>CMakeLists.txt:</p>
  
  <pre><code>cmake_minimum_required(VERSION 3.1)
  
  set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -mmacosx-version-min=10.7 -stdlib=libc++")
  
  add_library(lib SHARED lib.cpp)
  add_executable(main main.cpp)
  target_link_libraries(main lib)
  </code></pre>