+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 ...
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. */
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;
&& !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);
+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
--- /dev/null
+// { 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;
--- /dev/null
+// { 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;
+ };
+ };
+};
--- /dev/null
+// { 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;