[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 <richard.sandiford@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. From-SVN: r278119
This commit is contained in:
parent
9b6e95d30e
commit
ae83b9deb8
7 changed files with 57 additions and 3 deletions
|
@ -1,3 +1,12 @@
|
|||
2019-11-13 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
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 <nathan@acm.org>
|
||||
|
||||
* name-lookup.c (lookup_using_decl): New function, merged from ...
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2019-11-13 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
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 <mliska@suse.cz>
|
||||
|
||||
* gcc.dg/params/params.exp: Restore test by parsing output
|
||||
|
|
9
gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C
Normal file
|
@ -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;
|
14
gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C
Normal file
14
gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C
Normal file
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
8
gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C
Normal file
8
gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C
Normal file
|
@ -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;
|
Loading…
Add table
Reference in a new issue