]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/pt.c
Make __PRETTY_FUNCTION__-like functions mergeable string csts (PR c++/64266).
[thirdparty/gcc.git] / gcc / cp / pt.c
index b49dce08206859dd8294b158a7cb62e08c0a867d..2dc0cb1629cdc183273fd27b1677b5beb1b4a3eb 100644 (file)
@@ -800,6 +800,7 @@ check_specialization_namespace (tree tmpl)
     return true;
   else
     {
+      auto_diagnostic_group d;
       if (permerror (input_location,
                     "specialization of %qD in different namespace", tmpl))
        inform (DECL_SOURCE_LOCATION (tmpl),
@@ -2592,6 +2593,7 @@ check_template_variable (tree decl)
     }
   if (template_header_count > wanted)
     {
+      auto_diagnostic_group d;
       bool warned = pedwarn (DECL_SOURCE_LOCATION (decl), 0,
                             "too many template headers for %qD "
                             "(should be %d)",
@@ -2724,6 +2726,7 @@ warn_spec_missing_attributes (tree tmpl, tree spec, tree attrlist)
   if (!nattrs)
     return;
 
+  auto_diagnostic_group d;
   if (warning_at (DECL_SOURCE_LOCATION (spec), OPT_Wmissing_attributes,
                  "explicit specialization %q#D may be missing attributes",
                  spec))
@@ -3070,6 +3073,7 @@ check_explicit_specialization (tree declarator,
          if (TREE_CODE (decl) == FUNCTION_DECL
              && DECL_HIDDEN_FRIEND_P (tmpl))
            {
+             auto_diagnostic_group d;
              if (pedwarn (DECL_SOURCE_LOCATION (decl), 0,
                           "friend declaration %qD is not visible to "
                           "explicit specialization", tmpl))
@@ -3865,6 +3869,17 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
        return NULL_TREE;
       }
 
+    case IF_STMT:
+      cp_walk_tree (&IF_COND (t), &find_parameter_packs_r,
+                   ppd, ppd->visited);
+      cp_walk_tree (&THEN_CLAUSE (t), &find_parameter_packs_r,
+                   ppd, ppd->visited);
+      cp_walk_tree (&ELSE_CLAUSE (t), &find_parameter_packs_r,
+                   ppd, ppd->visited);
+      /* Don't walk into IF_STMT_EXTRA_ARGS.  */
+      *walk_subtrees = 0;
+      return NULL_TREE;
+
     default:
       return NULL_TREE;
     }
@@ -4880,6 +4895,7 @@ process_partial_specialization (tree decl)
           && TMPL_ARGS_DEPTH (specargs) == 1
           && !get_partial_spec_bindings (maintmpl, maintmpl, specargs))
     {
+      auto_diagnostic_group d;
       if (permerror (input_location, "partial specialization %qD is not "
                     "more specialized than", decl))
        inform (DECL_SOURCE_LOCATION (maintmpl), "primary template %qD",
@@ -6671,7 +6687,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
             template-parameter.  */
          expr = build_converted_constant_expr (type, expr, complain);
          if (expr == error_mark_node)
-           return error_mark_node;
+           /* Make sure we return NULL_TREE only if we have really issued
+              an error, as described above.  */
+           return (complain & tf_error) ? NULL_TREE : error_mark_node;
          expr = maybe_constant_value (expr);
          expr = convert_from_reference (expr);
        }
@@ -7758,7 +7776,7 @@ convert_template_argument (tree parm,
   tree val;
   int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
 
-  if (parm == error_mark_node)
+  if (parm == error_mark_node || error_operand_p (arg))
     return error_mark_node;
 
   /* Trivially convert placeholders. */
@@ -9341,6 +9359,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
         {
           if (complain & tf_error)
             {
+             auto_diagnostic_group d;
               error ("template constraint failure");
               diagnose_constraints (input_location, gen_tmpl, arglist);
             }
@@ -9699,6 +9718,7 @@ finish_template_variable (tree var, tsubst_flags_t complain)
     {
       if (complain & tf_error)
        {
+         auto_diagnostic_group d;
          error ("use of invalid variable template %qE", var);
          diagnose_constraints (location_of (var), templ, arglist);
        }
@@ -12783,6 +12803,28 @@ tsubst_default_arguments (tree fn, tsubst_flags_t complain)
                                                    complain);
 }
 
+/* Hash table mapping a FUNCTION_DECL to its dependent explicit-specifier.  */
+static GTY((cache)) tree_cache_map *explicit_specifier_map;
+
+/* Store a pair to EXPLICIT_SPECIFIER_MAP.  */
+
+void
+store_explicit_specifier (tree v, tree t)
+{
+  if (!explicit_specifier_map)
+    explicit_specifier_map = tree_cache_map::create_ggc (37);
+  DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (v) = true;
+  explicit_specifier_map->put (v, t);
+}
+
+/* Lookup an element in EXPLICIT_SPECIFIER_MAP.  */
+
+static tree
+lookup_explicit_specifier (tree v)
+{
+  return *explicit_specifier_map->get (v);
+}
+
 /* Subroutine of tsubst_decl for the case when T is a FUNCTION_DECL.  */
 
 static tree
@@ -12923,6 +12965,17 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
     DECL_INITIAL (r) = NULL_TREE;
   DECL_CONTEXT (r) = ctx;
 
+  /* Handle explicit(dependent-expr).  */
+  if (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (t))
+    {
+      tree spec = lookup_explicit_specifier (t);
+      spec = tsubst_copy_and_build (spec, args, complain, in_decl,
+                                   /*function_p=*/false,
+                                   /*i_c_e_p=*/true);
+      spec = build_explicit_specifier (spec, complain);
+      DECL_NONCONVERTING_P (r) = (spec == boolean_true_node);
+    }
+
   /* OpenMP UDRs have the only argument a reference to the declared
      type.  We want to diagnose if the declared type is a reference,
      which is invalid, but as references to references are usually
@@ -16682,6 +16735,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
            register_local_specialization (inst, decl);
            break;
          }
+       else if (DECL_PRETTY_FUNCTION_P (decl))
+         decl = make_fname_decl (DECL_SOURCE_LOCATION (decl),
+                                 DECL_NAME (decl),
+                                 true/*DECL_PRETTY_FUNCTION_P (decl)*/);
        else if (DECL_IMPLICIT_TYPEDEF_P (decl)
                 && LAMBDA_TYPE_P (TREE_TYPE (decl)))
          /* Don't copy the old closure; we'll create a new one in
@@ -16729,39 +16786,30 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                else
                  {
                    int const_init = false;
+                   unsigned int cnt = 0;
+                   tree first = NULL_TREE, ndecl = error_mark_node;
                    maybe_push_decl (decl);
+
                    if (VAR_P (decl)
-                       && DECL_PRETTY_FUNCTION_P (decl))
-                     {
-                       /* For __PRETTY_FUNCTION__ we have to adjust the
-                          initializer.  */
-                       const char *const name
-                         = cxx_printable_name (current_function_decl, 2);
-                       init = cp_fname_init (name, &TREE_TYPE (decl));
-                     }
-                   else
-                     init = tsubst_init (init, decl, args, complain, in_decl);
+                       && DECL_DECOMPOSITION_P (decl)
+                       && TREE_TYPE (pattern_decl) != error_mark_node)
+                     ndecl = tsubst_decomp_names (decl, pattern_decl, args,
+                                                  complain, in_decl, &first,
+                                                  &cnt);
+
+                   init = tsubst_init (init, decl, args, complain, in_decl);
 
                    if (VAR_P (decl))
                      const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
                                    (pattern_decl));
-                   if (VAR_P (decl)
-                       && DECL_DECOMPOSITION_P (decl)
-                       && TREE_TYPE (pattern_decl) != error_mark_node)
-                     {
-                       unsigned int cnt;
-                       tree first;
-                       tree ndecl
-                         = tsubst_decomp_names (decl, pattern_decl, args,
-                                                complain, in_decl, &first, &cnt);
-                       if (ndecl != error_mark_node)
-                         cp_maybe_mangle_decomp (ndecl, first, cnt);
-                       cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
-                       if (ndecl != error_mark_node)
-                         cp_finish_decomp (ndecl, first, cnt);
-                     }
-                   else
-                     cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
+
+                   if (ndecl != error_mark_node)
+                     cp_maybe_mangle_decomp (ndecl, first, cnt);
+
+                   cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
+
+                   if (ndecl != error_mark_node)
+                     cp_finish_decomp (ndecl, first, cnt);
                  }
              }
          }
@@ -16794,6 +16842,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
         stmt = (processing_template_decl
                ? begin_range_for_stmt (NULL_TREE, NULL_TREE)
                : begin_for_stmt (NULL_TREE, NULL_TREE));
+       RECUR (RANGE_FOR_INIT_STMT (t));
         decl = RANGE_FOR_DECL (t);
         decl = tsubst (decl, args, complain, in_decl);
         maybe_push_decl (decl);
@@ -16811,6 +16860,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
            RANGE_FOR_IVDEP (stmt) = RANGE_FOR_IVDEP (t);
            RANGE_FOR_UNROLL (stmt) = RANGE_FOR_UNROLL (t);
            finish_range_for_decl (stmt, decl, expr);
+           if (decomp_first && decl != error_mark_node)
+             cp_finish_decomp (decl, decomp_first, decomp_cnt);
          }
        else
          {
@@ -23103,6 +23154,14 @@ do_decl_instantiation (tree decl, tree storage)
       error ("explicit instantiation of non-template %q#D", decl);
       return;
     }
+  else if (DECL_DECLARED_CONCEPT_P (decl))
+    {
+      if (VAR_P (decl))
+       error ("explicit instantiation of variable concept %q#D", decl);
+      else
+       error ("explicit instantiation of function concept %q#D", decl);
+      return;
+    }
 
   bool var_templ = (DECL_TEMPLATE_INFO (decl)
                     && variable_template_p (DECL_TI_TEMPLATE (decl)));
@@ -26056,7 +26115,7 @@ listify (tree arg)
   if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
     {    
       gcc_rich_location richloc (input_location);
-      maybe_add_include_fixit (&richloc, "<initializer_list>");
+      maybe_add_include_fixit (&richloc, "<initializer_list>", false);
       error_at (&richloc,
                "deducing from brace-enclosed initializer list"
                " requires %<#include <initializer_list>%>");
@@ -26097,7 +26156,7 @@ struct auto_hash : default_hash_traits<tree>
 inline hashval_t
 auto_hash::hash (tree t)
 {
-  if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
+  if (tree c = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
     /* Matching constrained-type-specifiers denote the same template
        parameter, so hash the constraint.  */
     return hash_placeholder_constraint (c);
@@ -26856,7 +26915,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
 
   /* Check any placeholder constraints against the deduced type. */
   if (flag_concepts && !processing_template_decl)
-    if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node))
+    if (tree constr = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (auto_node)))
       {
         /* Use the deduced type to check the associated constraints. If we
            have a partial-concept-id, rebuild the argument list so that
@@ -26874,6 +26933,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
           {
             if (complain & tf_warning_or_error)
               {
+               auto_diagnostic_group d;
                 switch (context)
                   {
                   case adc_unspecified:
@@ -27526,6 +27586,8 @@ declare_integer_pack (void)
                               NULL_TREE, ECF_CONST);
   DECL_DECLARED_CONSTEXPR_P (ipfn) = true;
   DECL_BUILT_IN_CLASS (ipfn) = BUILT_IN_FRONTEND;
+  DECL_FUNCTION_CODE (ipfn)
+    = (enum built_in_function) (int) CP_BUILT_IN_INTEGER_PACK;
 }
 
 /* Set up the hash tables for template instantiations.  */