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 <polacek@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.
Showing
gcc/testsuite/g++.dg/cpp2a/nontype-class28.C
0 → 100644
gcc/testsuite/g++.dg/cpp2a/nontype-class29.C
0 → 100644
Please
register
or
sign in
to comment