Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -54859,8 +54859,10 @@ is TRUE if the expression is the immediate operand of an "&" operator.
} /* if */
} else if (is_nontype_template_param_symbol(fund_sym)) {
/* A dependent construct. Represent it generically with a
tpck_template_ref constant. */
expl_templ_arg_list =
tpck_template_ref constant. Leave expl_templ_arg_list
unsubstituted, since scan_identifier will also substitute
it. */
a_template_arg_ptr subst_templ_arg_list =
copy_template_arg_list_with_substitution_rebuilding_arg_operands(
fund_sym, expl_templ_arg_list,
(a_template_param_ptr)NULL,
Expand All @@ -54875,7 +54877,7 @@ is TRUE if the expression is the immediate operand of an "&" operator.
con->variant.template_param.variant.template_ref.con =
sym->variant.constant;
con->variant.template_param.variant.template_ref.arg_list =
expl_templ_arg_list;
subst_templ_arg_list;
con->type = type_of_unknown_templ_param_nontype;
sym = alloc_symbol(sk_constant, sym->header,
&sym->decl_position);
Expand Down
18 changes: 18 additions & 0 deletions src/pending_changes/gh-532-alias-ctad-noexcept-template-call.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[GH #532]
Alias template CTAD with a template-id in a constructor noexcept specification

Class template argument deduction through an alias template could crash
when the noexcept specification of a constructor template of the underlying
class template called a member function template with the constructor's
template parameter pack as explicit template arguments, e.g. aliases of
std::tuple with libstdc++. The explicit template arguments were substituted
twice. For example, with --c++20:

template<typename... E> struct S {
template<typename... U> static constexpr bool n() { return true; }
S(const E&...) {}
template<typename... U> S(U&&...) noexcept(n<U...>()) {}
};
template<typename X, typename T> struct F {};
template<typename X, typename... T> using A = S<F<X, T>...>;
A a{F<int, int>{}};
1 change: 1 addition & 0 deletions tests/tests/regressions/.gh-532.rto/default.1.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fe_only -DTEST_NUMBER=1 --c++20 Test_name.c
1 change: 1 addition & 0 deletions tests/tests/regressions/.gh-532.rto/default.2.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fe_only -DTEST_NUMBER=2 --c++20 --g++ --gnu_version=150200 Test_name.c
1 change: 1 addition & 0 deletions tests/tests/regressions/.gh-532.rto/default.3.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fe_only -DTEST_NUMBER=3 --c++20 --clang --clang_version=220100 Test_name.c
1 change: 1 addition & 0 deletions tests/tests/regressions/.gh-532.rto/default.4.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fe_only -DTEST_NUMBER=4 --ms_c++20 --microsoft_version 1950 Test_name.c
18 changes: 18 additions & 0 deletions tests/tests/regressions/gh-532.sft.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//type:fp
//options:--c++20:--c++20 --g++ --gnu_version=150200:--c++20 --clang --clang_version=220100:--ms_c++20 --microsoft_version 1950

// Class template argument deduction through an alias template crashed when
// the noexcept specification of a constructor template called a member
// function template with the constructor's parameter pack as explicit
// template arguments, e.g. aliases of std::tuple with libstdc++. The
// explicit template arguments of the call were substituted twice.

template<typename... E> struct S
{
template<typename... U> static constexpr bool n() { return true; }
S(const E&...) {}
template<typename... U> S(U&&...) noexcept(n<U...>()) {}
};
template<typename X, typename T> struct F {};
template<typename X, typename... T> using A = S<F<X, T>...>;
A a{F<int, int>{}};
Loading