aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-10-08 16:27:11 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-10-08 16:27:11 -0400
commit024da3094e3bac0ed63bf0955e70557e61fc17f9 (patch)
treefdd80a0b18875b8093c9d38891fa6b1311ac41d3
parentf193c7230cb09fac61b03a1a5f090bc978ccff73 (diff)
downloadgcc-024da3094e3bac0ed63bf0955e70557e61fc17f9.zip
gcc-024da3094e3bac0ed63bf0955e70557e61fc17f9.tar.gz
gcc-024da3094e3bac0ed63bf0955e70557e61fc17f9.tar.bz2
re PR c++/63485 (ICE: canonical types differ for identical types A<const wchar_t [3]>::type and const char_type [3])
PR c++/63485 * tree.c (build_cplus_array_type): Look for a type with no typedef-name or attributes. From-SVN: r216012
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/tree.c4
-rw-r--r--gcc/testsuite/g++.dg/template/array29.C56
3 files changed, 63 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c70de7e..975193d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index cfb0ed8..5b11d5c 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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
index 0000000..e43cb9d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/array29.C
@@ -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> &);