title: Gcc thread sanitizer false positive only for debug info flag
body: <p>I am having a problem with Gcc's thread sanitizer that I cannot find on their bugzilla or on stackoverflow so I am unsure if I am missing something or if this really is a bug. If I create a main.cpp file containing:</p>
  
  <pre><code>#include &lt;thread&gt;
  int main(){
      std::thread t([](){});
      t.join();
      return 0;}
  </code></pre>
  
  <p>Now if I compile it using:</p>
  
  <pre><code>g++-4.9.2 -std=c++1y -fsanitize=thread -fPIE -pie -o TestProgram main.cpp
  </code></pre>
  
  <p>Running the resulting executable does not yield any problem. Yet if I add the debug info flag:</p>
  
  <pre><code>g++-4.9.2 -std=c++1y -fsanitize=thread -g -fPIE -pie -o TestProgram main.cpp
  </code></pre>
  
  <p>then the thread sanitizer detects a data race:</p>
  
  <pre><code>WARNING: ThreadSanitizer: data race (pid=22683)
    Write of size 8 at 0x7d0c0000efd8 by thread T1:
      #0 operator delete(void*) ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:592 (libtsan.so.0+0x000000049490)
      #1 deallocate /usr/local/include/c++/4.9.2/ext/new_allocator.h:110 (TestProgram+0x000000002089)
      #2 deallocate /usr/local/include/c++/4.9.2/bits/alloc_traits.h:383 (TestProgram+0x000000001f78)
      #3 _M_destroy /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:535 (TestProgram+0x0000000026f4)
      #4 std::_Sp_counted_base&lt;(__gnu_cxx::_Lock_policy)2&gt;::_M_release() /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:166 (libstdc++.so.6+0x0000000b5c51)
      #5 ~__shared_count /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:666 (libstdc++.so.6+0x0000000b5c51)
      #6 ~__shared_ptr /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:914 (libstdc++.so.6+0x0000000b5c51)
      #7 ~shared_ptr /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr.h:93 (libstdc++.so.6+0x0000000b5c51)
      #8 execute_native_thread_routine ../../../../../gcc-4.9.2/libstdc++-v3/src/c++11/thread.cc:95 (libstdc++.so.6+0x0000000b5c51)
  
    Previous atomic write of size 4 at 0x7d0c0000efd8 by main thread:
      #0 __tsan_atomic32_fetch_add ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interface_atomic.cc:468 (libtsan.so.0+0x0000000206ce)
      #1 __exchange_and_add /usr/local/include/c++/4.9.2/ext/atomicity.h:49 (TestProgram+0x0000000014a0)
      #2 __exchange_and_add_dispatch /usr/local/include/c++/4.9.2/ext/atomicity.h:82 (TestProgram+0x000000001557)
      #3 std::_Sp_counted_base&lt;(__gnu_cxx::_Lock_policy)2&gt;::_M_release() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:146 (TestProgram+0x000000002ceb)
      #4 std::__shared_count&lt;(__gnu_cxx::_Lock_policy)2&gt;::~__shared_count() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:666 (TestProgram+0x000000002cb6)
      #5 std::__shared_ptr&lt;std::thread::_Impl_base, (__gnu_cxx::_Lock_policy)2&gt;::~__shared_ptr() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:914 (TestProgram+0x000000002bc1)
      #6 std::shared_ptr&lt;std::thread::_Impl_base&gt;::~shared_ptr() /usr/local/include/c++/4.9.2/bits/shared_ptr.h:93 (TestProgram+0x000000002bed)
      #7 thread&lt;main()::&lt;lambda()&gt; &gt; /usr/local/include/c++/4.9.2/thread:135 (TestProgram+0x0000000016f1)
      #8 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)
  
    Location is heap block of size 48 at 0x7d0c0000efd0 allocated by main thread:
      #0 operator new(unsigned long) ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:560 (libtsan.so.0+0x0000000496d2)
      #1 allocate /usr/local/include/c++/4.9.2/ext/new_allocator.h:104 (TestProgram+0x000000001fe9)
      #2 allocate /usr/local/include/c++/4.9.2/bits/alloc_traits.h:357 (TestProgram+0x000000001ecd)
      #3 __shared_count&lt;std::thread::_Impl&lt;std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt;, std::allocator&lt;std::thread::_Impl&lt;std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; &gt;, std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:616 (TestProgram+0x000000001d99)
      #4 __shared_ptr&lt;std::allocator&lt;std::thread::_Impl&lt;std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; &gt;, std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:1090 (TestProgram+0x000000001ccb)
      #5 shared_ptr&lt;std::allocator&lt;std::thread::_Impl&lt;std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; &gt;, std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; /usr/local/include/c++/4.9.2/bits/shared_ptr.h:316 (TestProgram+0x000000001c5f)
      #6 allocate_shared&lt;std::thread::_Impl&lt;std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt;, std::allocator&lt;std::thread::_Impl&lt;std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; &gt;, std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; /usr/local/include/c++/4.9.2/bits/shared_ptr.h:588 (TestProgram+0x000000001bf0)
      #7 make_shared&lt;std::thread::_Impl&lt;std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt;, std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; /usr/local/include/c++/4.9.2/bits/shared_ptr.h:604 (TestProgram+0x000000001ab0)
      #8 _M_make_routine&lt;std::_Bind_simple&lt;main()::&lt;lambda()&gt;()&gt; &gt; /usr/local/include/c++/4.9.2/thread:193 (TestProgram+0x000000001919)
      #9 thread&lt;main()::&lt;lambda()&gt; &gt; /usr/local/include/c++/4.9.2/thread:135 (TestProgram+0x0000000016bf)
      #10 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)
  
    Thread T1 (tid=22685, running) created by main thread at:
      #0 pthread_create ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:877 (libtsan.so.0+0x000000047c03)
      #1 __gthread_create /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/x86_64-unknown-linux-gnu/bits/gthr-default.h:662 (libstdc++.so.6+0x0000000b5d00)
      #2 std::thread::_M_start_thread(std::shared_ptr&lt;std::thread::_Impl_base&gt;) ../../../../../gcc-4.9.2/libstdc++-v3/src/c++11/thread.cc:142 (libstdc++.so.6+0x0000000b5d00)
      #3 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)
  
  SUMMARY: ThreadSanitizer: data race /usr/local/include/c++/4.9.2/ext/new_allocator.h:110 deallocate
  ==================
  ThreadSanitizer: reported 1 warnings
  </code></pre>
  
  <p>Now the exact same code compiled with clang++ (version 3.6.0 (trunk 221144)) does not detect a data race:</p>
  
  <pre><code>clang++ -std=c++1y -fsanitize=thread -g -fPIE -pie -o TestProgram main.cpp
  </code></pre>
  
  <p>I am a bit quizzical about this behavior from gcc as:
  1) passing an empty lambda function as an argument to a thread seems licit to me
  2) gcc's behavior depends on the -g flag which doesn't strike me as having much to do with the thread sanitizer
  3) under similar circumstances clang adopts a behavior that I would consider correct</p>
  
  <p>Many thanks,</p>