https://wandbox.org/permlink/B02uUhc2QP8OChB9 ==== template<class T> struct A { A(int); }; template<class T> A(T) -> A<T*>; template<class T, class = int> using B = A<T>; B a(0); ==== prog.cc:10:12: internal compiler error: in alias_ctad_tweaks, at cp/pt.c:28223 10 | B a((int*)0); | ^ 0x5b9faa alias_ctad_tweaks ../../source/gcc/cp/pt.c:28223 0x5b9faa deduction_guides_for ../../source/gcc/cp/pt.c:28395 0x7048b3 do_class_deduction ../../source/gcc/cp/pt.c:28500 0x7048b3 do_auto_deduction(tree_node*, tree_node*, tree_node*, int, auto_deduction_context, tree_node*, int) ../../source/gcc/cp/pt.c:28629 0x6693e6 cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int) ../../source/gcc/cp/decl.c:7463 0x6eb461 cp_parser_init_declarator ../../source/gcc/cp/parser.c:20762 0x6ce805 cp_parser_simple_declaration ../../source/gcc/cp/parser.c:13627 0x6f3962 cp_parser_declaration ../../source/gcc/cp/parser.c:13325 0x6f4084 cp_parser_translation_unit ../../source/gcc/cp/parser.c:4723 0x6f4084 c_parse_file() ../../source/gcc/cp/parser.c:43563 0x7bb56b c_common_parse_file() ../../source/gcc/c-family/c-opts.c:1186 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. ==== The error disappears if `A<T*>` is changed to `A<T>`, or if `, class = int` is removed.
Confirmed.
commit 1a291106384cabc73da0bc0f457b1cd3a4015970 Author: Jason Merrill <jason@redhat.com> Date: Wed Nov 27 17:05:53 2019 -0500 Implement P1814R0, CTAD for alias templates. This patch implements C++20 class template argument deduction for alias templates, which works by a moderately arcane transformation of the deduction guides for the underlying class template. When implementing it, it seemed that I could simplify the rules in the draft a bit and get essentially the same effect; I'll be emailing the committee to that effect soon. gcc/cp/ * pt.c (rewrite_tparm_list): Factor out of build_deduction_guide. (maybe_aggr_guide): Check for copy-init here. (alias_ctad_tweaks, deduction_guides_for): New. (ctor_deduction_guides_for): Factor out of do_class_deduction. (ctad_template_p): New. * parser.c (cp_parser_simple_type_specifier): Use it. * constraint.cc (append_constraint): New. gcc/c-family/ * c-cppbuiltin.c (c_cpp_builtins): Update __cpp_deduction_guides. From-SVN: r278786
It appears that alias_ctad_tweaks assumes the deduction of the right hand side of the deduction guide from the alias template does not fail. > int err = unify (ftparms, targs, ret, utype, UNIFY_ALLOW_NONE, false); > gcc_assert (!err); But this can fail if the RHS of the deduction guide contains `T*` or the like. I guess this is exactly where the simplification mentioned in r278786 fails to work.
*** Bug 93867 has been marked as a duplicate of this bug. ***
Another test from Bug 93867: template <typename CharT, unsigned N> struct basic_fixed_string { constexpr basic_fixed_string(const CharT *p) { for (int i = 0; i < N; ++i) { m_data[i] = p[i]; } } CharT m_data[N] {}; }; template <typename CharT, int N> basic_fixed_string(const CharT (&)[N]) -> basic_fixed_string<CharT,N>; template <unsigned N> using fixed_string = basic_fixed_string<char, N>; template <fixed_string path> constexpr int foo() { return 42; } int main(int argc, char const *argv[]) { foo<"hello">(); return 0; }
Another test case from Peter O'Rourke on cpplang Slack: https://godbolt.org/z/YEw4v9 template<int> struct A {}; template<int> A() -> A<1>; template<int> using B = A<2>; B bar;
I think there is another example of the same bug. This can be pretty common code in C++20: #include <tuple> template<typename... T> using p = std::pair<T...>; auto x = p{int{}, int{}};
Another example, with gcc trunk: https://godbolt.org/z/ovxr4a. --- template<typename T, bool B = false> struct Foo { Foo(T) {} }; template<typename T> Foo(T) -> Foo<T>; template<typename T> using Bar = Foo<T, true>; Bar b{0}; --- This error only seems to occur when using deduction guides that are different from the implicitly generated set, e.g. as in this case omitting a parameter.
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:1a19d334ce493ec2ce2daeac74beef63fd67e2bc commit r11-8104-g1a19d334ce493ec2ce2daeac74beef63fd67e2bc Author: Jason Merrill <jason@redhat.com> Date: Fri Apr 9 18:02:38 2021 -0400 c++: deduction guide using alias [PR99180] alias_ctad_tweaks was expecting that all deduction guides for the class would be suitable for deduction from the alias definition; in this case, the deduction guide uses 'true' and the alias B uses 'false', so deduction fails. But that's OK, we just don't use that deduction guide. I also noticed that we were giving up on deduction entirely if substitution failed for some guide; we should only give up on that particular deduction guide. We ought to give a better diagnostic about this case when deduction fails, but that can wait. gcc/cp/ChangeLog: PR c++/99180 PR c++/93295 PR c++/93867 PR c++/99118 PR c++/96873 * pt.c (alias_ctad_tweaks): Handle failure better. gcc/testsuite/ChangeLog: PR c++/99180 PR c++/93295 PR c++/93867 PR c++/95486 * g++.dg/cpp2a/class-deduction-alias5.C: New test. * g++.dg/cpp2a/class-deduction-alias6.C: New test. * g++.dg/cpp2a/class-deduction-alias7.C: New test. * g++.dg/cpp2a/class-deduction-alias8.C: New test.
*** Bug 99118 has been marked as a duplicate of this bug. ***
*** Bug 96873 has been marked as a duplicate of this bug. ***
Let's call this a duplicate of the one that already has the regression tag. *** This bug has been marked as a duplicate of bug 99180 ***
The releases/gcc-10 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:92e9b2a995f718f1c2ab1cd0840b439c24d3535f commit r10-9852-g92e9b2a995f718f1c2ab1cd0840b439c24d3535f Author: Jason Merrill <jason@redhat.com> Date: Fri Apr 9 18:02:38 2021 -0400 c++: deduction guide using alias [PR99180] alias_ctad_tweaks was expecting that all deduction guides for the class would be suitable for deduction from the alias definition; in this case, the deduction guide uses 'true' and the alias B uses 'false', so deduction fails. But that's OK, we just don't use that deduction guide. I also noticed that we were giving up on deduction entirely if substitution failed for some guide; we should only give up on that particular deduction guide. We ought to give a better diagnostic about this case when deduction fails, but that can wait. gcc/cp/ChangeLog: PR c++/99180 PR c++/93295 PR c++/93867 PR c++/99118 PR c++/96873 * pt.c (alias_ctad_tweaks): Handle failure better. gcc/testsuite/ChangeLog: PR c++/99180 PR c++/93295 PR c++/93867 PR c++/95486 * g++.dg/cpp2a/class-deduction-alias5.C: New test. * g++.dg/cpp2a/class-deduction-alias6.C: New test. * g++.dg/cpp2a/class-deduction-alias7.C: New test. * g++.dg/cpp2a/class-deduction-alias8.C: New test.