Ping
Richard Sandiford <richard.sandif...@arm.com> writes: > 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? > > Richard > > > 2019-10-25 Richard Sandiford <richard.sandif...@arm.com> > > gcc/cp/ > PR c++/92206 > * cp-tree.h (STF_ASSUME_VALID): New constant. > * 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. > > Index: gcc/cp/cp-tree.h > =================================================================== > --- gcc/cp/cp-tree.h 2019-10-25 09:21:28.098331304 +0100 > +++ gcc/cp/cp-tree.h 2019-10-25 14:51:22.618009886 +0100 > @@ -5728,8 +5728,12 @@ #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_ASSUME_VALID: assume where possible that the given type is valid, > + relying on code elsewhere to report any appropriate diagnostics. */ > const unsigned int STF_USER_VISIBLE = 1U; > +const unsigned int STF_ASSUME_VALID = 1U << 1; > > /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM > node. */ > Index: gcc/cp/tree.c > =================================================================== > --- gcc/cp/tree.c 2019-10-22 08:47:01.255327861 +0100 > +++ gcc/cp/tree.c 2019-10-25 14:51:22.618009886 +0100 > @@ -1489,7 +1489,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_ASSUME_VALID) > + && 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; > @@ -1674,7 +1675,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_ASSUME_VALID); > } > else > result = TYPE_MAIN_VARIANT (t); > Index: gcc/testsuite/g++.dg/pr92206-1.C > =================================================================== > --- /dev/null 2019-09-17 11:41:18.176664108 +0100 > +++ gcc/testsuite/g++.dg/pr92206-1.C 2019-10-25 14:51:22.618009886 +0100 > @@ -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/pr92206-2.C > =================================================================== > --- /dev/null 2019-09-17 11:41:18.176664108 +0100 > +++ gcc/testsuite/g++.dg/pr92206-2.C 2019-10-25 14:51:22.618009886 +0100 > @@ -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/pr92206-3.C > =================================================================== > --- /dev/null 2019-09-17 11:41:18.176664108 +0100 > +++ gcc/testsuite/g++.dg/pr92206-3.C 2019-10-25 14:51:22.618009886 +0100 > @@ -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;