Commit ae83b9de by Richard Sandiford Committed by Richard Sandiford

[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
parent 9b6e95d3
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> 2019-11-12 Nathan Sidwell <nathan@acm.org>
* name-lookup.c (lookup_using_decl): New function, merged from ... * name-lookup.c (lookup_using_decl): New function, merged from ...
......
...@@ -5759,8 +5759,13 @@ enum auto_deduction_context ...@@ -5759,8 +5759,13 @@ enum auto_deduction_context
STF_USER_VISIBLE: use heuristics to try to avoid stripping user-facing STF_USER_VISIBLE: use heuristics to try to avoid stripping user-facing
aliases of internal details. This is intended for diagnostics, 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_USER_VISIBLE = 1U;
const unsigned int STF_STRIP_DEPENDENT = 1U << 1;
/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
node. */ node. */
......
...@@ -1488,7 +1488,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) ...@@ -1488,7 +1488,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
if (t == TYPE_CANONICAL (t)) if (t == TYPE_CANONICAL (t))
return 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 /* DR 1558: However, if the template-id is dependent, subsequent
template argument substitution still applies to the template-id. */ template argument substitution still applies to the template-id. */
return t; return t;
...@@ -1673,7 +1674,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) ...@@ -1673,7 +1674,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
&& !user_facing_original_type_p (t)) && !user_facing_original_type_p (t))
return t; return t;
result = strip_typedefs (DECL_ORIGINAL_TYPE (TYPE_NAME (t)), result = strip_typedefs (DECL_ORIGINAL_TYPE (TYPE_NAME (t)),
remove_attributes, flags); remove_attributes,
flags | STF_STRIP_DEPENDENT);
} }
else else
result = TYPE_MAIN_VARIANT (t); result = TYPE_MAIN_VARIANT (t);
......
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> 2019-11-13 Martin Liska <mliska@suse.cz>
* gcc.dg/params/params.exp: Restore test by parsing output * gcc.dg/params/params.exp: Restore test by parsing output
......
// { 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;
// { 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;
};
};
};
// { 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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment