re PR debug/66653 (ice in gen_type_die_with_usage, at dwarf2out.c:20876)
authorJason Merrill <jason@redhat.com>
Tue, 30 Jun 2015 14:31:36 +0000 (10:31 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 30 Jun 2015 14:31:36 +0000 (10:31 -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.

From-SVN: r225192

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-gimplify.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/lex.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/debug/dwarf2/tls1.C [new file with mode: 0644]

index 04fb007f8e705aaf50e12e5f9308939a7497e6cd..cdb37c41fb75cc22c452faceb0792cd3943d228d 100644 (file)
@@ -1,3 +1,27 @@
+2015-06-30  Jason Merrill  <jason@redhat.com>
+
+       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.
+
 2015-06-30  Edward Smith-Rowland  <3dw4rd@verizon.net>
 
        Implement N4197 - Adding u8 character literals
index b8469194f7013b6ab62ddbc3677044e4c87dc68d..44346bf8f92aaf2db4b989f138e673289edf26c0 100644 (file)
@@ -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
index 1a627db1db21a4262a30829afc24d7b6e5b27504..b95489e78162e4238c585c4ce06cce3559968b93 100644 (file)
@@ -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;
index e8cc38f97e6bf07e8359de26f79c7f8b337c1f72..18cf87e893ac41ca7b144681c89276eb244b6de1 100644 (file)
@@ -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
index 5a644d7e2f4d3561caa45ffbabcc3370fb55cd01..9fabde7881ba15dfc2bec1cd331c7ac67023d6a6 100644 (file)
@@ -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
@@ -4859,7 +4863,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))
@@ -7056,7 +7060,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)
     {
@@ -7099,7 +7103,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 ();
@@ -7139,7 +7143,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;
@@ -7179,7 +7183,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)
@@ -7208,7 +7212,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:
@@ -7321,7 +7325,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);
@@ -8182,9 +8186,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
@@ -10857,9 +10865,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)
index a7a6efb25f2dc0741e3ece1cf536fc3441b7686f..5032333c314d418aab23e1e3c40dc226cda93400 100644 (file)
@@ -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);
 
index 9bbdba5a7ec187f3e3d1c16f8347252816bf301f..915fbddff022640ea031851427a0c23af2ef0a65 100644 (file)
@@ -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)
index 874f29f02c66fa721b543159c6dc8df3090ca1a9..6b73d49ce29c3d69db6485a6c6064ca9e6a1c9c5 100644 (file)
@@ -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
index c23d9bef0c27f17c7a277d5013ae82dfca2ec4c4..8de2522a6d4bd5ab56c67ee820452e84f5077f45 100644 (file)
@@ -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
index f1f5e533c7afb2ecf40a442f80cce748ceeee1b6..0d1112c33d0ff31c3d42efb3e0d788e8eca9e0aa 100644 (file)
@@ -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 (file)
index 0000000..6286d7b
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/66653
+// { dg-options "-gdwarf" }
+
+template <typename T> class A
+{
+  static __thread T a;
+};