if (TYPE_P (pat))
{
type = strip_typedefs (pat, remove_attributes, flags);
- if (type != pat)
+ /* Empty packs can thwart our efforts here. Consider
+
+ template <typename T, typename... Ts>
+ using IsOneOf = disjunction<is_same<T, Ts>...>;
+
+ where IsOneOf seemingly uses all of its template parameters in
+ its expansion (and does not expand a pack from the enclosing
+ class), so the alias is not marked as complex. However, it may
+ be used as in "IsOneOf<Ts>", where Ts is an empty parameter pack,
+ and stripping it down into "disjunction<>" here would exclude the
+ Ts pack, resulting in an error. */
+ if (type != pat && uses_parameter_packs (type))
{
result = copy_node (t);
PACK_EXPANSION_PATTERN (result) = type;
--- /dev/null
+// PR c++/104008
+// { dg-do compile { target c++11 } }
+
+template <typename...> struct conjunction;
+template <typename...> struct disjunction;
+template <typename, typename> struct is_same;
+template <bool> struct enable_if;
+template <bool _Cond> using enable_if_t = typename enable_if<_Cond>::type;
+struct B;
+struct __uniq_ptr_impl {
+ struct _Ptr {
+ using type = B *;
+ };
+ using pointer = _Ptr::type;
+};
+struct unique_ptr {
+ using pointer = __uniq_ptr_impl::pointer;
+ unique_ptr(pointer);
+};
+template <typename T, typename... Ts>
+using IsOneOf = disjunction<is_same<T, Ts>...>;
+
+template <typename...> struct any_badge;
+
+struct badge {
+ badge(any_badge<>);
+ badge();
+};
+
+template <typename...> struct any_badge {
+ template <typename... OtherHolders,
+ enable_if_t<conjunction<IsOneOf<OtherHolders>...>::value>>
+ any_badge();
+};
+
+template <typename, typename... _Args> unique_ptr make_unique(_Args... __args);
+
+struct B {
+ B(badge);
+ unique_ptr b_ = make_unique<B>(badge{});
+};
+
+template <typename, typename... _Args> unique_ptr make_unique(_Args... __args) {
+ return new B(__args...);
+}
--- /dev/null
+// PR c++/104008
+// { dg-do compile { target c++11 } }
+// Differs from variadic-alias3.C only in the pattern of a pack expansion
+// in line 34. But it's important to check that we also deal with more
+// complex patterns.
+
+template <typename...> struct conjunction;
+template <typename...> struct disjunction;
+template <typename, typename> struct is_same;
+template <bool> struct enable_if;
+template <bool _Cond> using enable_if_t = typename enable_if<_Cond>::type;
+struct B;
+struct __uniq_ptr_impl {
+ struct _Ptr {
+ using type = B *;
+ };
+ using pointer = _Ptr::type;
+};
+struct unique_ptr {
+ using pointer = __uniq_ptr_impl::pointer;
+ unique_ptr(pointer);
+};
+template <typename T, typename... Ts>
+using IsOneOf = disjunction<is_same<T, Ts>...>;
+
+template <typename...> struct any_badge;
+
+struct badge {
+ badge(any_badge<>);
+ badge();
+};
+
+template <typename...> struct any_badge {
+ template <typename... OtherHolders,
+ enable_if_t<conjunction<IsOneOf<OtherHolders>&...>::value>>
+ any_badge();
+};
+
+template <typename, typename... _Args> unique_ptr make_unique(_Args... __args);
+
+struct B {
+ B(badge);
+ unique_ptr b_ = make_unique<B>(badge{});
+};
+
+template <typename, typename... _Args> unique_ptr make_unique(_Args... __args) {
+ return new B(__args...);
+}