https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104594
Patrick Palka <ppalka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=67898 CC| |jason at gcc dot gnu.org --- Comment #3 from Patrick Palka <ppalka at gcc dot gnu.org> --- I wonder if this is ultimately a manifestation of PR67898. After substituting into an NTTP, if the type of the NTTP or the type of its argument is still dependent then we can't yet check the implicit conversion from the argument type to the parameter type. And we don't encode this implicit conversion within the substituted argument (as e.g. an IMPLICIT_CONV_EXPR) because we'll check the conversion again when we call coerce_template_parms the next time around anyway. However, as PR67898 illustrates, this causes problems if a subsequent template parameter refers to this NTTP, e.g: template<class T, T V, class = decltype(V)> struct A; template<class U, int W> using B = A<U, W>; Here A<U, W> should resolve to A<U, W, U> but it instead resolves to A<U, W, int> because we don't encode the implicit conversion (from int to U) within the substituted argument for V, and hence substitution into the default argument yields decltype(W), which is just int, rather than yielding decltype(U(W)). Seems we can run into the same issue during normalization as illustrated in this current PR. The normal form for E in commment #2 is just (X != 0) (with mapping X -> X) but we really should be encoding the implicit conversions into the mapping (yielding something like X -> unsigned(int(X))). So I wonder if the best way to tackle this PR is to tackle PR67898 more generally?