re PR debug/66653 (ice in gen_type_die_with_usage, at dwarf2out.c:20876)
[gcc.git] / gcc / cp / pt.c
index ec33d96fc6fb6f4fecc9c85785fc58432744dea2..6b73d49ce29c3d69db6485a6c6064ca9e6a1c9c5 100644 (file)
@@ -28,12 +28,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "hash-set.h"
-#include "vec.h"
-#include "input.h"
 #include "alias.h"
 #include "symtab.h"
-#include "inchash.h"
 #include "tree.h"
 #include "stringpool.h"
 #include "varasm.h"
@@ -93,7 +89,7 @@ struct GTY((for_user)) spec_entry
   tree spec;
 };
 
-struct spec_hasher : ggc_hasher<spec_entry *>
+struct spec_hasher : ggc_ptr_hash<spec_entry>
 {
   static hashval_t hash (spec_entry *);
   static bool equal (spec_entry *, spec_entry *);
@@ -214,6 +210,7 @@ static tree template_parm_to_arg (tree t);
 static tree current_template_args (void);
 static tree tsubst_template_parm (tree, tree, tsubst_flags_t);
 static tree instantiate_alias_template (tree, tree, tsubst_flags_t);
+static bool complex_alias_template_p (const_tree tmpl);
 
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -1022,6 +1019,35 @@ optimize_specialization_lookup_p (tree tmpl)
          && !DECL_FRIEND_P (DECL_TEMPLATE_RESULT (tmpl)));
 }
 
+/* Make sure ARGS doesn't use any inappropriate typedefs; we should have
+   gone through coerce_template_parms by now.  */
+
+static void
+check_unstripped_args (tree args ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_CHECKING
+  ++processing_template_decl;
+  if (!any_dependent_template_arguments_p (args))
+    {
+      tree inner = INNERMOST_TEMPLATE_ARGS (args);
+      for (int i = 0; i < TREE_VEC_LENGTH (inner); ++i)
+       {
+         tree arg = TREE_VEC_ELT (inner, i);
+         if (TREE_CODE (arg) == TEMPLATE_DECL)
+           /* OK */;
+         else if (TYPE_P (arg))
+           gcc_assert (strip_typedefs (arg, NULL) == arg);
+         else if (strip_typedefs (TREE_TYPE (arg), NULL) != TREE_TYPE (arg))
+           /* Allow typedefs on the type of a non-type argument, since a
+              parameter can have them.  */;
+         else
+           gcc_assert (strip_typedefs_expr (arg, NULL) == arg);
+       }
+    }
+  --processing_template_decl;
+#endif
+}
+
 /* Retrieve the specialization (in the sense of [temp.spec] - a
    specialization is either an instantiation or an explicit
    specialization) of TMPL for the given template ARGS.  If there is
@@ -1055,13 +1081,7 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
                  ? TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))
                  : template_class_depth (DECL_CONTEXT (tmpl))));
 
-#ifdef ENABLE_CHECKING
-  /* We should have gone through coerce_template_parms by now.  */
-  ++processing_template_decl;
-  if (!any_dependent_template_arguments_p (args))
-    gcc_assert (strip_typedefs_expr (args, NULL) == args);
-  --processing_template_decl;
-#endif
+  check_unstripped_args (args);
 
   if (optimize_specialization_lookup_p (tmpl))
     {
@@ -2435,7 +2455,7 @@ check_explicit_specialization (tree declarator,
   switch (tsk)
     {
     case tsk_none:
-      if (processing_specialization && TREE_CODE (decl) != VAR_DECL)
+      if (processing_specialization && !VAR_P (decl))
        {
          specialization = 1;
          SET_DECL_TEMPLATE_SPECIALIZATION (decl);
@@ -2868,7 +2888,7 @@ check_explicit_specialization (tree declarator,
            /* A specialization is not necessarily COMDAT.  */
            DECL_COMDAT (decl) = (TREE_PUBLIC (decl)
                                  && DECL_DECLARED_INLINE_P (decl));
-         else if (TREE_CODE (decl) == VAR_DECL)
+         else if (VAR_P (decl))
            DECL_COMDAT (decl) = false;
 
          /* Register this specialization so that we can find it
@@ -4423,6 +4443,7 @@ get_template_parm_index (tree parm)
           || TREE_CODE (parm) == TEMPLATE_DECL)
     parm = TREE_TYPE (parm);
   if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+      || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM
       || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
     parm = TEMPLATE_TYPE_PARM_INDEX (parm);
   gcc_assert (TREE_CODE (parm) == TEMPLATE_PARM_INDEX);
@@ -4750,7 +4771,7 @@ push_template_decl_real (tree decl, bool is_friend)
   is_partial = ((DECL_IMPLICIT_TYPEDEF_P (decl)
                 && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
                 && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
-               || (TREE_CODE (decl) == VAR_DECL
+               || (VAR_P (decl)
                    && DECL_LANG_SPECIFIC (decl)
                    && DECL_TEMPLATE_SPECIALIZATION (decl)
                    && TINFO_USED_TEMPLATE_ID (DECL_TEMPLATE_INFO (decl))));
@@ -4796,7 +4817,7 @@ push_template_decl_real (tree decl, bool is_friend)
       if (DECL_CLASS_SCOPE_P (decl))
        member_template_p = true;
       if (TREE_CODE (decl) == TYPE_DECL
-         && ANON_AGGRNAME_P (DECL_NAME (decl)))
+         && anon_aggrname_p (DECL_NAME (decl)))
        {
          error ("template class without a name");
          return error_mark_node;
@@ -5099,6 +5120,11 @@ template arguments to %qD do not match original template %qD",
          if (TREE_CODE (parm) == TEMPLATE_DECL)
            DECL_CONTEXT (parm) = tmpl;
        }
+
+      if (TREE_CODE (decl) == TYPE_DECL
+         && TYPE_DECL_ALIAS_P (decl)
+         && complex_alias_template_p (tmpl))
+       TEMPLATE_DECL_COMPLEX_ALIAS_P (tmpl) = true;
     }
 
   /* The DECL_TI_ARGS of DECL contains full set of arguments referring
@@ -5356,13 +5382,56 @@ alias_template_specialization_p (const_tree t)
   return false;
 }
 
-/* Return TRUE iff T is a specialization of an alias template with
+/* An alias template is complex from a SFINAE perspective if a template-id
+   using that alias can be ill-formed when the expansion is not, as with
+   the void_t template.  We determine this by checking whether the
+   expansion for the alias template uses all its template parameters.  */
+
+struct uses_all_template_parms_data
+{
+  int level;
+  bool *seen;
+};
+
+static int
+uses_all_template_parms_r (tree t, void *data_)
+{
+  struct uses_all_template_parms_data &data
+    = *(struct uses_all_template_parms_data*)data_;
+  tree idx = get_template_parm_index (t);
+
+  if (TEMPLATE_PARM_LEVEL (idx) == data.level)
+    data.seen[TEMPLATE_PARM_IDX (idx)] = true;
+  return 0;
+}
+
+static bool
+complex_alias_template_p (const_tree tmpl)
+{
+  struct uses_all_template_parms_data data;
+  tree pat = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
+  tree parms = DECL_TEMPLATE_PARMS (tmpl);
+  data.level = TMPL_PARMS_DEPTH (parms);
+  int len = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS (parms));
+  data.seen = XALLOCAVEC (bool, len);
+  for (int i = 0; i < len; ++i)
+    data.seen[i] = false;
+
+  for_each_template_parm (pat, uses_all_template_parms_r, &data, NULL, true);
+  for (int i = 0; i < len; ++i)
+    if (!data.seen[i])
+      return true;
+  return false;
+}
+
+/* Return TRUE iff T is a specialization of a complex alias template with
    dependent template-arguments.  */
 
 bool
 dependent_alias_template_spec_p (const_tree t)
 {
   return (alias_template_specialization_p (t)
+         && TEMPLATE_DECL_COMPLEX_ALIAS_P (DECL_TI_TEMPLATE (TYPE_NAME (t)))
          && (any_dependent_template_arguments_p
              (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t)))));
 }
@@ -9169,12 +9238,20 @@ instantiate_class_template_1 (tree type)
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
 
+  int saved_unevaluated_operand = cp_unevaluated_operand;
+  int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+
   fn_context = decl_function_context (TYPE_MAIN_DECL (type));
   /* Also avoid push_to_top_level for a lambda in an NSDMI.  */
   if (!fn_context && LAMBDA_TYPE_P (type) && TYPE_CLASS_SCOPE_P (type))
     fn_context = error_mark_node;
   if (!fn_context)
     push_to_top_level ();
+  else
+    {
+      cp_unevaluated_operand = 0;
+      c_inhibit_evaluation_warnings = 0;
+    }
   /* Use #pragma pack from the template context.  */
   saved_maximum_field_alignment = maximum_field_alignment;
   maximum_field_alignment = TYPE_PRECISION (pattern);
@@ -9590,6 +9667,14 @@ instantiate_class_template_1 (tree type)
        }
     }
 
+  if (fn_context)
+    {
+      /* Restore these before substituting into the lambda capture
+        initializers.  */
+      cp_unevaluated_operand = saved_unevaluated_operand;
+      c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
+    }
+
   if (tree expr = CLASSTYPE_LAMBDA_EXPR (type))
     {
       tree decl = lambda_function (type);
@@ -9740,16 +9825,22 @@ make_fnparm_pack (tree spec_parm)
   return extract_fnparm_pack (NULL_TREE, &spec_parm);
 }
 
-/* Return true iff the Ith element of the argument pack ARG_PACK is a
-   pack expansion.  */
+/* Return 1 if the Ith element of the argument pack ARG_PACK is a
+   pack expansion with no extra args, 2 if it has extra args, or 0
+   if it is not a pack expansion.  */
 
-static bool
+static int
 argument_pack_element_is_expansion_p (tree arg_pack, int i)
 {
   tree vec = ARGUMENT_PACK_ARGS (arg_pack);
   if (i >= TREE_VEC_LENGTH (vec))
-    return false;
-  return PACK_EXPANSION_P (TREE_VEC_ELT (vec, i));
+    return 0;
+  tree elt = TREE_VEC_ELT (vec, i);
+  if (!PACK_EXPANSION_P (elt))
+    return 0;
+  if (PACK_EXPANSION_EXTRA_ARGS (elt))
+    return 2;
+  return 1;
 }
 
 
@@ -9799,7 +9890,12 @@ use_pack_expansion_extra_args_p (tree parm_packs,
        {
          tree arg = TREE_VALUE (parm_pack);
 
-         if (argument_pack_element_is_expansion_p (arg, i))
+         int exp = argument_pack_element_is_expansion_p (arg, i);
+         if (exp == 2)
+           /* We can't substitute a pack expansion with extra args into
+              our pattern.  */
+           return true;
+         else if (exp)
            has_expansion_arg = true;
          else
            has_non_expansion_arg = true;
@@ -10696,7 +10792,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        if (PRIMARY_TEMPLATE_P (t))
          DECL_PRIMARY_TEMPLATE (r) = r;
 
-       if (TREE_CODE (decl) != TYPE_DECL && TREE_CODE (decl) != VAR_DECL)
+       if (TREE_CODE (decl) != TYPE_DECL && !VAR_P (decl))
          /* Record this non-type partial instantiation.  */
          register_specialization (r, t,
                                   DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)),
@@ -11248,8 +11344,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          {
            /* T is a static data member or namespace-scope entity.
               We have to substitute into namespace-scope variables
-              (even though such entities are never templates) because
-              of cases like:
+              (not just variable templates) because of cases like:
               
                 template <class T> void f() { extern T t; }
 
@@ -11372,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);
@@ -11410,6 +11506,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
               initializer is present.  We mimic the non-template
               processing here.  */
            DECL_EXTERNAL (r) = 1;
+           if (DECL_NAMESPACE_SCOPE_P (t))
+             DECL_NOT_REALLY_EXTERN (r) = 1;
 
            DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
@@ -13012,10 +13110,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                      if (TREE_STATIC (r))
                        rest_of_decl_compilation (r, toplevel_bindings_p (),
                                                  at_eof);
-                     else if (decl_constant_var_p (r))
-                       /* A use of a local constant decays to its value.
-                          FIXME update for core DR 696.  */
-                       r = scalar_constant_value (r);
+                     else
+                       r = process_outer_var_ref (r, complain);
                    }
                }
              /* Remember this for subsequent uses.  */
@@ -13433,6 +13529,32 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     }
 }
 
+/* Helper function for tsubst_omp_clauses, used for instantiation of
+   OMP_CLAUSE_DECL of clauses that handles also OpenMP array sections
+   represented with TREE_LIST.  */
+
+static tree
+tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
+                       tree in_decl)
+{
+  if (TREE_CODE (decl) == TREE_LIST)
+    {
+      tree low_bound
+       = tsubst_expr (TREE_PURPOSE (decl), args, complain, in_decl,
+                      /*integral_constant_expression_p=*/false);
+      tree length = tsubst_expr (TREE_VALUE (decl), args, complain, in_decl,
+                                /*integral_constant_expression_p=*/false);
+      tree chain = tsubst_omp_clause_decl (TREE_CHAIN (decl), args, complain,
+                                          in_decl);
+      if (TREE_PURPOSE (decl) == low_bound
+         && TREE_VALUE (decl) == length
+         && TREE_CHAIN (decl) == chain)
+       return decl;
+      return tree_cons (low_bound, length, chain);
+    }
+  return tsubst_copy (decl, args, complain, in_decl);
+}
+
 /* Like tsubst_copy, but specifically for OpenMP clauses.  */
 
 static tree
@@ -13464,16 +13586,23 @@ tsubst_omp_clauses (tree clauses, bool declare_simd,
        case OMP_CLAUSE_FIRSTPRIVATE:
        case OMP_CLAUSE_COPYIN:
        case OMP_CLAUSE_COPYPRIVATE:
+       case OMP_CLAUSE_UNIFORM:
+         OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args,
+                                             complain, in_decl);
+         break;
+       case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE_FROM:
+       case OMP_CLAUSE_TO:
+       case OMP_CLAUSE_MAP:
+         OMP_CLAUSE_DECL (nc)
+           = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
+                                     in_decl);
+         break;
        case OMP_CLAUSE_IF:
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_SCHEDULE:
        case OMP_CLAUSE_COLLAPSE:
        case OMP_CLAUSE_FINAL:
-       case OMP_CLAUSE_DEPEND:
-       case OMP_CLAUSE_FROM:
-       case OMP_CLAUSE_TO:
-       case OMP_CLAUSE_UNIFORM:
-       case OMP_CLAUSE_MAP:
        case OMP_CLAUSE_DEVICE:
        case OMP_CLAUSE_DIST_SCHEDULE:
        case OMP_CLAUSE_NUM_TEAMS:
@@ -13500,20 +13629,17 @@ tsubst_omp_clauses (tree clauses, bool declare_simd,
              else
                gcc_assert (identifier_p (placeholder));
            }
-         OMP_CLAUSE_OPERAND (nc, 0)
-           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
-                          in_decl, /*integral_constant_expression_p=*/false);
+         OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args,
+                                             complain, in_decl);
          break;
        case OMP_CLAUSE_LINEAR:
        case OMP_CLAUSE_ALIGNED:
-         OMP_CLAUSE_OPERAND (nc, 0)
-           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
-                          in_decl, /*integral_constant_expression_p=*/false);
+         OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args,
+                                             complain, in_decl);
          OMP_CLAUSE_OPERAND (nc, 1)
            = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain,
                           in_decl, /*integral_constant_expression_p=*/false);
          break;
-
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_DEFAULT:
@@ -15571,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
@@ -15579,7 +15705,11 @@ tsubst_copy_and_build (tree t,
              r = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
          }
        else if (outer_automatic_var_p (r))
-         r = process_outer_var_ref (r, complain);
+         {
+           r = process_outer_var_ref (r, complain);
+           if (is_capture_proxy (r))
+             register_local_specialization (r, t);
+         }
 
        if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
          /* If the original type was a reference, we'll be wrapped in
@@ -16439,15 +16569,11 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
       break;
 
     case DEDUCE_CONV:
-      {
-       /* Swap PARM and ARG throughout the remainder of this
-          function; the handling is precisely symmetric since PARM
-          will initialize ARG rather than vice versa.  */
-       tree* temp = parm;
-       parm = arg;
-       arg = temp;
-       break;
-      }
+      /* Swap PARM and ARG throughout the remainder of this
+        function; the handling is precisely symmetric since PARM
+        will initialize ARG rather than vice versa.  */
+      std::swap (parm, arg);
+      break;
 
     case DEDUCE_EXACT:
       /* Core issue #873: Do the DR606 thing (see below) for these cases,
@@ -20890,6 +21016,12 @@ dependent_type_p_r (tree type)
        names a dependent type.  */
   if (TREE_CODE (type) == TYPENAME_TYPE)
     return true;
+
+  /* An alias template specialization can be dependent even if the
+     resulting type is not.  */
+  if (dependent_alias_template_spec_p (type))
+    return true;
+
   /* -- a cv-qualified type where the cv-unqualified type is
        dependent.
      No code is necessary for this bullet; the code below handles
@@ -20941,12 +21073,6 @@ dependent_type_p_r (tree type)
           && (any_dependent_template_arguments_p
               (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)))))
     return true;
-  /* For an alias template specialization, check the arguments both to the
-     class template and the alias template.  */
-  else if (alias_template_specialization_p (type)
-          && (any_dependent_template_arguments_p
-              (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (type)))))
-    return true;
 
   /* All TYPEOF_TYPEs, DECLTYPE_TYPEs, and UNDERLYING_TYPEs are
      dependent; if the argument of the `typeof' expression is not
@@ -21442,6 +21568,10 @@ type_dependent_expression_p (tree expression)
       && variable_template_p (DECL_TI_TEMPLATE (expression)))
     return any_dependent_template_arguments_p (DECL_TI_ARGS (expression));
 
+  /* Always dependent, on the number of arguments if nothing else.  */
+  if (TREE_CODE (expression) == EXPR_PACK_EXPANSION)
+    return true;
+
   if (TREE_TYPE (expression) == unknown_type_node)
     {
       if (TREE_CODE (expression) == ADDR_EXPR)
@@ -21459,10 +21589,6 @@ type_dependent_expression_p (tree expression)
       if (TREE_CODE (expression) == SCOPE_REF)
        return false;
 
-      /* Always dependent, on the number of arguments if nothing else.  */
-      if (TREE_CODE (expression) == EXPR_PACK_EXPANSION)
-       return true;
-
       if (BASELINK_P (expression))
        {
          if (BASELINK_OPTYPE (expression)