Hi again,
On 14/01/2017 15:43, Jason Merrill wrote:
OK.
As you may or may not have noticed, I had to revert the patch because it
caused the regression of
tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc during error
recovery: an ICE happens in remap_decl when build_variant_type_copy is
called on a TREE_TYPE (== DECL_ORIGINAL_TYPE) which is error_mark_node.
A possible straightforward and safe fix for the new issue would be
simply checking for the special condition, as I did in patch_71737_3
below, which passes testing. Alternately, I have been fiddling also with
older approaches, and patch_71737_4 below also passes testing: it simply
renounces to preserve a typedef which names an error_mark_node type.
Thanks again!
Paolo.
//////////////////////////
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c (revision 245274)
+++ c-family/c-common.c (working copy)
@@ -7420,16 +7420,18 @@ set_underlying_type (tree x)
if (TYPE_NAME (TREE_TYPE (x)) == 0)
TYPE_NAME (TREE_TYPE (x)) = x;
}
- else if (TREE_TYPE (x) != error_mark_node
- && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
+ else if (DECL_ORIGINAL_TYPE (x) == NULL_TREE)
{
tree tt = TREE_TYPE (x);
DECL_ORIGINAL_TYPE (x) = tt;
- tt = build_variant_type_copy (tt);
- TYPE_STUB_DECL (tt) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
- TYPE_NAME (tt) = x;
- TREE_USED (tt) = TREE_USED (x);
- TREE_TYPE (x) = tt;
+ if (tt != error_mark_node)
+ {
+ tt = build_variant_type_copy (tt);
+ TYPE_STUB_DECL (tt) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
+ TYPE_NAME (tt) = x;
+ TREE_USED (tt) = TREE_USED (x);
+ TREE_TYPE (x) = tt;
+ }
}
}
Index: testsuite/g++.dg/cpp0x/pr71737.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr71737.C (revision 245274)
+++ testsuite/g++.dg/cpp0x/pr71737.C (working copy)
@@ -0,0 +1,13 @@
+// PR c++/78765
+// { dg-do compile { target c++11 } }
+
+template <template <typename ...> class TT>
+struct quote {
+ template <typename ...Ts>
+ using apply = TT<Ts...>; // { dg-error "pack expansion" }
+};
+
+template <typename>
+using to_int_t = int;
+
+using t = quote<quote<to_int_t>::apply>::apply<int>;
Index: tree-inline.c
===================================================================
--- tree-inline.c (revision 245274)
+++ tree-inline.c (working copy)
@@ -375,7 +375,8 @@ remap_decl (tree decl, copy_body_data *id)
/* Preserve the invariant that DECL_ORIGINAL_TYPE != TREE_TYPE,
which is enforced in gen_typedef_die when DECL_ABSTRACT_ORIGIN
is not set on the TYPE_DECL, for example in LTO mode. */
- if (DECL_ORIGINAL_TYPE (t) == TREE_TYPE (t))
+ if (DECL_ORIGINAL_TYPE (t) == TREE_TYPE (t)
+ && TREE_TYPE (t) != error_mark_node)
{
tree x = build_variant_type_copy (TREE_TYPE (t));
TYPE_STUB_DECL (x) = TYPE_STUB_DECL (TREE_TYPE (t));
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 245274)
+++ cp/pt.c (working copy)
@@ -12876,11 +12876,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t com
args, complain, in_decl);
/* Preserve a typedef that names a type. */
- if (is_typedef_decl (r))
+ if (is_typedef_decl (r) && type != error_mark_node)
{
DECL_ORIGINAL_TYPE (r) = NULL_TREE;
set_underlying_type (r);
- if (TYPE_DECL_ALIAS_P (r) && type != error_mark_node)
+ if (TYPE_DECL_ALIAS_P (r))
/* An alias template specialization can be dependent
even if its underlying type is not. */
TYPE_DEPENDENT_P_VALID (TREE_TYPE (r)) = false;
Index: testsuite/g++.dg/cpp0x/pr71737.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr71737.C (revision 245274)
+++ testsuite/g++.dg/cpp0x/pr71737.C (working copy)
@@ -0,0 +1,13 @@
+// PR c++/78765
+// { dg-do compile { target c++11 } }
+
+template <template <typename ...> class TT>
+struct quote {
+ template <typename ...Ts>
+ using apply = TT<Ts...>; // { dg-error "pack expansion" }
+};
+
+template <typename>
+using to_int_t = int;
+
+using t = quote<quote<to_int_t>::apply>::apply<int>;