https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104008

--- Comment #9 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Marek Polacek <mpola...@gcc.gnu.org>:

https://gcc.gnu.org/g:c7a6a32739d62deab03266e2b5449fce261b1ecb

commit r12-7710-gc7a6a32739d62deab03266e2b5449fce261b1ecb
Author: Marek Polacek <pola...@redhat.com>
Date:   Wed Mar 16 09:34:34 2022 -0400

    c++: alias template and empty parameter packs [PR104008]

    Zero-length pack expansions are treated as if no list were provided
    at all, that is, with

      template<typename...> struct S { };
      template<typename T, typename... Ts>
      void g() {
        S<std::is_same<T, Ts>...>;
      }

    g<int> will result in S<>.  In the following test we have something
    similar:

      template <typename T, typename... Ts>
      using IsOneOf = disjunction<is_same<T, Ts>...>;

    and then we have "IsOneOf<OtherHolders>..." where OtherHolders is an
    empty pack.  Since r11-7931, we strip_typedefs in TYPE_PACK_EXPANSION.
    In this test that results in "IsOneOf<OtherHolders>" being turned into
    "disjunction<>".  So the whole expansion is now "disjunction<>...".  But
    then we error in make_pack_expansion because find_parameter_packs_r won't
    find the pack OtherHolders.

    We strip the alias template because dependent_alias_template_spec_p says
    it's not dependent.  It it not dependent because this alias is not
    TEMPLATE_DECL_COMPLEX_ALIAS_P.  My understanding is that currently we
    consider an alias complex if it

    1) expands a pack from the enclosing class, as in

        template<template<typename... U> typename... TT>
        struct S {
          template<typename... Args>
          using X = P<TT<Args...>...>;
        };

       where the alias expands TT; or

    2) the expansion does *not* name all the template parameters, as in

        template<typename...> struct R;
        template<typename T, typename... Ts>
        using U = R<X<Ts>...>;

       where T is not named in the expansion.

    But IsOneOf is neither.  And it can't know how it's going to be used.
    Therefore I think we cannot make it complex (and in turn dependent) to fix
    this bug.

    After much gnashing of teeth, I think we simply want to avoid stripping
    the alias if the new pattern doesn't have any parameter packs to expand.

            PR c++/104008

    gcc/cp/ChangeLog:

            * tree.cc (strip_typedefs): Don't strip an alias template when
            doing so would result in losing a parameter pack.

    gcc/testsuite/ChangeLog:

            * g++.dg/cpp0x/variadic-alias3.C: New test.
            * g++.dg/cpp0x/variadic-alias4.C: New test.

Reply via email to