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.