From ae83b9deb87787371cd94b4417e160d41dd0322c Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 13 Nov 2019 08:42:56 +0000 Subject: [PATCH] [C++] Fix interaction between aka changes and DR1558 (PR92206) 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 safely strip aliases with dependent template parameters. 2019-11-13 Richard Sandiford 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. From-SVN: r278119 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/cp-tree.h | 7 ++++++- gcc/cp/tree.c | 6 ++++-- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C | 9 +++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C | 8 ++++++++ 7 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bf50b1bcfa9..5dcf13bbc89 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2019-11-13 Richard Sandiford + + 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. + 2019-11-12 Nathan Sidwell * name-lookup.c (lookup_using_decl): New function, merged from ... diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index adc021b2a5c..42afe1bd5cb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5759,8 +5759,13 @@ enum auto_deduction_context 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. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index ba635d4ddbd..6c39c004b01 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1488,7 +1488,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) 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_attributes, unsigned int flags) && !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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 19243cfb6bf..a253a5397cc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-11-13 Richard Sandiford + + 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. + 2019-11-13 Martin Liska * gcc.dg/params/params.exp: Restore test by parsing output diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C new file mode 100644 index 00000000000..c3f7b1977db --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C @@ -0,0 +1,9 @@ +// { dg-require-effective-target c++11 } + +template struct A {}; +template using alias1 = A; +template class B { + using alias2 = alias1>; // { dg-error {no type named 'value'} } + A a; // { dg-bogus {no type named 'value'} } +}; +B b; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C new file mode 100644 index 00000000000..31d73d6bad3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C @@ -0,0 +1,14 @@ +// { dg-require-effective-target c++11 } + +template struct A; +class Vector { + template struct TypeIsGCThing { + template ::Type> using Vector = Vector; + struct B; + template class ContainerIter { + using Action = B; + using ActionVector = Vector; + ContainerIter a; + }; + }; +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C new file mode 100644 index 00000000000..6698a366411 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C @@ -0,0 +1,8 @@ +// { dg-require-effective-target c++11 } + +template void a(); +template struct b; +template using c = int; +template )> using f = e; +template using g = f; +template c>::i> j; -- 2.30.2