diff mbox

[C++] PR 71737

Message ID 77c56a77-11c9-c23a-5681-b22279426384@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Feb. 9, 2017, 9:08 a.m. UTC
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: 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>;

Comments

Jason Merrill Feb. 9, 2017, 9:52 p.m. UTC | #1
On Thu, Feb 9, 2017 at 4:08 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> 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.

_4 seems consistent with the set_underlying_type behavior, I guess
let's go with that.

Jason
diff mbox

Patch

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));