re PR c++/63485 (ICE: canonical types differ for identical types A<const wchar_t...
authorJason Merrill <jason@redhat.com>
Wed, 8 Oct 2014 20:27:11 +0000 (16:27 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 8 Oct 2014 20:27:11 +0000 (16:27 -0400)
PR c++/63485
* tree.c (build_cplus_array_type): Look for a type with no
typedef-name or attributes.

From-SVN: r216012

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

index c70de7e22ed1db0f27240c585c59ebfb393cd09e..975193d6a127a4fd215db44894117327f362a525 100644 (file)
@@ -1,5 +1,9 @@
 2014-10-08  Jason Merrill  <jason@redhat.com>
 
+       PR c++/63485
+       * tree.c (build_cplus_array_type): Look for a type with no
+       typedef-name or attributes.
+
        * call.c (call_copy_ctor): New.
        (build_over_call): Use it to avoid infinite recursion on invalid code.
 
index cfb0ed8c2998bf82a56bb34ead8ab06c90124f14..5b11d5cc8f003222c709db0a349b86411479d293 100644 (file)
@@ -853,7 +853,9 @@ build_cplus_array_type (tree elt_type, tree index_type)
     {
       tree m = t;
       for (t = m; t; t = TYPE_NEXT_VARIANT (t))
-       if (TREE_TYPE (t) == elt_type)
+       if (TREE_TYPE (t) == elt_type
+           && TYPE_NAME (t) == NULL_TREE
+           && TYPE_ATTRIBUTES (t) == NULL_TREE)
          break;
       if (!t)
        {
diff --git a/gcc/testsuite/g++.dg/template/array29.C b/gcc/testsuite/g++.dg/template/array29.C
new file mode 100644 (file)
index 0000000..e43cb9d
--- /dev/null
@@ -0,0 +1,56 @@
+// PR c++/63485
+
+template <typename C> struct A
+{
+  typedef C type;
+};
+template <class> class B
+{
+};
+template <class Range> void as_literal (Range &);
+template <typename> struct C
+{
+  typedef wchar_t char_type;
+  const char_type on_full_year_placeholder[3];
+  void
+  on_extended_iso_date ()
+  {
+    B<A<wchar_t const[3]>::type> a;
+    as_literal (on_full_year_placeholder);
+  }
+};
+template <typename> struct date_time_format_parser_callback : C<wchar_t>
+{
+};
+template <typename BaseT> struct D
+{
+  typedef typename BaseT::char_type char_type;
+  char_type
+  parse (const char_type *, const char_type *,
+         typename BaseT::callback_type p3)
+  {
+    p3.on_extended_iso_date ();
+  }
+};
+struct F
+{
+  typedef date_time_format_parser_callback<wchar_t> callback_type;
+  typedef wchar_t char_type;
+};
+template <typename CharT, typename ParserT, typename CallbackT>
+void
+parse_format (CharT *p1, ParserT p2, CallbackT p3)
+{
+  CharT p = p2.parse (&p, p1, p3);
+}
+template <typename CharT>
+void
+parse_date_time_format (const CharT *, const CharT *p2,
+                        date_time_format_parser_callback<CharT> &p3)
+{
+  D<F> b;
+  parse_format (p2, b, p3);
+}
+template void
+parse_date_time_format (const wchar_t *, const wchar_t *,
+                        date_time_format_parser_callback<wchar_t> &);