https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127855

            Bug ID: 127855
           Summary: [GCC C++17] CTAD through an alias of an alias whose
                    target is `const Y<T>`: pedwarn, then ICE in
                    `set_constraints` (constraint.cc:1053)
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: 0599jiangyc at gmail dot com
  Target Milestone: ---

**Repo:** gcc-mirror/gcc · **Commit:** `d373724d1` (master, 2026-09-17) ·
**Build:** `--enable-languages=c,c++ --disable-bootstrap
--enable-checking=yes,extra,rtl` (x86_64-pc-linux-gnu, Ubuntu 22.04)


## What happens

Before C++20, `do_auto_deduction` accepts class template argument deduction
through an alias template only when the alias is equivalent to another
template: it pedwarns, prints "use 'Z' directly instead", and continues with
`tmpl = get_underlying_template (tmpl)`. Here `W<T>` is equivalent to `Z<T>`,
but `Z<T>` is itself an alias template (`const Y<T>`, not equivalent to `Y`).
The substituted template is never checked again, so C++20 alias CTAD
(`alias_ctad_tweaks`) runs in C++17 mode and asserts `flag_concepts` in
`set_constraints`:

```
gcc-alias-ctad-cxx17-const-alias-of-alias.cc:5:7: warning: alias template
deduction only available with '-std=c++20' or '-std=gnu++20'
    5 | W w (s);
      |       ^
gcc-alias-ctad-cxx17-const-alias-of-alias.cc:5:7: note: use 'template<class T>
using Z = const Y<T>' directly instead
gcc-alias-ctad-cxx17-const-alias-of-alias.cc:5:7: internal compiler error: in
set_constraints, at cp/constraint.cc:1053
0x7cf067 set_constraints(tree_node*, tree_node*)
        gcc/cp/constraint.cc:1053
0x104ac47 alias_ctad_tweaks
        gcc/cp/pt.cc:32433
0x106af9f deduction_guides_for
        gcc/cp/pt.cc:32735
0x104b912 do_class_deduction
        gcc/cp/pt.cc:32907
0x104b912 do_auto_deduction(tree_node*, tree_node*, tree_node*, int,
auto_deduction_context, tree_node*, int, tree_node*)
        gcc/cp/pt.cc:33129
0xedf561 cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int,
cp_decomp*)
        gcc/cp/decl.cc:9714
0x1010250 cp_parser_init_declarator
        gcc/cp/parser.cc:26526
```

## Reproducer

`gcc-alias-ctad-cxx17-const-alias-of-alias.cc`:

```c++
template <class> struct Y { };
template <class T> using Z = const Y<T>;
template <class T> using W = Z<T>;
Y<int> s;
W w (s);
```

```bash
g++ -fsyntax-only -std=c++17 gcc-alias-ctad-cxx17-const-alias-of-alias.cc
```

`-std=gnu++17` behaves the same, at any `-O`; C++14 and earlier reject `W w
(s);` (no CTAD). With `Z w (s);` the front end reports the hard error "alias
template deduction only available with '-std=c++20'" and stops. With `using Z =
Y<T>;` (no `const`) the pedwarn path works, because `Z` is then equivalent to
`Y`. In C++20 the same code is rejected with a normal "class template argument
deduction failed". GCC 11.4 rejects it with an error.

## Expected

The error that `Z w (s);` gets. In `do_auto_deduction` (pt.cc, "Be permissive
with equivalent alias templates"), after `tmpl = u;` the replacement can still
be an alias template. Using the fully resolved template, or going round the
`cxx_dialect < cxx20 && DECL_ALIAS_TEMPLATE_P` check again, would avoid
reaching `alias_ctad_tweaks` before C++20.

## Notes

Found by fusing the test for PR c++/100032 (`template <class T> using Z = const
Y<T>;`) with a PR c++/94149 test. Neither seed alone crashes (the original
fused program used `W w(s);` with an unrelated `struct S`). 3/3 reproductions,
empty-input control clean. ICE after a pedwarn only, so in effect ice-on-valid
for GNU dialects. The code is unchanged on master `a02e200` (2026-10-10): no
commit touches `constraint.cc`, and the `get_underlying_template` block in
`pt.cc` is the same.
  • [Bug c++/127855] New: [GCC C++17... 0599jiangyc at gmail dot com via Gcc-bugs

Reply via email to