Jason Merrill <ja...@redhat.com> writes:
> On 10/25/19 2:53 PM, Richard Sandiford wrote:
>> One of the changes in r277281 was to make the typedef variant
>> handling in strip_typedefs pass the raw DECL_ORIGINAL_TYPE to the
>> recursive call, instead of applying TYPE_MAIN_VARIANT first.
>> This PR shows that that interacts badly with the implementation
>> of DR1558, because we then refuse to strip aliases with dependent
>> template parameters and trip:
>> 
>>    gcc_assert (!typedef_variant_p (result)
>>            || ((flags & STF_USER_VISIBLE)
>>                && !user_facing_original_type_p (result)));
>> 
>> Keeping the current behaviour but suppressing the ICE leads to a
>> duplicate error (the dg-bogus in the first test), so that didn't
>> seem like a good fix.
>> 
>> I assume keeping the alias should never actually be necessary for
>> DECL_ORIGINAL_TYPEs, because it will already have been checked
>> somewhere, even for implicit TYPE_DECLs.  This patch therefore
>> passes a flag to say that we can assume the type is validated
>> elsewhere.
>> 
>> It seems a rather clunky fix, sorry, but restoring the
>> TYPE_MAIN_VARIANT (...) isn't compatible with the aka stuff.
>> 
>> Bootstrapped & regression-tested on aarch64-linux-gnu.  OK to install?
>
>> 2019-10-25  Richard Sandiford  <richard.sandif...@arm.com>
>> 
>> gcc/cp/
>>      PR c++/92206
>>      * cp-tree.h (STF_ASSUME_VALID): New constant.
>
> Let's call this STF_STRIP_DEPENDENT.
>
>>      * tree.c (strip_typedefs): Add STF_ASSUME_VALID to the flags
>>      when calling strip_typedefs recursively on a DECL_ORIGINAL_TYPE.
>>      Don't apply the fix for DR1558 in that case; allow aliases with
>>      dependent template parameters to be stripped instead.
>> 
>> gcc/testsuite/
>>      PR c++/92206
>>      * g++.dg/pr92206-1.C: New test.
>>      * g++.dg/pr92206-2.C: Likewise.
>>      * g++.dg/pr92206-3.C: Likewise.
>
> Let's call these g++.dg/cpp0x/alias-decl-pr92206*.
>
> OK with those changes.

Thanks.  For the record, here's what I committed after retesting as above.

Richard


2019-11-13  Richard Sandiford  <richard.sandif...@arm.com>

gcc/cp/
        PR c++/92206
        * cp-tree.h (STF_STRIP_DEPENDENT): New constant.
        * tree.c (strip_typedefs): Add STF_STRIP_DEPENDENT to the flags
        when calling strip_typedefs recursively on a DECL_ORIGINAL_TYPE.
        Don't apply the fix for DR1558 in that case; allow aliases with
        dependent template parameters to be stripped instead.

gcc/testsuite/
        PR c++/92206
        * g++.dg/cpp0x/alias-decl-pr92206-1.C: New test.
        * g++.dg/cpp0x/alias-decl-pr92206-2.C: Likewise.
        * g++.dg/cpp0x/alias-decl-pr92206-3.C: Likewise.

Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h    2019-11-13 08:40:56.000000000 +0000
+++ gcc/cp/cp-tree.h    2019-11-13 08:41:13.222023539 +0000
@@ -5759,8 +5759,13 @@ #define TFF_POINTER                              (1
 
    STF_USER_VISIBLE: use heuristics to try to avoid stripping user-facing
        aliases of internal details.  This is intended for diagnostics,
-       where it should (for example) give more useful "aka" types.  */
+       where it should (for example) give more useful "aka" types.
+
+   STF_STRIP_DEPENDENT: allow the stripping of aliases with dependent
+       template parameters, relying on code elsewhere to report any
+       appropriate diagnostics.  */
 const unsigned int STF_USER_VISIBLE = 1U;
+const unsigned int STF_STRIP_DEPENDENT = 1U << 1;
 
 /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
    node.  */
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c       2019-11-13 08:40:56.000000000 +0000
+++ gcc/cp/tree.c       2019-11-13 08:41:13.222023539 +0000
@@ -1488,7 +1488,8 @@ strip_typedefs (tree t, bool *remove_att
   if (t == TYPE_CANONICAL (t))
     return t;
 
-  if (dependent_alias_template_spec_p (t))
+  if (!(flags & STF_STRIP_DEPENDENT)
+      && dependent_alias_template_spec_p (t))
     /* DR 1558: However, if the template-id is dependent, subsequent
        template argument substitution still applies to the template-id.  */
     return t;
@@ -1673,7 +1674,8 @@ strip_typedefs (tree t, bool *remove_att
              && !user_facing_original_type_p (t))
            return t;
          result = strip_typedefs (DECL_ORIGINAL_TYPE (TYPE_NAME (t)),
-                                  remove_attributes, flags);
+                                  remove_attributes,
+                                  flags | STF_STRIP_DEPENDENT);
        }
       else
        result = TYPE_MAIN_VARIANT (t);
Index: gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C
===================================================================
--- /dev/null   2019-09-17 11:41:18.176664108 +0100
+++ gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C   2019-11-13 
08:41:13.226023511 +0000
@@ -0,0 +1,9 @@
+// { dg-require-effective-target c++11 }
+
+template<typename> struct A {};
+template<typename T1, typename T2 = typename T1::value> using alias1 = A<T1>;
+template<typename T> class B {
+  using alias2 = alias1<A<T>>; // { dg-error {no type named 'value'} }
+  A<alias2> a; // { dg-bogus {no type named 'value'} }
+};
+B<int> b;
Index: gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C
===================================================================
--- /dev/null   2019-09-17 11:41:18.176664108 +0100
+++ gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C   2019-11-13 
08:41:13.226023511 +0000
@@ -0,0 +1,14 @@
+// { dg-require-effective-target c++11 }
+
+template <bool> struct A;
+class Vector {
+  template <typename> struct TypeIsGCThing {
+    template <typename T, typename A<T ::value>::Type> using Vector = Vector;
+    struct B;
+    template <typename> class ContainerIter {
+      using Action = B;
+      using ActionVector = Vector<Action, 0>;
+      ContainerIter<ActionVector> a;
+    };
+  };
+};
Index: gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C
===================================================================
--- /dev/null   2019-09-17 11:41:18.176664108 +0100
+++ gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C   2019-11-13 
08:41:13.226023511 +0000
@@ -0,0 +1,8 @@
+// { dg-require-effective-target c++11 }
+
+template <typename> void a();
+template <typename> struct b;
+template <bool> using c = int;
+template <typename d, typename e = decltype(a<d>)> using f = e;
+template <typename e> using g = f<e>;
+template <typename h> c<b<g<h>>::i> j;

Reply via email to