Bug 93295 - ICE in alias_ctad_tweaks
Summary: ICE in alias_ctad_tweaks
Status: RESOLVED DUPLICATE of bug 99180
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 93867 96873 99118 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-01-16 20:27 UTC by ensadc
Modified: 2021-05-20 21:35 UTC (History)
10 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-01-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ensadc 2020-01-16 20:27:38 UTC
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.
Comment 1 Marek Polacek 2020-01-16 20:41:33 UTC
Confirmed.
Comment 2 Marek Polacek 2020-01-16 20:50:49 UTC
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
Comment 3 ensadc 2020-01-18 06:38:36 UTC
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.
Comment 4 Marek Polacek 2020-02-21 13:35:36 UTC
*** Bug 93867 has been marked as a duplicate of this bug. ***
Comment 5 Marek Polacek 2020-02-21 13:36:29 UTC
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;
}
Comment 6 Arthur O'Dwyer 2020-05-21 00:17:25 UTC
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;
Comment 7 oficsu 2020-07-29 14:38:20 UTC
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{}};
Comment 8 Steven Franzen 2020-10-13 13:24:46 UTC
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.
Comment 9 GCC Commits 2021-04-10 04:07:10 UTC
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.
Comment 10 Jason Merrill 2021-04-10 04:13:09 UTC
*** Bug 99118 has been marked as a duplicate of this bug. ***
Comment 11 Jason Merrill 2021-04-10 04:14:21 UTC
*** Bug 96873 has been marked as a duplicate of this bug. ***
Comment 12 Jason Merrill 2021-04-10 04:17:02 UTC
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 ***
Comment 13 GCC Commits 2021-05-20 21:35:42 UTC
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.