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
14 changes: 14 additions & 0 deletions src/pending_changes/gh-533-alias-ctad-pack-requires.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[GH #533]
Alias template CTAD with a constrained constructor of a variadic class template

Class template argument deduction through an alias template could read freed
memory, and possibly crash, when a constructor of the underlying class
template had a parameter pack and a requires clause, e.g. aliases of
std::tuple with libstdc++. For example, with --c++20:

template<typename... E> struct S {
static constexpr bool c = true;
S(E...) requires c {}
};
template<typename... T> using A = S<T...>;
A a{1};
6 changes: 4 additions & 2 deletions src/templates.c
Original file line number Diff line number Diff line change
Expand Up @@ -45648,6 +45648,10 @@ On success, return the symbol for the new guide; otherwise return NULL.
a_routine_ptr rout;
a_ctws_state ctws_state;
a_boolean copy_error = FALSE;
/* ctws_state.alias_parameter_pack_mapping points to one of these and is
still used for the requires clauses after the block below. */
Dyn_array<a_template_param_ptr>
pack_mapping, alias_pack_mapping;

if (guide_template_params != NULL) {
a_symbol_ptr class_sym = symbol_for(ret_type)
Expand All @@ -45659,8 +45663,6 @@ On success, return the symbol for the new guide; otherwise return NULL.
a_template_arg_ptr alias_proto_args;
size_t number_of_guide_params = 0;
Dyn_array<a_boolean> nondeduced_args, used_parameters;
Dyn_array<a_template_param_ptr>
pack_mapping, alias_pack_mapping;

/* Substitute the prototype arguments of the template alias into each of
the deduced template arguments to record which template parameters of
Expand Down
1 change: 1 addition & 0 deletions tests/tests/regressions/.gh-533.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-533.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-533.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-533.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
15 changes: 15 additions & 0 deletions tests/tests/regressions/gh-533.sft.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//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 read a
// destroyed array (the mapping of template parameter packs) when substituting
// into the requires clause of a constructor of a class template with a
// parameter pack, e.g. aliases of std::tuple with libstdc++.

template<typename... E> struct S
{
static constexpr bool c = true;
S(E...) requires c {}
};
template<typename... T> using A = S<T...>;
A a{1};
Loading