From patchwork Tue Jun 30 14:30:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 489741 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 494871402CC for ; Wed, 1 Jul 2015 00:31:05 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=GoawL5gT; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=gFKg8hqTHFKDk8m/k dJXTVqbSkdnuFvBUGCLTG7ODKCYJJBWj5pvgfshc9JsTPCEh71btecJ1kCE28pe9 kQ52lk8adOcqbFNh4mtKB31gnR4Mwn6znKCh/MeAm32XnJ8x61mwBnyq38raJZ9U FtsjgeJiqWYlD0iUkjm9qEB5Lk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=Sph9hgGh1TV6914xtE0DZ/p Yc5A=; b=GoawL5gT6kTm3QuRNrear62vmNyfGRHojgNVei6uBqpr+JT96CG/c5/ +w3o/05c66MDb8dX6F98ZxrAqGwDPGaEMx+juXqJPiS8hgRhwAk96R+SdEiQBAIc 0HeM5G6RBQalMcaiecyIc4cc2hE3o9ooG4ppOGCwtJUt6E60M/Zc= Received: (qmail 120679 invoked by alias); 30 Jun 2015 14:30:58 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 120622 invoked by uid 89); 30 Jun 2015 14:30:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.8 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 30 Jun 2015 14:30:55 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 365418F291; Tue, 30 Jun 2015 14:30:54 +0000 (UTC) Received: from [10.10.116.35] ([10.10.116.35]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t5UEUq3c008640; Tue, 30 Jun 2015 10:30:53 -0400 Message-ID: <5592A818.7070607@redhat.com> Date: Tue, 30 Jun 2015 10:30:48 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: Richard Biener CC: Aldy Hernandez , gcc-patches , Jan Hubicka Subject: Re: [patch] PR debug/66653: avoid late_global_decl on decl_type_context()s References: <558B71A3.3080004@redhat.com> <558C32D7.1090902@redhat.com> <558DCB24.6060904@redhat.com> <5591C776.5050405@redhat.com> In-Reply-To: <5591C776.5050405@redhat.com> 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 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 commit fcc92fd874243b1366dcbd75ff32cc8862d8ec52 Author: Jason Merrill 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 **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 % in % 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 &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 % for %", 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 class A +{ + static __thread T a; +};