public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
@ 2015-06-25  3:19 Aldy Hernandez
  2015-06-25  9:49 ` Richard Biener
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Aldy Hernandez @ 2015-06-25  3:19 UTC (permalink / raw)
  To: gcc-patches, jason merrill

[-- Attachment #1: Type: text/plain, Size: 1658 bytes --]

The problem here is that we are trying to call 
dwarf2out_late_global_decl() on a static variable in a template which 
has a type of TEMPLATE_TYPE_PARM:

template <typename T> class A
{
   static __thread T a;
};

We are calling late_global_decl because we are about to remove the 
unused static from the symbol table:

	  /* See if the debugger can use anything before the DECL
	     passes away.  Perhaps it can notice a DECL that is now a
	     constant and can tag the early DIE with an appropriate
	     attribute.

	     Otherwise, this is the last chance the debug_hooks have
	     at looking at optimized away DECLs, since
	     late_global_decl will subsequently be called from the
	     contents of the now pruned symbol table.  */
	  if (!decl_function_context (node->decl))
	    (*debug_hooks->late_global_decl) (node->decl);

Since gen_type_die_with_usage() cannot handle TEMPLATE_TYPE_PARMs we ICE.

I think we need to avoid calling late_global_decl on DECL's for which 
decl_type_context() is true, similarly to what we do for the call to 
early_global_decl in rest_of_decl_compilation:

       && !decl_function_context (decl)
       && !current_function_decl
       && DECL_SOURCE_LOCATION (decl) != BUILTINS_LOCATION
       && !decl_type_context (decl))
     (*debug_hooks->early_global_decl) (decl);

Presumably the old code did not run into this problem because the 
TEMPLATE_TYPE_PARAMs had been lowered by the time dwarf2out_decl was 
called, but here we are calling late_global_decl relatively early.

The attached patch fixes the problem.

Tested with --enable-languages=all.  Ada had other issues, so I skipped it.

OK for mainline?

[-- Attachment #2: curr --]
[-- Type: text/plain, Size: 1173 bytes --]

commit 302f9976c53aa09e431bd54f37dbfeaa2c6b2acc
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Wed Jun 24 20:04:09 2015 -0700

    	PR debug/66653
    	* cgraphunit.c (analyze_functions): Do not call
    	debug_hooks->late_global_decl when decl_type_context.

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 066a155..d2974ad 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1149,7 +1149,8 @@ analyze_functions (bool first_time)
 	     at looking at optimized away DECLs, since
 	     late_global_decl will subsequently be called from the
 	     contents of the now pruned symbol table.  */
-	  if (!decl_function_context (node->decl))
+	  if (!decl_function_context (node->decl)
+	      && !decl_type_context (node->decl))
 	    (*debug_hooks->late_global_decl) (node->decl);
 
 	  node->remove ();
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pr66653.C b/gcc/testsuite/g++.dg/debug/dwarf2/pr66653.C
new file mode 100644
index 0000000..bcaaf88
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pr66653.C
@@ -0,0 +1,8 @@
+// PR debug/54508
+// { dg-do compile }
+// { dg-options "-g" }
+
+template <typename T> class A
+{
+  static __thread T a;
+};

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-25  3:19 [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s Aldy Hernandez
@ 2015-06-25  9:49 ` Richard Biener
  2015-06-25 15:08   ` Aldy Hernandez
  2015-06-25 13:56 ` Eric Botcazou
  2015-06-25 17:02 ` Jason Merrill
  2 siblings, 1 reply; 13+ messages in thread
From: Richard Biener @ 2015-06-25  9:49 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc-patches, jason merrill

On Thu, Jun 25, 2015 at 5:12 AM, Aldy Hernandez <aldyh@redhat.com> wrote:
> The problem here is that we are trying to call dwarf2out_late_global_decl()
> on a static variable in a template which has a type of TEMPLATE_TYPE_PARM:
>
> template <typename T> class A
> {
>   static __thread T a;
> };
>
> We are calling late_global_decl because we are about to remove the unused
> static from the symbol table:
>
>           /* See if the debugger can use anything before the DECL
>              passes away.  Perhaps it can notice a DECL that is now a
>              constant and can tag the early DIE with an appropriate
>              attribute.
>
>              Otherwise, this is the last chance the debug_hooks have
>              at looking at optimized away DECLs, since
>              late_global_decl will subsequently be called from the
>              contents of the now pruned symbol table.  */
>           if (!decl_function_context (node->decl))
>             (*debug_hooks->late_global_decl) (node->decl);
>
> Since gen_type_die_with_usage() cannot handle TEMPLATE_TYPE_PARMs we ICE.
>
> I think we need to avoid calling late_global_decl on DECL's for which
> decl_type_context() is true, similarly to what we do for the call to
> early_global_decl in rest_of_decl_compilation:
>
>       && !decl_function_context (decl)
>       && !current_function_decl
>       && DECL_SOURCE_LOCATION (decl) != BUILTINS_LOCATION
>       && !decl_type_context (decl))
>     (*debug_hooks->early_global_decl) (decl);
>
> Presumably the old code did not run into this problem because the
> TEMPLATE_TYPE_PARAMs had been lowered by the time dwarf2out_decl was called,
> but here we are calling late_global_decl relatively early.

I think we need to sort out that instead - by the time we call _early_
global decl it
should already be "lowered".  Otherwise LTO streaming will run into
the decl_type_context it cannot handle.  Is the case running into
late_global_decl
before we called early_global_decl on it btw?

Richard.

> The attached patch fixes the problem.
>
> Tested with --enable-languages=all.  Ada had other issues, so I skipped it.
>
> OK for mainline?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-25  3:19 [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s Aldy Hernandez
  2015-06-25  9:49 ` Richard Biener
@ 2015-06-25 13:56 ` Eric Botcazou
  2015-06-25 14:57   ` Aldy Hernandez
  2015-06-25 17:02 ` Jason Merrill
  2 siblings, 1 reply; 13+ messages in thread
From: Eric Botcazou @ 2015-06-25 13:56 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc-patches, jason merrill

> Tested with --enable-languages=all.  Ada had other issues, so I skipped it.

What other issues exactly?  It's fine at r224930 for example.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-25 13:56 ` Eric Botcazou
@ 2015-06-25 14:57   ` Aldy Hernandez
  2015-06-25 20:57     ` Eric Botcazou
  0 siblings, 1 reply; 13+ messages in thread
From: Aldy Hernandez @ 2015-06-25 14:57 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches, jason merrill

On 06/25/2015 06:53 AM, Eric Botcazou wrote:
>> Tested with --enable-languages=all.  Ada had other issues, so I skipped it.
>
> What other issues exactly?  It's fine at r224930 for example.
>

There were some defined but not used warnings (??) that caused it to 
fail, especially since I didn't configure with --disable-werror.  I 
didn't look into it.

Aldy

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-25  9:49 ` Richard Biener
@ 2015-06-25 15:08   ` Aldy Hernandez
  0 siblings, 0 replies; 13+ messages in thread
From: Aldy Hernandez @ 2015-06-25 15:08 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, jason merrill

On 06/25/2015 02:48 AM, Richard Biener wrote:
> On Thu, Jun 25, 2015 at 5:12 AM, Aldy Hernandez <aldyh@redhat.com> wrote:
>> The problem here is that we are trying to call dwarf2out_late_global_decl()
>> on a static variable in a template which has a type of TEMPLATE_TYPE_PARM:
>>
>> template <typename T> class A
>> {
>>    static __thread T a;
>> };
>>
>> We are calling late_global_decl because we are about to remove the unused
>> static from the symbol table:
>>
>>            /* See if the debugger can use anything before the DECL
>>               passes away.  Perhaps it can notice a DECL that is now a
>>               constant and can tag the early DIE with an appropriate
>>               attribute.
>>
>>               Otherwise, this is the last chance the debug_hooks have
>>               at looking at optimized away DECLs, since
>>               late_global_decl will subsequently be called from the
>>               contents of the now pruned symbol table.  */
>>            if (!decl_function_context (node->decl))
>>              (*debug_hooks->late_global_decl) (node->decl);
>>
>> Since gen_type_die_with_usage() cannot handle TEMPLATE_TYPE_PARMs we ICE.
>>
>> I think we need to avoid calling late_global_decl on DECL's for which
>> decl_type_context() is true, similarly to what we do for the call to
>> early_global_decl in rest_of_decl_compilation:
>>
>>        && !decl_function_context (decl)
>>        && !current_function_decl
>>        && DECL_SOURCE_LOCATION (decl) != BUILTINS_LOCATION
>>        && !decl_type_context (decl))
>>      (*debug_hooks->early_global_decl) (decl);
>>
>> Presumably the old code did not run into this problem because the
>> TEMPLATE_TYPE_PARAMs had been lowered by the time dwarf2out_decl was called,
>> but here we are calling late_global_decl relatively early.
>
> I think we need to sort out that instead - by the time we call _early_
> global decl it
> should already be "lowered".  Otherwise LTO streaming will run into
> the decl_type_context it cannot handle.  Is the case running into
> late_global_decl
> before we called early_global_decl on it btw?

Typically in C++ we call early_global_decl via:

	cp_finish_decl
	  -> make_rtl_for_nonlocal_decl
	    -> rest_of_decl_compilation
	      -> early_global_decl.

However, in this case we have not called early_global_decl on the DECL 
because cp_finish_decl avoids the make_rtl_for_nonlocal_decl path for 
templates:

cp_finish_decl():
   ...
   if (processing_template_decl)
     {
       bool type_dependent_p;
       ...
       ...
       return;
     }

Aldy

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-25  3:19 [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s Aldy Hernandez
  2015-06-25  9:49 ` Richard Biener
  2015-06-25 13:56 ` Eric Botcazou
@ 2015-06-25 17:02 ` Jason Merrill
  2015-06-26  9:40   ` Richard Biener
  2 siblings, 1 reply; 13+ messages in thread
From: Jason Merrill @ 2015-06-25 17:02 UTC (permalink / raw)
  To: Aldy Hernandez, gcc-patches, Jan Hubicka

On 06/24/2015 11:12 PM, Aldy Hernandez wrote:
> The problem here is that we are trying to call
> dwarf2out_late_global_decl() on a static variable in a template which
> has a type of TEMPLATE_TYPE_PARM:
>
> template <typename T> class A
> {
>    static __thread T a;
> };
>
> We are calling late_global_decl because we are about to remove the
> unused static from the symbol table:

The problem here is that 'a' should never have been in the symbol table 
in the first place, since it's an uninstantiated template.  It's there 
because of honza's change to store the TLS model in the symbol table, so 
TLS templates end up with varpool entries that, of course, will never be 
referenced.

I guess either we need to avoid putting these templates in the symbol 
table or we need to mark these fake entries somehow.

Jason

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-25 14:57   ` Aldy Hernandez
@ 2015-06-25 20:57     ` Eric Botcazou
  0 siblings, 0 replies; 13+ messages in thread
From: Eric Botcazou @ 2015-06-25 20:57 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc-patches, jason merrill

> There were some defined but not used warnings (??) that caused it to
> fail, especially since I didn't configure with --disable-werror.

Weird.  I bootstrap the compiler in default mode every day and I haven't had a 
bootstrap failure for at least a month.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-25 17:02 ` Jason Merrill
@ 2015-06-26  9:40   ` Richard Biener
  2015-06-26 22:04     ` Jason Merrill
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Biener @ 2015-06-26  9:40 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Aldy Hernandez, gcc-patches, Jan Hubicka

On Thu, Jun 25, 2015 at 6:56 PM, Jason Merrill <jason@redhat.com> wrote:
> On 06/24/2015 11:12 PM, Aldy Hernandez wrote:
>>
>> The problem here is that we are trying to call
>> dwarf2out_late_global_decl() on a static variable in a template which
>> has a type of TEMPLATE_TYPE_PARM:
>>
>> template <typename T> class A
>> {
>>    static __thread T a;
>> };
>>
>> We are calling late_global_decl because we are about to remove the
>> unused static from the symbol table:
>
>
> The problem here is that 'a' should never have been in the symbol table in
> the first place, since it's an uninstantiated template.  It's there because
> of honza's change to store the TLS model in the symbol table, so TLS
> templates end up with varpool entries that, of course, will never be
> referenced.

Can we defer TLS model setting to template instantiation?

> I guess either we need to avoid putting these templates in the symbol table
> or we need to mark these fake entries somehow.
>
> Jason
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-26  9:40   ` Richard Biener
@ 2015-06-26 22:04     ` Jason Merrill
  2015-06-29  9:14       ` Richard Biener
  0 siblings, 1 reply; 13+ messages in thread
From: Jason Merrill @ 2015-06-26 22:04 UTC (permalink / raw)
  To: Richard Biener; +Cc: Aldy Hernandez, gcc-patches, Jan Hubicka

On 06/26/2015 05:37 AM, Richard Biener wrote:
> Can we defer TLS model setting to template instantiation?

We need to represent somehow that __thread (or thread_local) was used in 
the declaration, but DECL_THREAD_LOCAL_P was changed to refer to the TLS 
model.

Jason

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-26 22:04     ` Jason Merrill
@ 2015-06-29  9:14       ` Richard Biener
  2015-06-29 22:35         ` Jason Merrill
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Biener @ 2015-06-29  9:14 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Aldy Hernandez, gcc-patches, Jan Hubicka

On Fri, Jun 26, 2015 at 11:59 PM, Jason Merrill <jason@redhat.com> wrote:
> On 06/26/2015 05:37 AM, Richard Biener wrote:
>>
>> Can we defer TLS model setting to template instantiation?
>
>
> We need to represent somehow that __thread (or thread_local) was used in the
> declaration, but DECL_THREAD_LOCAL_P was changed to refer to the TLS model.

Ok, so "easiest" would be to allocate a bit from decl_with_vis for this...

Richard.

> Jason
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-29  9:14       ` Richard Biener
@ 2015-06-29 22:35         ` Jason Merrill
  2015-06-30 14:43           ` Jason Merrill
  0 siblings, 1 reply; 13+ messages in thread
From: Jason Merrill @ 2015-06-29 22:35 UTC (permalink / raw)
  To: Richard Biener; +Cc: Aldy Hernandez, gcc-patches, Jan Hubicka

On 06/29/2015 05:07 AM, Richard Biener wrote:
> On Fri, Jun 26, 2015 at 11:59 PM, Jason Merrill <jason@redhat.com> wrote:
>> On 06/26/2015 05:37 AM, Richard Biener wrote:
>>>
>>> Can we defer TLS model setting to template instantiation?
>>
>> We need to represent somehow that __thread (or thread_local) was used in the
>> declaration, but DECL_THREAD_LOCAL_P was changed to refer to the TLS model.
>
> Ok, so "easiest" would be to allocate a bit from decl_with_vis for this...

Or I can find a flag in the front end.  I guess I'll do that.

Jason

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-29 22:35         ` Jason Merrill
@ 2015-06-30 14:43           ` Jason Merrill
  2015-07-01  7:39             ` Richard Biener
  0 siblings, 1 reply; 13+ messages in thread
From: Jason Merrill @ 2015-06-30 14:43 UTC (permalink / raw)
  To: Richard Biener; +Cc: Aldy Hernandez, gcc-patches, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 615 bytes --]

On 06/29/2015 06:32 PM, Jason Merrill wrote:
> On 06/29/2015 05:07 AM, Richard Biener wrote:
>> On Fri, Jun 26, 2015 at 11:59 PM, Jason Merrill <jason@redhat.com> wrote:
>>> On 06/26/2015 05:37 AM, Richard Biener wrote:
>>>>
>>>> Can we defer TLS model setting to template instantiation?
>>>
>>> We need to represent somehow that __thread (or thread_local) was used in the
>>> declaration, but DECL_THREAD_LOCAL_P was changed to refer to the TLS model.
>>
>> Ok, so "easiest" would be to allocate a bit from decl_with_vis for this...
>
> Or I can find a flag in the front end.  I guess I'll do that.

Thus.

Jason


[-- Attachment #2: 66653.patch --]
[-- Type: text/x-patch, Size: 15775 bytes --]

commit fcc92fd874243b1366dcbd75ff32cc8862d8ec52
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jun 29 15:30:35 2015 -0400

    	PR debug/66653
    	* cp-tree.h (CP_DECL_THREAD_LOCAL_P): New.
    	(DECL_GNU_TLS_P): Use DECL_LANG_SPECIFIC field.
    	(SET_DECL_GNU_TLS_P): New.
    	* call.c (make_temporary_var_for_ref_to_temp): Use
    	CP_DECL_THREAD_LOCAL_P.
    	(set_up_extended_ref_temp): Likewise.
    	* decl.c (duplicate_decls, expand_static_init): Likewise.
    	(redeclaration_error_message, grokvardecl): Likewise.
    	(start_decl, register_dtor_fn, grokdeclarator): Likewise.
    	* decl2.c (get_guard, var_needs_tls_wrapper): Likewise.
    	(handle_tls_init): Likewise.
    	* pt.c (tsubst_decl, tsubst_copy_and_build): Likewise.
    	* semantics.c (finish_id_expression): Likewise.
    	(handle_omp_array_sections_1, finish_omp_clauses): Likewise.
    	(finish_omp_threadprivate): Likewise.
    	* tree.c (decl_storage_duration): Likewise.
    	* cp-gimplify.c (omp_var_to_track): Likewise.
    	(cp_genericize_r): Check that it matches DECL_THREAD_LOCAL_P.
    	* lex.c (retrofit_lang_decl): Return if DECL_LANG_SPECIFIC is
    	already set.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index b846919..44346bf 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -9556,13 +9556,14 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
 
   /* Register the variable.  */
   if (VAR_P (decl)
-      && (TREE_STATIC (decl) || DECL_THREAD_LOCAL_P (decl)))
+      && (TREE_STATIC (decl) || CP_DECL_THREAD_LOCAL_P (decl)))
     {
       /* Namespace-scope or local static; give it a mangled name.  */
       /* FIXME share comdat with decl?  */
       tree name;
 
       TREE_STATIC (var) = TREE_STATIC (decl);
+      CP_DECL_THREAD_LOCAL_P (var) = CP_DECL_THREAD_LOCAL_P (decl);
       set_decl_tls_model (var, DECL_TLS_MODEL (decl));
       name = mangle_ref_init_variable (decl);
       DECL_NAME (var) = name;
@@ -9683,7 +9684,7 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
       rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
       if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
 	{
-	  if (DECL_THREAD_LOCAL_P (var))
+	  if (CP_DECL_THREAD_LOCAL_P (var))
 	    tls_aggregates = tree_cons (NULL_TREE, var,
 					tls_aggregates);
 	  else
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 1a627db..b95489e 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -831,7 +831,7 @@ omp_var_to_track (tree decl)
     type = TREE_TYPE (type);
   if (type == error_mark_node || !CLASS_TYPE_P (type))
     return false;
-  if (VAR_P (decl) && DECL_THREAD_LOCAL_P (decl))
+  if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl))
     return false;
   if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
     return false;
@@ -1157,6 +1157,12 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
       *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
       *walk_subtrees = 0;
     }
+  else if (TREE_CODE (stmt) == DECL_EXPR)
+    {
+      tree d = DECL_EXPR_DECL (stmt);
+      if (TREE_CODE (d) == VAR_DECL)
+	gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
+    }
   else if (TREE_CODE (stmt) == OMP_PARALLEL || TREE_CODE (stmt) == OMP_TASK)
     {
       struct cp_genericize_omp_taskreg omp_ctx;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e8cc38f..18cf87e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -51,7 +51,7 @@ c-common.h, not after.
       AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
       PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF, SCOPE_REF)
       PAREN_STRING_LITERAL (in STRING_CST)
-      DECL_GNU_TLS_P (in VAR_DECL)
+      CP_DECL_THREAD_LOCAL_P (in VAR_DECL)
       KOENIG_LOOKUP_P (in CALL_EXPR)
       STATEMENT_LIST_NO_SCOPE (in STATEMENT_LIST).
       EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT)
@@ -2017,7 +2017,7 @@ struct GTY(()) lang_decl_base {
   unsigned repo_available_p : 1;	   /* var or fn */
   unsigned threadprivate_or_deleted_p : 1; /* var or fn */
   unsigned anticipated_p : 1;		   /* fn, type or template */
-  unsigned friend_attr : 1;		   /* fn, type or template */
+  unsigned friend_or_tls : 1;		   /* var, fn, type or template */
   unsigned template_conv_p : 1;		   /* var or template */
   unsigned odr_used : 1;		   /* var or fn */
   unsigned u2sel : 1;
@@ -2438,7 +2438,16 @@ struct GTY(()) lang_decl {
    and should not be added to the list of members for this class.  */
 #define DECL_FRIEND_P(NODE) \
   (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \
-   ->u.base.friend_attr)
+   ->u.base.friend_or_tls)
+
+/* Nonzero if the thread-local variable was declared with __thread as
+   opposed to thread_local.  */
+#define DECL_GNU_TLS_P(NODE)				\
+  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))		\
+   && DECL_LANG_SPECIFIC (NODE)->u.base.friend_or_tls)
+#define SET_DECL_GNU_TLS_P(NODE)				\
+  (retrofit_lang_decl (VAR_DECL_CHECK (NODE)),			\
+   DECL_LANG_SPECIFIC (NODE)->u.base.friend_or_tls = true)
 
 /* A TREE_LIST of the types which have befriended this FUNCTION_DECL.  */
 #define DECL_BEFRIENDING_CLASSES(NODE) \
@@ -2566,9 +2575,11 @@ struct GTY(()) lang_decl {
   (DECL_NAME (NODE) \
    && !strcmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__PRETTY_FUNCTION__"))
 
-/* Nonzero if the thread-local variable was declared with __thread
-   as opposed to thread_local.  */
-#define DECL_GNU_TLS_P(NODE) \
+/* Nonzero if the variable was declared to be thread-local.
+   We need a special C++ version of this test because the middle-end
+   DECL_THREAD_LOCAL_P uses the symtab, so we can't use it for
+   templates.  */
+#define CP_DECL_THREAD_LOCAL_P(NODE) \
   (TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE)))
 
 /* The _TYPE context in which this _DECL appears.  This field holds the
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a4fbab4..8bea2e3 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2523,8 +2523,12 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	}
 
       if (VAR_P (newdecl)
-	  && DECL_THREAD_LOCAL_P (newdecl))
-	set_decl_tls_model (olddecl, DECL_TLS_MODEL (newdecl));
+	  && CP_DECL_THREAD_LOCAL_P (newdecl))
+	{
+	  CP_DECL_THREAD_LOCAL_P (olddecl) = true;
+	  if (!processing_template_decl)
+	    set_decl_tls_model (olddecl, DECL_TLS_MODEL (newdecl));
+	}
     }
 
   DECL_UID (olddecl) = olddecl_uid;
@@ -2702,14 +2706,14 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       return NULL;
     }
   else if (VAR_P (newdecl)
-	   && DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl)
+	   && CP_DECL_THREAD_LOCAL_P (newdecl) != CP_DECL_THREAD_LOCAL_P (olddecl)
 	   && (! DECL_LANG_SPECIFIC (olddecl)
 	       || ! CP_DECL_THREADPRIVATE_P (olddecl)
-	       || DECL_THREAD_LOCAL_P (newdecl)))
+	       || CP_DECL_THREAD_LOCAL_P (newdecl)))
     {
       /* Only variables can be thread-local, and all declarations must
 	 agree on this property.  */
-      if (DECL_THREAD_LOCAL_P (newdecl))
+      if (CP_DECL_THREAD_LOCAL_P (newdecl))
 	return G_("thread-local declaration of %q#D follows "
 	          "non-thread-local declaration");
       else
@@ -4861,7 +4865,7 @@ start_decl (const cp_declarator *declarator,
       && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
     {
       bool ok = false;
-      if (DECL_THREAD_LOCAL_P (decl))
+      if (CP_DECL_THREAD_LOCAL_P (decl))
 	error ("%qD declared %<thread_local%> in %<constexpr%> function",
 	       decl);
       else if (TREE_STATIC (decl))
@@ -7058,7 +7062,7 @@ register_dtor_fn (tree decl)
      function to do the cleanup.  */
   dso_parm = (flag_use_cxa_atexit
 	      && !targetm.cxx.use_atexit_for_cxa_atexit ());
-  ob_parm = (DECL_THREAD_LOCAL_P (decl) || dso_parm);
+  ob_parm = (CP_DECL_THREAD_LOCAL_P (decl) || dso_parm);
   use_dtor = ob_parm && CLASS_TYPE_P (type);
   if (use_dtor)
     {
@@ -7101,7 +7105,7 @@ register_dtor_fn (tree decl)
   mark_used (cleanup);
   cleanup = build_address (cleanup);
 
-  if (DECL_THREAD_LOCAL_P (decl))
+  if (CP_DECL_THREAD_LOCAL_P (decl))
     atex_node = get_thread_atexit_node ();
   else
     atex_node = get_atexit_node ();
@@ -7141,7 +7145,7 @@ register_dtor_fn (tree decl)
 
   if (ob_parm)
     {
-      if (!DECL_THREAD_LOCAL_P (decl)
+      if (!CP_DECL_THREAD_LOCAL_P (decl)
 	  && targetm.cxx.use_aeabi_atexit ())
 	{
 	  arg1 = cleanup;
@@ -7181,7 +7185,7 @@ expand_static_init (tree decl, tree init)
 	return;
     }
 
-  if (DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
+  if (CP_DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
       && !DECL_FUNCTION_SCOPE_P (decl))
     {
       if (init)
@@ -7210,7 +7214,7 @@ expand_static_init (tree decl, tree init)
       tree flag, begin;
       /* We don't need thread-safety code for thread-local vars.  */
       bool thread_guard = (flag_threadsafe_statics
-			   && !DECL_THREAD_LOCAL_P (decl));
+			   && !CP_DECL_THREAD_LOCAL_P (decl));
 
       /* Emit code to perform this initialization but once.  This code
 	 looks like:
@@ -7323,7 +7327,7 @@ expand_static_init (tree decl, tree init)
       finish_then_clause (if_stmt);
       finish_if_stmt (if_stmt);
     }
-  else if (DECL_THREAD_LOCAL_P (decl))
+  else if (CP_DECL_THREAD_LOCAL_P (decl))
     tls_aggregates = tree_cons (init, decl, tls_aggregates);
   else
     static_aggregates = tree_cons (init, decl, static_aggregates);
@@ -8184,9 +8188,13 @@ grokvardecl (tree type,
   if (decl_spec_seq_has_spec_p (declspecs, ds_thread))
     {
       if (DECL_EXTERNAL (decl) || TREE_STATIC (decl))
-        set_decl_tls_model (decl, decl_default_tls_model (decl));
+	{
+	  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)
-	DECL_GNU_TLS_P (decl) = true;
+	SET_DECL_GNU_TLS_P (decl);
     }
 
   /* If the type of the decl has no linkage, make sure that we'll
@@ -10859,9 +10867,11 @@ grokdeclarator (const cp_declarator *declarator,
 
 		if (thread_p)
 		  {
-		    set_decl_tls_model (decl, decl_default_tls_model (decl));
+		    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)
-		      DECL_GNU_TLS_P (decl) = true;
+		      SET_DECL_GNU_TLS_P (decl);
 		  }
 
 		if (constexpr_p && !initialized)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a7a6efb..5032333 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3005,6 +3005,7 @@ get_guard (tree decl)
       TREE_STATIC (guard) = TREE_STATIC (decl);
       DECL_COMMON (guard) = DECL_COMMON (decl);
       DECL_COMDAT (guard) = DECL_COMDAT (decl);
+      CP_DECL_THREAD_LOCAL_P (guard) = CP_DECL_THREAD_LOCAL_P (decl);
       set_decl_tls_model (guard, DECL_TLS_MODEL (decl));
       if (DECL_ONE_ONLY (decl))
 	make_decl_one_only (guard, cxx_comdat_group (guard));
@@ -3143,7 +3144,7 @@ static bool
 var_needs_tls_wrapper (tree var)
 {
   return (!error_operand_p (var)
-	  && DECL_THREAD_LOCAL_P (var)
+	  && CP_DECL_THREAD_LOCAL_P (var)
 	  && !DECL_GNU_TLS_P (var)
 	  && !DECL_FUNCTION_SCOPE_P (var)
 	  && !var_defined_without_dynamic_init (var));
@@ -4278,6 +4279,7 @@ handle_tls_init (void)
   DECL_ARTIFICIAL (guard) = true;
   DECL_IGNORED_P (guard) = true;
   TREE_USED (guard) = true;
+  CP_DECL_THREAD_LOCAL_P (guard) = true;
   set_decl_tls_model (guard, decl_default_tls_model (guard));
   pushdecl_top_level_and_finish (guard, NULL_TREE);
 
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 9bbdba5..915fbdd 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -553,6 +553,9 @@ retrofit_lang_decl (tree t)
   size_t size;
   int sel;
 
+  if (DECL_LANG_SPECIFIC (t))
+    return;
+
   if (TREE_CODE (t) == FUNCTION_DECL)
     sel = 1, size = sizeof (struct lang_decl_fn);
   else if (TREE_CODE (t) == NAMESPACE_DECL)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 874f29f..6b73d49 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11467,8 +11467,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 		  }
 		SET_DECL_VALUE_EXPR (r, ve);
 	      }
-	    if (TREE_STATIC (r) || DECL_EXTERNAL (r))
-	      set_decl_tls_model (r, decl_tls_model (t));
+	    if (CP_DECL_THREAD_LOCAL_P (r)
+		&& !processing_template_decl)
+	      set_decl_tls_model (r, decl_default_tls_model (r));
 	  }
 	else if (DECL_SELF_REFERENCE_P (t))
 	  SET_DECL_SELF_REFERENCE_P (r);
@@ -15696,7 +15697,7 @@ tsubst_copy_and_build (tree t,
 	    && !processing_template_decl
 	    && !cp_unevaluated_operand
 	    && (TREE_STATIC (r) || DECL_EXTERNAL (r))
-	    && DECL_THREAD_LOCAL_P (r))
+	    && CP_DECL_THREAD_LOCAL_P (r))
 	  {
 	    if (tree wrap = get_tls_wrapper_fn (r))
 	      /* Replace an evaluated use of the thread_local variable with
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c23d9be..8de2522 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3553,7 +3553,7 @@ finish_id_expression (tree id_expression,
 	  && !cp_unevaluated_operand
 	  && !processing_template_decl
 	  && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
-	  && DECL_THREAD_LOCAL_P (decl)
+	  && CP_DECL_THREAD_LOCAL_P (decl)
 	  && (wrap = get_tls_wrapper_fn (decl)))
 	{
 	  /* Replace an evaluated use of the thread_local variable with
@@ -4291,7 +4291,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
 	  return error_mark_node;
 	}
       else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
-	       && VAR_P (t) && DECL_THREAD_LOCAL_P (t))
+	       && VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
 	{
 	  error_at (OMP_CLAUSE_LOCATION (c),
 		    "%qD is threadprivate variable in %qs clause", t,
@@ -5784,7 +5784,7 @@ finish_omp_clauses (tree clauses)
 		       omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
 	      remove = true;
 	    }
-	  else if (VAR_P (t) && DECL_THREAD_LOCAL_P (t))
+	  else if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
 	    {
 	      error ("%qD is threadprivate variable in %qs clause", t,
 		     omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
@@ -5954,7 +5954,7 @@ finish_omp_clauses (tree clauses)
 	  break;
 
 	case OMP_CLAUSE_COPYIN:
-	  if (!VAR_P (t) || !DECL_THREAD_LOCAL_P (t))
+	  if (!VAR_P (t) || !CP_DECL_THREAD_LOCAL_P (t))
 	    {
 	      error ("%qE must be %<threadprivate%> for %<copyin%>", t);
 	      remove = true;
@@ -5982,7 +5982,7 @@ finish_omp_clauses (tree clauses)
 	{
 	  const char *share_name = NULL;
 
-	  if (VAR_P (t) && DECL_THREAD_LOCAL_P (t))
+	  if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
 	    share_name = "threadprivate";
 	  else switch (cxx_omp_predetermined_sharing (t))
 	    {
@@ -6085,8 +6085,9 @@ finish_omp_threadprivate (tree vars)
 		DECL_LANG_SPECIFIC (v)->u.base.u2sel = 1;
 	    }
 
-	  if (! DECL_THREAD_LOCAL_P (v))
+	  if (! CP_DECL_THREAD_LOCAL_P (v))
 	    {
+	      CP_DECL_THREAD_LOCAL_P (v) = true;
 	      set_decl_tls_model (v, decl_default_tls_model (v));
 	      /* If rtl has been already set for this var, call
 		 make_decl_rtl once again, so that encode_section_info
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index f1f5e53..0d1112c 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -4036,7 +4036,7 @@ decl_storage_duration (tree decl)
   if (!TREE_STATIC (decl)
       && !DECL_EXTERNAL (decl))
     return dk_auto;
-  if (DECL_THREAD_LOCAL_P (decl))
+  if (CP_DECL_THREAD_LOCAL_P (decl))
     return dk_thread;
   return dk_static;
 }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/tls1.C b/gcc/testsuite/g++.dg/debug/dwarf2/tls1.C
new file mode 100644
index 0000000..6286d7b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/tls1.C
@@ -0,0 +1,7 @@
+// PR c++/66653
+// { dg-options "-gdwarf" }
+
+template <typename T> class A
+{
+  static __thread T a;
+};

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s
  2015-06-30 14:43           ` Jason Merrill
@ 2015-07-01  7:39             ` Richard Biener
  0 siblings, 0 replies; 13+ messages in thread
From: Richard Biener @ 2015-07-01  7:39 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Aldy Hernandez, gcc-patches, Jan Hubicka

On Tue, Jun 30, 2015 at 4:30 PM, Jason Merrill <jason@redhat.com> wrote:
> On 06/29/2015 06:32 PM, Jason Merrill wrote:
>>
>> On 06/29/2015 05:07 AM, Richard Biener wrote:
>>>
>>> On Fri, Jun 26, 2015 at 11:59 PM, Jason Merrill <jason@redhat.com> wrote:
>>>>
>>>> On 06/26/2015 05:37 AM, Richard Biener wrote:
>>>>>
>>>>>
>>>>> Can we defer TLS model setting to template instantiation?
>>>>
>>>>
>>>> We need to represent somehow that __thread (or thread_local) was used in
>>>> the
>>>> declaration, but DECL_THREAD_LOCAL_P was changed to refer to the TLS
>>>> model.
>>>
>>>
>>> Ok, so "easiest" would be to allocate a bit from decl_with_vis for
>>> this...
>>
>>
>> Or I can find a flag in the front end.  I guess I'll do that.
>
>
> Thus.

Looks good to me.

Richard.

> Jason
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-07-01  7:39 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-25  3:19 [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s Aldy Hernandez
2015-06-25  9:49 ` Richard Biener
2015-06-25 15:08   ` Aldy Hernandez
2015-06-25 13:56 ` Eric Botcazou
2015-06-25 14:57   ` Aldy Hernandez
2015-06-25 20:57     ` Eric Botcazou
2015-06-25 17:02 ` Jason Merrill
2015-06-26  9:40   ` Richard Biener
2015-06-26 22:04     ` Jason Merrill
2015-06-29  9:14       ` Richard Biener
2015-06-29 22:35         ` Jason Merrill
2015-06-30 14:43           ` Jason Merrill
2015-07-01  7:39             ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).