]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/59044 (Internal compiler error triggers when accessing a typedef in a speci...
authorJason Merrill <jason@redhat.com>
Thu, 5 Dec 2013 22:46:36 +0000 (17:46 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 5 Dec 2013 22:46:36 +0000 (17:46 -0500)
PR c++/59044
PR c++/59052
* pt.c (most_specialized_class): Use the partially instantiated
template for deduction.  Drop the TMPL parameter.

From-SVN: r205720

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/template/partial14.C [new file with mode: 0644]

index 2d5617a35cc30887c30e07df0c4a4c162e9b088e..16b6aa0024099f99afe770a95ff8cd1f149c629a 100644 (file)
@@ -1,3 +1,10 @@
+2013-12-05  Jason Merrill  <jason@redhat.com>
+
+       PR c++/59044
+       PR c++/59052
+       * pt.c (most_specialized_class): Use the partially instantiated
+       template for deduction.  Drop the TMPL parameter.
+
 2013-12-05  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * decl.c (duplicate_decls): Replace pairs of errors and permerrors
index 25d940c695a1c2e2752260751b7011b0821e47cc..01b2d44ee8e9587890e2a68923b695d3cd45c3d6 100644 (file)
@@ -176,7 +176,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
 static void regenerate_decl_from_template (tree, tree);
-static tree most_specialized_class (tree, tree, tsubst_flags_t);
+static tree most_specialized_class (tree, tsubst_flags_t);
 static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
 static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
 static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
@@ -4305,7 +4305,7 @@ process_partial_specialization (tree decl)
       if (COMPLETE_TYPE_P (inst_type)
          && CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type))
        {
-         tree spec = most_specialized_class (inst_type, maintmpl, tf_none);
+         tree spec = most_specialized_class (inst_type, tf_none);
          if (spec && TREE_TYPE (spec) == type)
            permerror (input_location,
                       "partial specialization of %qT after instantiation "
@@ -8716,7 +8716,7 @@ instantiate_class_template_1 (tree type)
 
   /* Determine what specialization of the original template to
      instantiate.  */
-  t = most_specialized_class (type, templ, tf_warning_or_error);
+  t = most_specialized_class (type, tf_warning_or_error);
   if (t == error_mark_node)
     {
       TYPE_BEING_DEFINED (type) = 1;
@@ -18242,7 +18242,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
     return -1;
 }
 
-/* Determine which of two partial specializations of MAIN_TMPL is more
+/* Determine which of two partial specializations of TMPL is more
    specialized.
 
    PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding
@@ -18258,7 +18258,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
    two templates is more specialized.  */
 
 static int
-more_specialized_class (tree main_tmpl, tree pat1, tree pat2)
+more_specialized_class (tree tmpl, tree pat1, tree pat2)
 {
   tree targs;
   tree tmpl1, tmpl2;
@@ -18273,7 +18273,7 @@ more_specialized_class (tree main_tmpl, tree pat1, tree pat2)
      types in the arguments, and we need our dependency check functions
      to behave correctly.  */
   ++processing_template_decl;
-  targs = get_class_bindings (main_tmpl, TREE_VALUE (pat1),
+  targs = get_class_bindings (tmpl, TREE_VALUE (pat1),
                              CLASSTYPE_TI_ARGS (tmpl1),
                              CLASSTYPE_TI_ARGS (tmpl2));
   if (targs)
@@ -18282,7 +18282,7 @@ more_specialized_class (tree main_tmpl, tree pat1, tree pat2)
       any_deductions = true;
     }
 
-  targs = get_class_bindings (main_tmpl, TREE_VALUE (pat2),
+  targs = get_class_bindings (tmpl, TREE_VALUE (pat2),
                              CLASSTYPE_TI_ARGS (tmpl2),
                              CLASSTYPE_TI_ARGS (tmpl1));
   if (targs)
@@ -18363,7 +18363,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
 }
 
 /* Return the innermost template arguments that, when applied to a partial
-   specialization of MAIN_TMPL whose innermost template parameters are
+   specialization of TMPL whose innermost template parameters are
    TPARMS, and whose specialization arguments are SPEC_ARGS, yield the
    ARGS.
 
@@ -18378,7 +18378,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
    is bound to `double'.  */
 
 static tree
-get_class_bindings (tree main_tmpl, tree tparms, tree spec_args, tree args)
+get_class_bindings (tree tmpl, tree tparms, tree spec_args, tree args)
 {
   int i, ntparms = TREE_VEC_LENGTH (tparms);
   tree deduced_args;
@@ -18418,8 +18418,8 @@ get_class_bindings (tree main_tmpl, tree tparms, tree spec_args, tree args)
      `T' is `A' but unify () does not check whether `typename T::X'
      is `int'.  */
   spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE);
-  spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (main_tmpl),
-                                    spec_args, main_tmpl,
+  spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+                                    spec_args, tmpl,
                                     tf_none, false, false);
   if (spec_args == error_mark_node
       /* We only need to check the innermost arguments; the other
@@ -18567,30 +18567,30 @@ most_general_template (tree decl)
 }
 
 /* Return the most specialized of the class template partial
-   specializations of TMPL which can produce TYPE, a specialization of
-   TMPL.  The value returned is actually a TREE_LIST; the TREE_TYPE is
+   specializations which can produce TYPE, a specialization of some class
+   template.  The value returned is actually a TREE_LIST; the TREE_TYPE is
    a _TYPE node corresponding to the partial specialization, while the
    TREE_PURPOSE is the set of template arguments that must be
    substituted into the TREE_TYPE in order to generate TYPE.
 
    If the choice of partial specialization is ambiguous, a diagnostic
    is issued, and the error_mark_node is returned.  If there are no
-   partial specializations of TMPL matching TYPE, then NULL_TREE is
-   returned.  */
+   partial specializations matching TYPE, then NULL_TREE is
+   returned, indicating that the primary template should be used.  */
 
 static tree
-most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
+most_specialized_class (tree type, tsubst_flags_t complain)
 {
   tree list = NULL_TREE;
   tree t;
   tree champ;
   int fate;
   bool ambiguous_p;
-  tree args;
   tree outer_args = NULL_TREE;
 
-  tmpl = most_general_template (tmpl);
-  args = CLASSTYPE_TI_ARGS (type);
+  tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
+  tree main_tmpl = most_general_template (tmpl);
+  tree args = CLASSTYPE_TI_ARGS (type);
 
   /* For determining which partial specialization to use, only the
      innermost args are interesting.  */
@@ -18600,7 +18600,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
       args = INNERMOST_TEMPLATE_ARGS (args);
     }
 
-  for (t = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); t; t = TREE_CHAIN (t))
+  for (t = DECL_TEMPLATE_SPECIALIZATIONS (main_tmpl); t; t = TREE_CHAIN (t))
     {
       tree partial_spec_args;
       tree spec_args;
@@ -18625,8 +18625,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
 
       partial_spec_args =
          coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
-                                add_to_template_args (outer_args,
-                                                      partial_spec_args),
+                                partial_spec_args,
                                 tmpl, tf_none,
                                 /*require_all_args=*/true,
                                 /*use_default_args=*/true);
diff --git a/gcc/testsuite/g++.dg/template/partial14.C b/gcc/testsuite/g++.dg/template/partial14.C
new file mode 100644 (file)
index 0000000..3870164
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/59044
+
+template <class T>
+class C {
+private:
+  template <T a, T b>
+  struct Implementation {};
+public:
+  typedef typename Implementation<0, 0>::Typedef Type;
+};
+
+template <class T>
+template <T b>
+struct C<T>::Implementation<0, b> { typedef void Typedef; };
+
+template class C<unsigned>;