re PR c++/66255 (ice in retrieve_specialization)
authorJason Merrill <jason@redhat.com>
Fri, 26 Jun 2015 20:33:46 +0000 (16:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 26 Jun 2015 20:33:46 +0000 (16:33 -0400)
PR c++/66255
* pt.c (check_unstripped_args): Split out from...
(retrieve_specialization): ...here.  Allow typedefs in the type of
a non-type argument.

From-SVN: r225084

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

index 452a6d9055adc28673f9fecc045e750d8bff825e..e9030a7de22d6c8c7b44db9c755f22d0903c773d 100644 (file)
@@ -1,5 +1,10 @@
 2015-06-26  Jason Merrill  <jason@redhat.com>
 
+       PR c++/66255
+       * pt.c (check_unstripped_args): Split out from...
+       (retrieve_specialization): ...here.  Allow typedefs in the type of
+       a non-type argument.
+
        PR c++/66067
        * mangle.c (write_nested_name): Limit TYPENAME_TYPE handling to
        TYPE_DECLs.
index fe5fc1447426e8698431f7b385ddf2a9747da2f2..082e04c4a80f094d9390b3be8d503f1bf6ed959b 100644 (file)
@@ -1019,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)
+{
+#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
@@ -1052,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))
     {
diff --git a/gcc/testsuite/g++.dg/template/nontype27.C b/gcc/testsuite/g++.dg/template/nontype27.C
new file mode 100644 (file)
index 0000000..956e5e4
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/66255
+
+typedef int int_t;
+
+template <int_t &>
+struct S { };
+
+int_t a;
+S <a> b;