Bug 60702 - thread_local initialization
Summary: thread_local initialization
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: 7.5
Assignee: Jakub Jelinek
URL:
Keywords: wrong-code
: 83568 89727 (view as bug list)
Depends on:
Blocks: 59994
  Show dependency treegraph
 
Reported: 2014-03-28 22:47 UTC by Stan Pavlovski
Modified: 2019-08-30 13:44 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 6.4.0, 7.2.0, 8.0
Last reconfirmed: 2018-10-25 00:00:00


Attachments
Gcc verbose output (1.44 KB, text/x-log)
2014-03-28 22:47 UTC, Stan Pavlovski
Details
Gcc temp output (74.50 KB, text/plain)
2014-03-28 22:48 UTC, Stan Pavlovski
Details
Source file (210 bytes, text/x-c++src)
2014-03-28 22:48 UTC, Stan Pavlovski
Details
Smaller testcase that reproduces the problem (201 bytes, text/plain)
2014-04-02 22:44 UTC, arturomdn
Details
gcc9-pr60702.patch (1.80 KB, patch)
2019-03-15 16:39 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stan Pavlovski 2014-03-28 22:47:47 UTC
Created attachment 32480 [details]
Gcc verbose output

Invalid thread local object initialization.
Snippet:

#include <iostream>
 
using namespace std;
 
struct far {
    struct boo {
        boo () {
            cerr << "bar::boo" << endl;
        }
        int i = 42;
    };
     
    static void baz() {
        cerr << far::FOO.i << endl;
    }
     
    static thread_local boo FOO;
};

thread_local typename far::boo far::FOO;
 
int main() {
    far f;
    cerr << f.FOO.i << endl;
    cerr << far::FOO.i << endl;
    return 0;
}

Output:
0
bar::boo
42
Comment 1 Stan Pavlovski 2014-03-28 22:48:42 UTC
Created attachment 32481 [details]
Gcc temp output
Comment 2 Stan Pavlovski 2014-03-28 22:48:59 UTC
Created attachment 32482 [details]
Source file
Comment 3 Stan Pavlovski 2014-03-28 22:51:59 UTC
Template class' thread_local member is not initialized unless other non-template class' thread_local member is initialized first:

#include <iostream>
 
using namespace std;
 
struct far {
    struct boo {
        boo () {
            cerr << "far::boo" << endl;
        }
        int i = 42;
    };
     
    static void baz() {
        cerr << far::FOO.i << endl;
    }
     
    static thread_local boo FOO;
};
 
template<class T>
struct bar {
    struct foo {
        foo () {
            cerr << "bar::foo" << endl;
        }
        int i = 42;
    };
     
    void baz() {
        cerr << bar::FOO.i << endl;
    }
     
    static thread_local foo FOO;
};
 
template<class T> thread_local typename bar<T>::foo bar<T>::FOO;
thread_local typename far::boo far::FOO;
 
int main() {
    bar<int> b;
    b.baz();
     
    far f;
    f.baz();
    return 0;
}

Output:

0
far::boo
bar::foo
42
Comment 4 arturomdn 2014-04-02 22:44:28 UTC
Created attachment 32528 [details]
Smaller testcase that reproduces the problem

clang had the same problem, this smaller test was submitted to the clang team and they identified it as a duplicate of a recently fixed bug:

http://llvm.org/bugs/show_bug.cgi?id=19254

Which was fixed as follows

http://llvm.org/viewvc/llvm-project?view=revision&revision=204869

With the following comment:

PR19254: If a thread_local data member of a class is accessed via member access
syntax, don't forget to run its initializer.
Comment 5 Kan Wang 2017-11-14 02:24:04 UTC
+1 for this. If class member has thread-local storage and is first accessed through member access operator (e.g. a.foo), it is not initialized as expected.

The short code snippet below reproduces the bug on g++ 4.8 - 7.1

#include <iostream>
int init() {
    std::cout << "init" << std::endl;
    return 0;
}

struct A {
    static thread_local int foo;
};
thread_local int A::foo { init() };

int main() {
    A a;
    int i = a.foo;
    std::cout << "--- should be initialized above ---" << std::endl;
    i = A::foo;
    return i;
}

Output:
--- should be initialized above ---
init
Comment 6 Jonathan Wakely 2018-10-25 10:50:22 UTC
*** Bug 83568 has been marked as a duplicate of this bug. ***
Comment 7 Jonathan Wakely 2018-10-25 10:58:47 UTC
Another wrong-code example taken from https://gcc.gnu.org/ml/gcc-help/2018-10/msg00116.html


class B
{
  int* x;
public:
  static thread_local B tmp;
  B() { x = new int(); }
  void f() { *x = 0; }
};

thread_local B B::tmp;

template<class T>
void f()
{
  B::tmp.f();
}

void g()
{
  B::tmp.f();
}

int main()
{
  //g();
  f<int>();
}


Unless the non-template g() is called first, the thread_local variable isn't initialized.
Comment 8 Jonathan Wakely 2019-03-15 13:59:41 UTC
*** Bug 89727 has been marked as a duplicate of this bug. ***
Comment 9 Jakub Jelinek 2019-03-15 15:33:53 UTC
When looking at GIMPLE dump on:
struct S { S (); ~S (); int i; };
thread_local S s;
struct T { static thread_local S u; } t;
thread_local S T::u;

S *f1 () { return &s; }
int *f2 () { return &s.i; }
S *f3 () { return &t.u; }
int *f4 () { return &t.u.i; }
S *f5 () { return &T::u; }
int *f6 () { return &T::u.i; }
template <int N>
S *f7 () { return &s; }
template <int N>
int *f8 () { return &s.i; }
template <int N>
S *f9 () { return &t.u; }
template <int N>
int *f10 () { return &t.u.i; }
template <int N>
S *f11 () { return &T::u; }
template <int N>
int *f12 () { return &T::u.i; }
void foo ()
{
  f7<0> ();
  f8<0> ();
  f9<0> ();
  f10<0> ();
  f11<0> ();
  f12<0> ();
}

the following patch fixes all but f12:
--- gcc/cp/typeck.c.jj	2019-03-13 21:21:27.000000000 +0100
+++ gcc/cp/typeck.c	2019-03-15 16:23:27.582046214 +0100
@@ -2443,6 +2443,16 @@ build_class_member_access_expr (cp_expr
       /* A static data member.  */
       result = member;
       mark_exp_read (object);
+
+      tree wrap;
+      if (!cp_unevaluated_operand
+	  && !processing_template_decl
+	  && CP_DECL_THREAD_LOCAL_P (result)
+	  && (wrap = get_tls_wrapper_fn (result)))
+	/* Replace an evaluated use of the thread_local variable with
+	   a call to its wrapper.  */
+	result = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
+
       /* If OBJECT has side-effects, they are supposed to occur.  */
       if (TREE_SIDE_EFFECTS (object))
 	result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
Comment 10 Jakub Jelinek 2019-03-15 16:39:02 UTC
Created attachment 45976 [details]
gcc9-pr60702.patch

Untested fix.
Comment 11 Iain Sandoe 2019-03-22 09:27:59 UTC
(In reply to Jakub Jelinek from comment #10)
> Created attachment 45976 [details]
> gcc9-pr60702.patch
> 
> Untested fix.

For emulated TLS on x86_64-Darwin16, this progresses 
thread_local12c.C 
thread_local12d.C
thread_local12i.C
thread_local12j.C
thread_local12l.C

which fail without the patch and pass with it,

thread_local11.C 
fails for every instance of _ZTH*
(passes for _ZTW* 2 gimple)
Comment 12 Jakub Jelinek 2019-03-22 14:43:28 UTC
Author: jakub
Date: Fri Mar 22 14:42:57 2019
New Revision: 269875

URL: https://gcc.gnu.org/viewcvs?rev=269875&root=gcc&view=rev
Log:
	PR c++/60702
	* cp-tree.h (get_tls_wrapper_fn): Remove declaration.
	(maybe_get_tls_wrapper_call): Declare.
	* decl2.c (get_tls_wrapper_fn): Make static.
	(maybe_get_tls_wrapper_call): New function.
	* typeck.c (build_class_member_access_expr): Handle accesses to TLS
	variables.
	* semantics.c (finish_qualified_id_expr): Likewise.
	(finish_id_expression_1): Use maybe_get_tls_wrapper_call.
	* pt.c (tsubst_copy_and_build): Likewise.

	* g++.dg/tls/thread_local11.C: New test.
	* g++.dg/tls/thread_local11.h: New test.
	* g++.dg/tls/thread_local12a.C: New test.
	* g++.dg/tls/thread_local12b.C: New test.
	* g++.dg/tls/thread_local12c.C: New test.
	* g++.dg/tls/thread_local12d.C: New test.
	* g++.dg/tls/thread_local12e.C: New test.
	* g++.dg/tls/thread_local12f.C: New test.
	* g++.dg/tls/thread_local12g.C: New test.
	* g++.dg/tls/thread_local12h.C: New test.
	* g++.dg/tls/thread_local12i.C: New test.
	* g++.dg/tls/thread_local12j.C: New test.
	* g++.dg/tls/thread_local12k.C: New test.
	* g++.dg/tls/thread_local12l.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/tls/thread_local11.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local11.h
    trunk/gcc/testsuite/g++.dg/tls/thread_local12a.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12b.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12c.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12d.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12e.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12f.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12g.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12h.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12i.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12j.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12k.C
    trunk/gcc/testsuite/g++.dg/tls/thread_local12l.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl2.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/testsuite/ChangeLog
Comment 13 Jakub Jelinek 2019-03-22 15:01:10 UTC
(In reply to Iain Sandoe from comment #11)
> (In reply to Jakub Jelinek from comment #10)
> > Created attachment 45976 [details]
> > gcc9-pr60702.patch
> > 
> > Untested fix.
> 
> For emulated TLS on x86_64-Darwin16, this progresses 
> thread_local12c.C 
> thread_local12d.C
> thread_local12i.C
> thread_local12j.C
> thread_local12l.C
> 
> which fail without the patch and pass with it,
> 
> thread_local11.C 
> fails for every instance of _ZTH*
> (passes for _ZTW* 2 gimple)

Doesn't thread_local-wrap3.C FAIL then as well?
If yes, then perhaps:
--- gcc/testsuite/g++.dg/tls/thread_local11.C.jj	2019-03-22 15:42:02.506993141 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local11.C	2019-03-22 15:56:11.077364204 +0100
@@ -15,18 +15,18 @@
 // { dg-final { scan-tree-dump-times "_ZTWN1T2u6E" 2 "gimple" } }
 // { dg-final { scan-tree-dump-times "_ZTWN1T2u7E" 2 "gimple" } }
 // { dg-final { scan-tree-dump-times "_ZTWN1T2u8E" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTH2s4" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u1E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u2E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u3E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u4E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u5E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u6E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u7E" 1 "gimple" } }
-// { dg-final { scan-tree-dump-times "_ZTHN1T2u8E" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTH2s4" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u1E" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u2E" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u3E" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u4E" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u5E" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u6E" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u7E" 1 "gimple" { target tls_native } } }
+// { dg-final { scan-tree-dump-times "_ZTHN1T2u8E" 1 "gimple" { target tls_native } } }
 
 #include "thread_local11.h"
 
If that test doesn't fail, then perhaps instead:
--- gcc/testsuite/g++.dg/tls/thread_local11.C.jj	2019-03-22 15:42:02.506993141 +0100
+++ gcc/testsuite/g++.dg/tls/thread_local11.C	2019-03-22 16:00:08.863486555 +0100
@@ -1,6 +1,7 @@
 // PR c++/60702
 // { dg-do compile { target c++11 } }
 // { dg-add-options tls }
+// { dg-require-alias "" }
 // { dg-require-effective-target tls_runtime }
 // { dg-additional-options "-fdump-tree-gimple" }
 // { dg-final { scan-tree-dump-times "_ZTW2s1" 2 "gimple" } }

(sadly there is no effective target alias).
Comment 14 Iain Sandoe 2019-03-22 19:39:49 UTC
(In reply to Jakub Jelinek from comment #13)
> (In reply to Iain Sandoe from comment #11)
> > (In reply to Jakub Jelinek from comment #10)
> > > Created attachment 45976 [details]
> > > gcc9-pr60702.patch
> > > 
> > > Untested fix.
> > 
> > For emulated TLS on x86_64-Darwin16, this progresses 
> > thread_local12c.C 
> > thread_local12d.C
> > thread_local12i.C
> > thread_local12j.C
> > thread_local12l.C
> > 
> > which fail without the patch and pass with it,
> > 
> > thread_local11.C 
> > fails for every instance of _ZTH*
> > (passes for _ZTW* 2 gimple)
> 
> Doesn't thread_local-wrap3.C FAIL then as well?

No, because it already 
// { dg-require-alias "" }
so it's unsupported.


> --- gcc/testsuite/g++.dg/tls/thread_local11.C.jj	2019-03-22
> 15:42:02.506993141 +0100
> +++ gcc/testsuite/g++.dg/tls/thread_local11.C	2019-03-22 15:56:11.077364204
> +0100
> @@ -15,18 +15,18 @@
>  // { dg-final { scan-tree-dump-times "_ZTWN1T2u6E" 2 "gimple" } }
>  // { dg-final { scan-tree-dump-times "_ZTWN1T2u7E" 2 "gimple" } }
>  // { dg-final { scan-tree-dump-times "_ZTWN1T2u8E" 2 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTH2s4" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTHN1T2u1E" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTHN1T2u2E" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTHN1T2u3E" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTHN1T2u4E" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTHN1T2u5E" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTHN1T2u6E" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTHN1T2u7E" 1 "gimple" } }
> -// { dg-final { scan-tree-dump-times "_ZTHN1T2u8E" 1 "gimple" } }
> +// { dg-final { scan-tree-dump-times "_ZTH2s1" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTH2s2" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTH2s3" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTH2s4" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTHN1T2u1E" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTHN1T2u2E" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTHN1T2u3E" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTHN1T2u4E" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTHN1T2u5E" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTHN1T2u6E" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTHN1T2u7E" 1 "gimple" { target
> tls_native } } }
> +// { dg-final { scan-tree-dump-times "_ZTHN1T2u8E" 1 "gimple" { target
> tls_native } } }
>  
>  #include "thread_local11.h"

^^ works for me, results below.

I guess we could do something more clever to detect that the __tls_init calls are present for !tls_native.  c.f. PR84497 where we don't generate the call (not had a chance to analyse that yet).

===

Running /src/gcc-trunk/gcc/testsuite/g++.dg/tls/tls.exp ...

		=== g++ Summary for unix/-m64 ===

# of expected passes		307
# of expected failures		2
# of unsupported tests		55
Running target unix/-m32

Running /src/gcc-trunk/gcc/testsuite/g++.dg/tls/tls.exp ...

		=== g++ Summary for unix/-m32 ===

# of expected passes		307
# of expected failures		2
# of unsupported tests		55

		=== g++ Summary ===

# of expected passes		614
# of expected failures		4
# of unsupported tests		110
/scratch/10-12-sie/gcc-trunk-unpatched/gcc/testsuite/g++/../../xg++  version 9.0.1 20190322 (experimental) [trunk revision 269875] (GCC)
Comment 15 Jakub Jelinek 2019-03-25 11:34:14 UTC
I think the dg-require-alias is the right thing though, this is not related to native vs. non-native TLS, but:
  /* If the variable is internal, or if we can't generate aliases,
     call the local init function directly.  */
  if (!TREE_PUBLIC (var) || !TARGET_SUPPORTS_ALIASES)
    return get_local_tls_init_fn (DECL_SOURCE_LOCATION (var));
Comment 16 Iain Sandoe 2019-03-25 11:41:32 UTC
(In reply to Jakub Jelinek from comment #15)
> I think the dg-require-alias is the right thing though, this is not related
> to native vs. non-native TLS, but:
>   /* If the variable is internal, or if we can't generate aliases,
>      call the local init function directly.  */
>   if (!TREE_PUBLIC (var) || !TARGET_SUPPORTS_ALIASES)
>     return get_local_tls_init_fn (DECL_SOURCE_LOCATION (var));

yeah, that's fair enough.  Perhaps an additional test can be added when there's more time (that checks for the __init_tls calls instead of the aliased refs to it).
Comment 17 Jakub Jelinek 2019-03-25 11:54:28 UTC
Author: jakub
Date: Mon Mar 25 11:53:56 2019
New Revision: 269912

URL: https://gcc.gnu.org/viewcvs?rev=269912&root=gcc&view=rev
Log:
	PR c++/60702
	* g++.dg/tls/thread_local11.C: Remove scan-tree-dump-times directives
	for _ZTH* calls.
	* g++.dg/tls/thread_local11a.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/tls/thread_local11a.C
Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/tls/thread_local11.C
Comment 18 Jakub Jelinek 2019-03-25 11:56:36 UTC
Should be fixed on the trunk now.
Comment 19 Jakub Jelinek 2019-04-30 20:53:25 UTC
Author: jakub
Date: Tue Apr 30 20:52:54 2019
New Revision: 270739

URL: https://gcc.gnu.org/viewcvs?rev=270739&root=gcc&view=rev
Log:
	Backported from mainline
	2019-03-22  Jakub Jelinek  <jakub@redhat.com>

	PR c++/60702
	* cp-tree.h (get_tls_wrapper_fn): Remove declaration.
	(maybe_get_tls_wrapper_call): Declare.
	* decl2.c (get_tls_wrapper_fn): Make static.
	(maybe_get_tls_wrapper_call): New function.
	* typeck.c (build_class_member_access_expr): Handle accesses to TLS
	variables.
	* semantics.c (finish_qualified_id_expr): Likewise.
	(finish_id_expression_1): Use maybe_get_tls_wrapper_call.
	* pt.c (tsubst_copy_and_build): Likewise.

	* g++.dg/tls/thread_local11.C: New test.
	* g++.dg/tls/thread_local11.h: New test.
	* g++.dg/tls/thread_local12a.C: New test.
	* g++.dg/tls/thread_local12b.C: New test.
	* g++.dg/tls/thread_local12c.C: New test.
	* g++.dg/tls/thread_local12d.C: New test.
	* g++.dg/tls/thread_local12e.C: New test.
	* g++.dg/tls/thread_local12f.C: New test.
	* g++.dg/tls/thread_local12g.C: New test.
	* g++.dg/tls/thread_local12h.C: New test.
	* g++.dg/tls/thread_local12i.C: New test.
	* g++.dg/tls/thread_local12j.C: New test.
	* g++.dg/tls/thread_local12k.C: New test.
	* g++.dg/tls/thread_local12l.C: New test.

Added:
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local11.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local11.h
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12a.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12b.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12c.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12d.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12e.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12f.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12g.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12h.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12i.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12j.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12k.C
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local12l.C
Modified:
    branches/gcc-8-branch/gcc/cp/ChangeLog
    branches/gcc-8-branch/gcc/cp/cp-tree.h
    branches/gcc-8-branch/gcc/cp/decl2.c
    branches/gcc-8-branch/gcc/cp/pt.c
    branches/gcc-8-branch/gcc/cp/semantics.c
    branches/gcc-8-branch/gcc/cp/typeck.c
    branches/gcc-8-branch/gcc/testsuite/ChangeLog
Comment 20 Jakub Jelinek 2019-04-30 20:54:01 UTC
Author: jakub
Date: Tue Apr 30 20:53:29 2019
New Revision: 270740

URL: https://gcc.gnu.org/viewcvs?rev=270740&root=gcc&view=rev
Log:
	Backported from mainline
	2019-03-25  Jakub Jelinek  <jakub@redhat.com>

	PR c++/60702
	* g++.dg/tls/thread_local11.C: Remove scan-tree-dump-times directives
	for _ZTH* calls.
	* g++.dg/tls/thread_local11a.C: New test.

Added:
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local11a.C
Modified:
    branches/gcc-8-branch/gcc/testsuite/ChangeLog
    branches/gcc-8-branch/gcc/testsuite/g++.dg/tls/thread_local11.C
Comment 21 Jakub Jelinek 2019-05-01 07:05:40 UTC
Fixed for 8.4+ too.
Comment 22 Jakub Jelinek 2019-08-30 12:31:20 UTC
Author: jakub
Date: Fri Aug 30 12:30:48 2019
New Revision: 275140

URL: https://gcc.gnu.org/viewcvs?rev=275140&root=gcc&view=rev
Log:
	Backported from mainline
	2019-03-22  Jakub Jelinek  <jakub@redhat.com>

	PR c++/60702
	* cp-tree.h (get_tls_wrapper_fn): Remove declaration.
	(maybe_get_tls_wrapper_call): Declare.
	* decl2.c (get_tls_wrapper_fn): Make static.
	(maybe_get_tls_wrapper_call): New function.
	* typeck.c (build_class_member_access_expr): Handle accesses to TLS
	variables.
	* semantics.c (finish_qualified_id_expr): Likewise.
	(finish_id_expression_1): Use maybe_get_tls_wrapper_call.
	* pt.c (tsubst_copy_and_build): Likewise.

	* g++.dg/tls/thread_local11.C: New test.
	* g++.dg/tls/thread_local11.h: New test.
	* g++.dg/tls/thread_local12a.C: New test.
	* g++.dg/tls/thread_local12b.C: New test.
	* g++.dg/tls/thread_local12c.C: New test.
	* g++.dg/tls/thread_local12d.C: New test.
	* g++.dg/tls/thread_local12e.C: New test.
	* g++.dg/tls/thread_local12f.C: New test.
	* g++.dg/tls/thread_local12g.C: New test.
	* g++.dg/tls/thread_local12h.C: New test.
	* g++.dg/tls/thread_local12i.C: New test.
	* g++.dg/tls/thread_local12j.C: New test.
	* g++.dg/tls/thread_local12k.C: New test.
	* g++.dg/tls/thread_local12l.C: New test.

Added:
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local11.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local11.h
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12a.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12b.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12c.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12d.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12e.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12f.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12g.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12h.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12i.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12j.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12k.C
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local12l.C
Modified:
    branches/gcc-7-branch/gcc/cp/ChangeLog
    branches/gcc-7-branch/gcc/cp/cp-tree.h
    branches/gcc-7-branch/gcc/cp/decl2.c
    branches/gcc-7-branch/gcc/cp/pt.c
    branches/gcc-7-branch/gcc/cp/semantics.c
    branches/gcc-7-branch/gcc/cp/typeck.c
    branches/gcc-7-branch/gcc/testsuite/ChangeLog
Comment 23 Jakub Jelinek 2019-08-30 12:31:59 UTC
Author: jakub
Date: Fri Aug 30 12:31:21 2019
New Revision: 275141

URL: https://gcc.gnu.org/viewcvs?rev=275141&root=gcc&view=rev
Log:
	Backported from mainline
	2019-03-25  Jakub Jelinek  <jakub@redhat.com>

	PR c++/60702
	* g++.dg/tls/thread_local11.C: Remove scan-tree-dump-times directives
	for _ZTH* calls.
	* g++.dg/tls/thread_local11a.C: New test.

Added:
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local11a.C
Modified:
    branches/gcc-7-branch/gcc/testsuite/ChangeLog
    branches/gcc-7-branch/gcc/testsuite/g++.dg/tls/thread_local11.C
Comment 24 Jakub Jelinek 2019-08-30 13:44:20 UTC
Fixed.