diff --git a/src/pending_changes/gh-533-alias-ctad-pack-requires.txt b/src/pending_changes/gh-533-alias-ctad-pack-requires.txt new file mode 100644 index 0000000000..02b836817f --- /dev/null +++ b/src/pending_changes/gh-533-alias-ctad-pack-requires.txt @@ -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 struct S { + static constexpr bool c = true; + S(E...) requires c {} + }; + template using A = S; + A a{1}; diff --git a/src/templates.c b/src/templates.c index 2737ad9316..ed870b7064 100644 --- a/src/templates.c +++ b/src/templates.c @@ -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 + pack_mapping, alias_pack_mapping; if (guide_template_params != NULL) { a_symbol_ptr class_sym = symbol_for(ret_type) @@ -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 nondeduced_args, used_parameters; - Dyn_array - 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 diff --git a/tests/tests/regressions/.gh-533.rto/default.1.1.txt b/tests/tests/regressions/.gh-533.rto/default.1.1.txt new file mode 100644 index 0000000000..32fc82e916 --- /dev/null +++ b/tests/tests/regressions/.gh-533.rto/default.1.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=1 --c++20 Test_name.c diff --git a/tests/tests/regressions/.gh-533.rto/default.2.1.txt b/tests/tests/regressions/.gh-533.rto/default.2.1.txt new file mode 100644 index 0000000000..15f97a3e0c --- /dev/null +++ b/tests/tests/regressions/.gh-533.rto/default.2.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=2 --c++20 --g++ --gnu_version=150200 Test_name.c diff --git a/tests/tests/regressions/.gh-533.rto/default.3.1.txt b/tests/tests/regressions/.gh-533.rto/default.3.1.txt new file mode 100644 index 0000000000..8f47794cbf --- /dev/null +++ b/tests/tests/regressions/.gh-533.rto/default.3.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=3 --c++20 --clang --clang_version=220100 Test_name.c diff --git a/tests/tests/regressions/.gh-533.rto/default.4.1.txt b/tests/tests/regressions/.gh-533.rto/default.4.1.txt new file mode 100644 index 0000000000..1bbe45a65c --- /dev/null +++ b/tests/tests/regressions/.gh-533.rto/default.4.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=4 --ms_c++20 --microsoft_version 1950 Test_name.c diff --git a/tests/tests/regressions/gh-533.sft.cpp b/tests/tests/regressions/gh-533.sft.cpp new file mode 100644 index 0000000000..ca88b76284 --- /dev/null +++ b/tests/tests/regressions/gh-533.sft.cpp @@ -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 struct S +{ + static constexpr bool c = true; + S(E...) requires c {} +}; +template using A = S; +A a{1};