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

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

https://gcc.gnu.org/g:423284053ec51832bc4c823fb90dc41e632e37ac

commit r10-6329-g423284053ec51832bc4c823fb90dc41e632e37ac
Author: Marek Polacek <pola...@redhat.com>
Date:   Tue Jan 28 17:44:21 2020 -0500

    c++: Fix class NTTP with template arguments [PR92948]

    This PR points out an ICE with an alias template and class NTTP, but I
    found that there are more issues.  Trouble arise when we use a
    (non-type) template parameter as an argument to the template arg list of
    a template that accepts a class NTTP and a conversion to a class is
    involved, e.g.

      struct A { A(int) { } };
      template<A a> struct B { };

      template<int X> void fn () {
          B<X> b;
      }

    Normally for such a conversion we create a TARGET_EXPR with an
    AGGR_INIT_EXPR that calls a __ct_comp with some arguments, but not in
    this case: when converting X to type A in convert_nontype_argument we
    are in a template and the template parameter 'X' is value-dependent, and
    AGGR_INIT_EXPR don't work in templates.  So it just creates a TARGET_EXPR
    that contains "A::A(*this, X)", but with that overload resolution fails:
      error: no matching function for call to 'A::A(A*, int)'
    That happens because finish_call_expr for a BASELINK creates a dummy
    object, so we have 'this' twice.  I thought for the value-dependent case
    we could use IMPLICIT_CONV_EXPR, as in the patch below.  Note that I
    only do this when we convert to a different type than the type of the
    expr.  The point is to avoid the call to a converting ctor.

    The second issue was an ICE in tsubst_copy: when there's a conversion
    like the above involved then
     /* Wrapper to make a C++20 template parameter object const.  */
      op = tsubst_copy (op, args, complain, in_decl);
    might not produce a _ZT... VAR_DECL with const type, so the assert
      gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (op)));
    fails.  Allowing IMPLICIT_CONV_EXPR there probably makes sense.

    And since convert_nontype_argument uses value_dependent_expression_p
    a lot, I used a dedicated bool to speed things up.

    2020-01-29  Marek Polacek  <pola...@redhat.com>

        PR c++/92948 - Fix class NTTP with template arguments.
        * pt.c (convert_nontype_argument): Use IMPLICIT_CONV_EXPR when
        converting a value-dependent expression to a class type.
        (tsubst_copy) <case VIEW_CONVERT_EXPR>: Allow IMPLICIT_CONV_EXPR
        as the result of the tsubst_copy call.

        * g++.dg/cpp2a/nontype-class28.C: New test.
        * g++.dg/cpp2a/nontype-class29.C: New test.

Reply via email to