diff --git a/README.md b/README.md index e6f53fff9f..8b10e26bd0 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ Finally, here is a roadmap diagram I made in 2016 that is still recognizably a r ![image](https://user-images.githubusercontent.com/1801526/189503047-0b0a4f0f-c5e7-42b2-a17d-37d80bef3970.png) -I haven't updated this roadmap diagram since 2016, but it shows many of the talks and papers that have come since then from this work, and it's still a pretty up-to-date roadmap of the major parts of Cpp2. As of this writing, cppfront implements much of the top part of this roadmap, and I plan for more to follow. +I haven't updated this roadmap diagram since 2016, but it shows many of the talks and papers that have come since then from this work, and it's still a pretty up-to-date roadmap of the major parts of Cpp2. As of spring 2023, cppfront implements most of this roadmap. I hope you enjoy reading about this personal experiment, and I hope that it might at least start a conversation about what could be possible _**within C++**_'s own evolution to make C++ 10x simpler, safer, and more toolable. diff --git a/include/cpp2util.h b/include/cpp2util.h index ca849b0a71..4e2323e236 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -201,6 +201,7 @@ #include #include #include + #include #include #include #include @@ -216,6 +217,7 @@ #include #include #include + #include #ifndef CPP2_NO_EXCEPTIONS #include @@ -324,8 +326,8 @@ class contract_group { using handler = void (*)(CPP2_MESSAGE_PARAM msg CPP2_SOURCE_LOCATION_PARAM); constexpr contract_group (handler h = {}) : reporter(h) { } - constexpr auto set_handler(handler h) -> handler; - constexpr auto get_handler() const -> handler { return reporter; } + constexpr auto set_handler(handler h); + constexpr auto get_handler() const -> handler { return reporter; } constexpr auto expects (bool b, CPP2_MESSAGE_PARAM msg = "" CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> void { if (!b) reporter(msg CPP2_SOURCE_LOCATION_ARG); } private: @@ -373,11 +375,9 @@ auto inline Testing = contract_group( } ); -constexpr auto contract_group::set_handler(handler h) -> handler { +constexpr auto contract_group::set_handler(handler h) { Default.expects(h); - auto old = reporter; reporter = h; - return old; } @@ -681,19 +681,37 @@ class out { // //----------------------------------------------------------------------- // -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang_major__) #define CPP2_FORCE_INLINE __forceinline #define CPP2_FORCE_INLINE_LAMBDA [[msvc::forceinline]] + #define CPP2_LAMBDA_NO_DISCARD #else #define CPP2_FORCE_INLINE __attribute__((always_inline)) #define CPP2_FORCE_INLINE_LAMBDA __attribute__((always_inline)) + + #if defined(__clang_major__) + // Also check __cplusplus, only to satisfy Clang -pedantic-errors + #if __cplusplus >= 202302L && (__clang_major__ > 13 || (__clang_major__ == 13 && __clang_minor__ >= 2)) + #define CPP2_LAMBDA_NO_DISCARD [[nodiscard]] + #else + #define CPP2_LAMBDA_NO_DISCARD + #endif + #elif defined(__GNUC__) + #if __GNUC__ >= 9 + #define CPP2_LAMBDA_NO_DISCARD [[nodiscard]] + #else + #define CPP2_LAMBDA_NO_DISCARD + #endif + #else + #define CPP2_LAMBDA_NO_DISCARD + #endif #endif // Note: [&] is because a nested UFCS might be viewed as trying to capture 'this' #define CPP2_UFCS(FUNCNAME,PARAM1,...) \ -[&](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ +[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); }) { \ return CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \ } else { \ @@ -702,7 +720,7 @@ class out { }(PARAM1, __VA_ARGS__) #define CPP2_UFCS_0(FUNCNAME,PARAM1) \ -[&](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ +[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \ return CPP2_FORWARD(obj).FUNCNAME(); \ } else { \ @@ -713,7 +731,7 @@ class out { #define CPP2_UFCS_REMPARENS(...) __VA_ARGS__ #define CPP2_UFCS_TEMPLATE(FUNCNAME,TEMPARGS,PARAM1,...) \ -[&](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ +[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); }) { \ return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); \ } else { \ @@ -722,7 +740,7 @@ class out { }(PARAM1, __VA_ARGS__) #define CPP2_UFCS_TEMPLATE_0(FUNCNAME,TEMPARGS,PARAM1) \ -[&](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ +[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \ return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \ } else { \ @@ -734,7 +752,7 @@ class out { // But for non-local lambdas [&] is not allowed #define CPP2_UFCS_NONLOCAL(FUNCNAME,PARAM1,...) \ -[](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ +[] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); }) { \ return CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \ } else { \ @@ -743,7 +761,7 @@ class out { }(PARAM1, __VA_ARGS__) #define CPP2_UFCS_0_NONLOCAL(FUNCNAME,PARAM1) \ -[](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ +[] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \ return CPP2_FORWARD(obj).FUNCNAME(); \ } else { \ @@ -752,7 +770,7 @@ class out { }(PARAM1) #define CPP2_UFCS_TEMPLATE_NONLOCAL(FUNCNAME,TEMPARGS,PARAM1,...) \ -[](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ +[] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); }) { \ return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); \ } else { \ @@ -761,7 +779,7 @@ class out { }(PARAM1, __VA_ARGS__) #define CPP2_UFCS_TEMPLATE_0_NONLOCAL(FUNCNAME,TEMPARGS,PARAM1) \ -[](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ +[] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \ if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \ return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \ } else { \ @@ -1334,38 +1352,37 @@ constexpr auto as( X const& x ) -> decltype(auto) //----------------------------------------------------------------------- // -// A variation of GSL's final_action_success and finally to run only on success -// (based on a PR I contributed to Microsoft GSL) +// A variation of GSL's final_action_success / finally // -// final_action_success ensures something is run at the end of a scope -// if no exception is thrown +// finally ensures something is run at the end of a scope always // -// finally_success is a convenience function to make a final_action_success_success +// finally_success ensures something is run at the end of a scope +// if no exception is thrown // //----------------------------------------------------------------------- // template -class final_action_success +class finally_success { public: - explicit final_action_success(const F& ff) noexcept : f{ff} { } - explicit final_action_success(F&& ff) noexcept : f{std::move(ff)} { } + explicit finally_success(const F& ff) noexcept : f{ff} { } + explicit finally_success(F&& ff) noexcept : f{std::move(ff)} { } - ~final_action_success() noexcept + ~finally_success() noexcept { if (invoke && ecount == std::uncaught_exceptions()) { f(); } } - final_action_success(final_action_success&& that) noexcept + finally_success(finally_success&& that) noexcept : f(std::move(that.f)), invoke(std::exchange(that.invoke, false)) { } - final_action_success(final_action_success const&) = delete; - void operator= (final_action_success const&) = delete; - void operator= (final_action_success&&) = delete; + finally_success(finally_success const&) = delete; + void operator= (finally_success const&) = delete; + void operator= (finally_success&&) = delete; private: F f; @@ -1373,43 +1390,29 @@ class final_action_success bool invoke = true; }; -[[nodiscard]] auto finally_success(auto&& f) noexcept -{ - return final_action_success{CPP2_FORWARD(f)}; -} - - -// -// Same, but clean up also on exceptional paths -// template -class final_action +class finally { public: - explicit final_action(const F& ff) noexcept : f{ff} { } - explicit final_action(F&& ff) noexcept : f{std::move(ff)} { } + explicit finally(const F& ff) noexcept : f{ff} { } + explicit finally(F&& ff) noexcept : f{std::move(ff)} { } - ~final_action() noexcept { f(); } + ~finally() noexcept { f(); } - final_action(final_action&& that) noexcept + finally(finally&& that) noexcept : f(std::move(that.f)), invoke(std::exchange(that.invoke, false)) { } - final_action (final_action const&) = delete; - void operator=(final_action const&) = delete; - void operator=(final_action&&) = delete; + finally (finally const&) = delete; + void operator=(finally const&) = delete; + void operator=(finally&&) = delete; private: F f; bool invoke = true; }; -[[nodiscard]] auto finally(auto&& f) noexcept -{ - return final_action{CPP2_FORWARD(f)}; -} - //----------------------------------------------------------------------- // diff --git a/regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2 b/regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2 index 1641462471..e2513804c5 100644 --- a/regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2 +++ b/regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2 @@ -20,5 +20,5 @@ insert_at: (where: int, val: int) [[pre: 0 <= where && where <= vec.ssize()]] [[post: vec.ssize() == vec.ssize()$ + 1]] = { - vec.insert( vec.begin()+where, val ); + _ = vec.insert( vec.begin()+where, val ); } diff --git a/regression-tests/pure2-bugfix-for-optional-template-argument-list.cpp2 b/regression-tests/pure2-bugfix-for-optional-template-argument-list.cpp2 new file mode 100644 index 0000000000..d6fad5067c --- /dev/null +++ b/regression-tests/pure2-bugfix-for-optional-template-argument-list.cpp2 @@ -0,0 +1,2 @@ +plus: const std::plus<> = (); +main: () -> int = std::plus<>()(0, 0); diff --git a/regression-tests/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2 b/regression-tests/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2 new file mode 100644 index 0000000000..242bee3f51 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2 @@ -0,0 +1,2 @@ +f: () requires std::regular = g(T()); +main: () = { } diff --git a/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2 b/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2 index e71c0e2f6b..fb16dd74a0 100644 --- a/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2 +++ b/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2 @@ -8,7 +8,7 @@ main: () -> int = { test_generic(a, "any"); test_generic(o, "optional"); - v.emplace<0>(1); + _ = v.emplace<0>(1); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/pure2-stdio-with-raii.cpp2 b/regression-tests/pure2-stdio-with-raii.cpp2 index 104943c9f6..59d5d56d6b 100644 --- a/regression-tests/pure2-stdio-with-raii.cpp2 +++ b/regression-tests/pure2-stdio-with-raii.cpp2 @@ -4,5 +4,5 @@ main: () -> int = { s: std::string = "Freddy"; myfile := cpp2::fopen("xyzzy", "w"); - myfile.fprintf( "Hello %s with UFCS!", s.c_str() ); + _ = myfile.fprintf( "Hello %s with UFCS!", s.c_str() ); } diff --git a/regression-tests/pure2-stdio.cpp2 b/regression-tests/pure2-stdio.cpp2 index 070c4140b1..5e30fb78f2 100644 --- a/regression-tests/pure2-stdio.cpp2 +++ b/regression-tests/pure2-stdio.cpp2 @@ -4,7 +4,7 @@ main: () -> int = { s: std::string = "Fred"; myfile := fopen("xyzzy", "w"); - myfile.fprintf( "Hello %s with UFCS!", s.c_str() ); - myfile.fclose(); + _ = myfile.fprintf( "Hello %s with UFCS!", s.c_str() ); + _ = myfile.fclose(); } diff --git a/regression-tests/pure2-type-safety-1.cpp2 b/regression-tests/pure2-type-safety-1.cpp2 index a102c34dcd..049c9075d5 100644 --- a/regression-tests/pure2-type-safety-1.cpp2 +++ b/regression-tests/pure2-type-safety-1.cpp2 @@ -12,7 +12,7 @@ main: () -> int = std::cout << "\n"; - v.emplace<1>(1); + _ = v.emplace<1>(1); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2 b/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2 index a843ca4fc5..837e2c8242 100644 --- a/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2 +++ b/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2 @@ -8,7 +8,7 @@ main: () -> int = { test_generic(a, "any"); test_generic(o, "optional"); - v.emplace<2>(1); + _ = v.emplace<2>(1); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/pure2-types-order-independence-and-nesting.cpp2 b/regression-tests/pure2-types-order-independence-and-nesting.cpp2 index 57e5a9679c..9f150985b7 100644 --- a/regression-tests/pure2-types-order-independence-and-nesting.cpp2 +++ b/regression-tests/pure2-types-order-independence-and-nesting.cpp2 @@ -34,7 +34,7 @@ X: type = { // X::exx member function description here exx: (this, count: int) = { // Exercise '_' anonymous objects too while we're at it - _ := finally( :()= std::cout << "leaving call to 'why((count)$)'\n"; ); + _: finally = :()= std::cout << "leaving call to 'why((count)$)'\n"; if count < 5 { py*.why( count+1 ); // use Y object from X } diff --git a/regression-tests/pure2-ufcs-member-access-and-chaining.cpp2 b/regression-tests/pure2-ufcs-member-access-and-chaining.cpp2 index d8c8230a7d..68ed760c2b 100644 --- a/regression-tests/pure2-ufcs-member-access-and-chaining.cpp2 +++ b/regression-tests/pure2-ufcs-member-access-and-chaining.cpp2 @@ -1,24 +1,28 @@ main: () -> int = { i := 42; - i.ufcs(); + _ = i.ufcs(); j := fun(); - j.i.ufcs(); + _ = j.i.ufcs(); - fun().i.ufcs(); + _ = fun().i.ufcs(); k := fun().i; - k.ufcs(); + _ = k.ufcs(); - get_i(j).ufcs(); + _ = get_i(j).ufcs(); - get_i(fun()).ufcs(); + _ = get_i(fun()).ufcs(); res := (42).ufcs(); - (j.i).ufcs(); + _ = (j.i).ufcs(); + + 42.no_return(); } +no_return: (x: int) = { } + ufcs: (i:int) -> int = { return i+2; } diff --git a/regression-tests/test-results/apple-clang-14/pure2-cpp1-multitoken-fundamental-types.cpp.execution b/regression-tests/test-results/apple-clang-14/pure2-cpp1-multitoken-fundamental-types.cpp.execution deleted file mode 100644 index a7a4bc3792..0000000000 --- a/regression-tests/test-results/apple-clang-14/pure2-cpp1-multitoken-fundamental-types.cpp.execution +++ /dev/null @@ -1 +0,0 @@ --50.250000 diff --git a/regression-tests/test-results/apple-clang-14/pure2-inspect-values.cpp.execution b/regression-tests/test-results/apple-clang-14/pure2-inspect-values.cpp.execution deleted file mode 100644 index 33ff0d4578..0000000000 --- a/regression-tests/test-results/apple-clang-14/pure2-inspect-values.cpp.execution +++ /dev/null @@ -1,10 +0,0 @@ -(no match) -rev dodgson -(no match) -the answer -zero -plugh -zero -integer -42 -xyzzy -(no match) diff --git a/regression-tests/test-results/gcc-10/mixed-allcpp1-hello.cpp.output b/regression-tests/test-results/clang-12/pure2-bugfix-for-optional-template-argument-list.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-allcpp1-hello.cpp.output rename to regression-tests/test-results/clang-12/pure2-bugfix-for-optional-template-argument-list.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-as-for-variant-20-types.cpp.output b/regression-tests/test-results/clang-12/pure2-bugfix-for-optional-template-argument-list.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-as-for-variant-20-types.cpp.output rename to regression-tests/test-results/clang-12/pure2-bugfix-for-optional-template-argument-list.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-bounds-check.cpp.output b/regression-tests/test-results/clang-12/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-bounds-check.cpp.output rename to regression-tests/test-results/clang-12/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-bounds-safety-with-assert-2.cpp.output b/regression-tests/test-results/clang-12/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-bounds-safety-with-assert-2.cpp.output rename to regression-tests/test-results/clang-12/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.output diff --git a/regression-tests/test-results/clang-12/pure2-cpp1-multitoken-fundamental-types.cpp.execution b/regression-tests/test-results/clang-12/pure2-cpp1-multitoken-fundamental-types.cpp.execution deleted file mode 100644 index a7a4bc3792..0000000000 --- a/regression-tests/test-results/clang-12/pure2-cpp1-multitoken-fundamental-types.cpp.execution +++ /dev/null @@ -1 +0,0 @@ --50.250000 diff --git a/regression-tests/test-results/clang-12/pure2-inspect-values.cpp.execution b/regression-tests/test-results/clang-12/pure2-inspect-values.cpp.execution deleted file mode 100644 index 33ff0d4578..0000000000 --- a/regression-tests/test-results/clang-12/pure2-inspect-values.cpp.execution +++ /dev/null @@ -1,10 +0,0 @@ -(no match) -rev dodgson -(no match) -the answer -zero -plugh -zero -integer -42 -xyzzy -(no match) diff --git a/regression-tests/test-results/gcc-10/gcc-version.output b/regression-tests/test-results/gcc-10/gcc-version.output deleted file mode 100644 index b71d86e8cf..0000000000 --- a/regression-tests/test-results/gcc-10/gcc-version.output +++ /dev/null @@ -1,5 +0,0 @@ -g++-10 (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0 -Copyright (C) 2020 Free Software Foundation, Inc. -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - diff --git a/regression-tests/test-results/gcc-10/pure2-cpp1-multitoken-fundamental-types.cpp.execution b/regression-tests/test-results/gcc-10/pure2-cpp1-multitoken-fundamental-types.cpp.execution deleted file mode 100644 index a7a4bc3792..0000000000 --- a/regression-tests/test-results/gcc-10/pure2-cpp1-multitoken-fundamental-types.cpp.execution +++ /dev/null @@ -1 +0,0 @@ --50.250000 diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-values.cpp.execution b/regression-tests/test-results/gcc-10/pure2-inspect-values.cpp.execution deleted file mode 100644 index 582ab3ce5d..0000000000 --- a/regression-tests/test-results/gcc-10/pure2-inspect-values.cpp.execution +++ /dev/null @@ -1,10 +0,0 @@ -zero -rev dodgson -(no match) -the answer -zero -plugh -zero -integer -42 -xyzzy -(no match) diff --git a/regression-tests/test-results/gcc-10/xyzzy b/regression-tests/test-results/gcc-10/xyzzy deleted file mode 100644 index 805bcb8538..0000000000 --- a/regression-tests/test-results/gcc-10/xyzzy +++ /dev/null @@ -1 +0,0 @@ -Hello Fred with UFCS! \ No newline at end of file diff --git a/regression-tests/test-results/gcc-13/gcc-version.output b/regression-tests/test-results/gcc-13/gcc-version.output index 7bbac4c854..c6847fe85f 100644 --- a/regression-tests/test-results/gcc-13/gcc-version.output +++ b/regression-tests/test-results/gcc-13/gcc-version.output @@ -1,4 +1,4 @@ -c++ (GCC) 13.1.1 20230429 +gcc (GCC) 13.1.1 20230614 (Red Hat 13.1.1-4) Copyright (C) 2023 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/regression-tests/test-results/gcc-10/mixed-allcpp1-hello.cpp.execution b/regression-tests/test-results/gcc-13/mixed-allcpp1-hello.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-allcpp1-hello.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-allcpp1-hello.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-bounds-safety-with-assert.cpp.output b/regression-tests/test-results/gcc-13/mixed-allcpp1-hello.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-bounds-safety-with-assert.cpp.output rename to regression-tests/test-results/gcc-13/mixed-allcpp1-hello.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-as-for-variant-20-types.cpp.execution b/regression-tests/test-results/gcc-13/mixed-as-for-variant-20-types.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-as-for-variant-20-types.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-as-for-variant-20-types.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-captures-in-expressions-and-postconditions.cpp.output b/regression-tests/test-results/gcc-13/mixed-as-for-variant-20-types.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-captures-in-expressions-and-postconditions.cpp.output rename to regression-tests/test-results/gcc-13/mixed-as-for-variant-20-types.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-bounds-check.cpp.execution b/regression-tests/test-results/gcc-13/mixed-bounds-check.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-bounds-check.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-bounds-check.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-fixed-type-aliases.cpp.output b/regression-tests/test-results/gcc-13/mixed-bounds-check.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-fixed-type-aliases.cpp.output rename to regression-tests/test-results/gcc-13/mixed-bounds-check.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-bounds-safety-with-assert-2.cpp.execution b/regression-tests/test-results/gcc-13/mixed-bounds-safety-with-assert-2.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-bounds-safety-with-assert-2.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-bounds-safety-with-assert-2.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-float-literals.cpp.output b/regression-tests/test-results/gcc-13/mixed-bounds-safety-with-assert-2.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-float-literals.cpp.output rename to regression-tests/test-results/gcc-13/mixed-bounds-safety-with-assert-2.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-bounds-safety-with-assert.cpp.execution b/regression-tests/test-results/gcc-13/mixed-bounds-safety-with-assert.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-bounds-safety-with-assert.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-bounds-safety-with-assert.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-forwarding.cpp.output b/regression-tests/test-results/gcc-13/mixed-bounds-safety-with-assert.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-forwarding.cpp.output rename to regression-tests/test-results/gcc-13/mixed-bounds-safety-with-assert.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-captures-in-expressions-and-postconditions.cpp.execution b/regression-tests/test-results/gcc-13/mixed-captures-in-expressions-and-postconditions.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-captures-in-expressions-and-postconditions.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-captures-in-expressions-and-postconditions.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-and-std-for-each.cpp.output b/regression-tests/test-results/gcc-13/mixed-captures-in-expressions-and-postconditions.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-and-std-for-each.cpp.output rename to regression-tests/test-results/gcc-13/mixed-captures-in-expressions-and-postconditions.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-fixed-type-aliases.cpp.execution b/regression-tests/test-results/gcc-13/mixed-fixed-type-aliases.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-fixed-type-aliases.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-fixed-type-aliases.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp.output b/regression-tests/test-results/gcc-13/mixed-fixed-type-aliases.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp.output rename to regression-tests/test-results/gcc-13/mixed-fixed-type-aliases.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-float-literals.cpp.execution b/regression-tests/test-results/gcc-13/mixed-float-literals.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-float-literals.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-float-literals.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-and-std-ranges-for-each.cpp.output b/regression-tests/test-results/gcc-13/mixed-float-literals.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-and-std-ranges-for-each.cpp.output rename to regression-tests/test-results/gcc-13/mixed-float-literals.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-forwarding.cpp.execution b/regression-tests/test-results/gcc-13/mixed-forwarding.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-forwarding.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-forwarding.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-with-pointer-capture.cpp.output b/regression-tests/test-results/gcc-13/mixed-forwarding.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-with-pointer-capture.cpp.output rename to regression-tests/test-results/gcc-13/mixed-forwarding.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-and-std-for-each.cpp.execution b/regression-tests/test-results/gcc-13/mixed-function-expression-and-std-for-each.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-and-std-for-each.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-function-expression-and-std-for-each.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-with-repeated-capture.cpp.output b/regression-tests/test-results/gcc-13/mixed-function-expression-and-std-for-each.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-with-repeated-capture.cpp.output rename to regression-tests/test-results/gcc-13/mixed-function-expression-and-std-for-each.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp.execution b/regression-tests/test-results/gcc-13/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-hello.cpp.output b/regression-tests/test-results/gcc-13/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-hello.cpp.output rename to regression-tests/test-results/gcc-13/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-and-std-ranges-for-each.cpp.execution b/regression-tests/test-results/gcc-13/mixed-function-expression-and-std-ranges-for-each.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-and-std-ranges-for-each.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-function-expression-and-std-ranges-for-each.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-initialization-safety-3-contract-violation.cpp.output b/regression-tests/test-results/gcc-13/mixed-function-expression-and-std-ranges-for-each.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-initialization-safety-3-contract-violation.cpp.output rename to regression-tests/test-results/gcc-13/mixed-function-expression-and-std-ranges-for-each.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-with-pointer-capture.cpp.execution b/regression-tests/test-results/gcc-13/mixed-function-expression-with-pointer-capture.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-with-pointer-capture.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-function-expression-with-pointer-capture.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-initialization-safety-3.cpp.output b/regression-tests/test-results/gcc-13/mixed-function-expression-with-pointer-capture.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-initialization-safety-3.cpp.output rename to regression-tests/test-results/gcc-13/mixed-function-expression-with-pointer-capture.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-function-expression-with-repeated-capture.cpp.execution b/regression-tests/test-results/gcc-13/mixed-function-expression-with-repeated-capture.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-function-expression-with-repeated-capture.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-function-expression-with-repeated-capture.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-inspect-templates.cpp.output b/regression-tests/test-results/gcc-13/mixed-function-expression-with-repeated-capture.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-inspect-templates.cpp.output rename to regression-tests/test-results/gcc-13/mixed-function-expression-with-repeated-capture.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-hello.cpp.execution b/regression-tests/test-results/gcc-13/mixed-hello.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-hello.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-hello.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-inspect-values-2.cpp.output b/regression-tests/test-results/gcc-13/mixed-hello.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-inspect-values-2.cpp.output rename to regression-tests/test-results/gcc-13/mixed-hello.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-initialization-safety-3-contract-violation.cpp.execution b/regression-tests/test-results/gcc-13/mixed-initialization-safety-3-contract-violation.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-initialization-safety-3-contract-violation.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-initialization-safety-3-contract-violation.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-inspect-values.cpp.output b/regression-tests/test-results/gcc-13/mixed-initialization-safety-3-contract-violation.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-inspect-values.cpp.output rename to regression-tests/test-results/gcc-13/mixed-initialization-safety-3-contract-violation.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-initialization-safety-3.cpp.execution b/regression-tests/test-results/gcc-13/mixed-initialization-safety-3.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-initialization-safety-3.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-initialization-safety-3.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-inspect-with-typeof-of-template-arg-list.cpp.execution b/regression-tests/test-results/gcc-13/mixed-initialization-safety-3.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-inspect-with-typeof-of-template-arg-list.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-initialization-safety-3.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-inspect-templates.cpp.execution b/regression-tests/test-results/gcc-13/mixed-inspect-templates.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-inspect-templates.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-inspect-templates.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-inspect-with-typeof-of-template-arg-list.cpp.output b/regression-tests/test-results/gcc-13/mixed-inspect-templates.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-inspect-with-typeof-of-template-arg-list.cpp.output rename to regression-tests/test-results/gcc-13/mixed-inspect-templates.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-inspect-values-2.cpp.execution b/regression-tests/test-results/gcc-13/mixed-inspect-values-2.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-inspect-values-2.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-inspect-values-2.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-intro-example-three-loops.cpp.output b/regression-tests/test-results/gcc-13/mixed-inspect-values-2.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-intro-example-three-loops.cpp.output rename to regression-tests/test-results/gcc-13/mixed-inspect-values-2.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-inspect-values.cpp.execution b/regression-tests/test-results/gcc-13/mixed-inspect-values.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-inspect-values.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-inspect-values.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-intro-for-with-counter-include-last.cpp.output b/regression-tests/test-results/gcc-13/mixed-inspect-values.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-intro-for-with-counter-include-last.cpp.output rename to regression-tests/test-results/gcc-13/mixed-inspect-values.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-lifetime-safety-and-null-contracts.cpp.output b/regression-tests/test-results/gcc-13/mixed-inspect-with-typeof-of-template-arg-list.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-lifetime-safety-and-null-contracts.cpp.output rename to regression-tests/test-results/gcc-13/mixed-inspect-with-typeof-of-template-arg-list.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-lifetime-safety-pointer-init-4.cpp.output b/regression-tests/test-results/gcc-13/mixed-inspect-with-typeof-of-template-arg-list.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-lifetime-safety-pointer-init-4.cpp.output rename to regression-tests/test-results/gcc-13/mixed-inspect-with-typeof-of-template-arg-list.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-intro-example-three-loops.cpp.execution b/regression-tests/test-results/gcc-13/mixed-intro-example-three-loops.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-intro-example-three-loops.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-intro-example-three-loops.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-multiple-return-values.cpp.output b/regression-tests/test-results/gcc-13/mixed-intro-example-three-loops.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-multiple-return-values.cpp.output rename to regression-tests/test-results/gcc-13/mixed-intro-example-three-loops.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-intro-for-with-counter-include-last.cpp.execution b/regression-tests/test-results/gcc-13/mixed-intro-for-with-counter-include-last.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-intro-for-with-counter-include-last.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-intro-for-with-counter-include-last.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-out-destruction.cpp.output b/regression-tests/test-results/gcc-13/mixed-intro-for-with-counter-include-last.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-out-destruction.cpp.output rename to regression-tests/test-results/gcc-13/mixed-intro-for-with-counter-include-last.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-lifetime-safety-and-null-contracts.cpp.execution b/regression-tests/test-results/gcc-13/mixed-lifetime-safety-and-null-contracts.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-lifetime-safety-and-null-contracts.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-lifetime-safety-and-null-contracts.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-parameter-passing-generic-out.cpp.output b/regression-tests/test-results/gcc-13/mixed-lifetime-safety-and-null-contracts.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-parameter-passing-generic-out.cpp.output rename to regression-tests/test-results/gcc-13/mixed-lifetime-safety-and-null-contracts.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-lifetime-safety-pointer-init-4.cpp.execution b/regression-tests/test-results/gcc-13/mixed-lifetime-safety-pointer-init-4.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-lifetime-safety-pointer-init-4.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-lifetime-safety-pointer-init-4.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-parameter-passing-with-forward.cpp.execution b/regression-tests/test-results/gcc-13/mixed-lifetime-safety-pointer-init-4.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-parameter-passing-with-forward.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-lifetime-safety-pointer-init-4.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-multiple-return-values.cpp.execution b/regression-tests/test-results/gcc-13/mixed-multiple-return-values.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-multiple-return-values.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-multiple-return-values.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-parameter-passing-with-forward.cpp.output b/regression-tests/test-results/gcc-13/mixed-multiple-return-values.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-parameter-passing-with-forward.cpp.output rename to regression-tests/test-results/gcc-13/mixed-multiple-return-values.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-out-destruction.cpp.execution b/regression-tests/test-results/gcc-13/mixed-out-destruction.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-out-destruction.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-out-destruction.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-parameter-passing.cpp.execution b/regression-tests/test-results/gcc-13/mixed-out-destruction.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-parameter-passing.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-out-destruction.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-parameter-passing-generic-out.cpp.execution b/regression-tests/test-results/gcc-13/mixed-parameter-passing-generic-out.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-parameter-passing-generic-out.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-parameter-passing-generic-out.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-parameter-passing.cpp.output b/regression-tests/test-results/gcc-13/mixed-parameter-passing-generic-out.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-parameter-passing.cpp.output rename to regression-tests/test-results/gcc-13/mixed-parameter-passing-generic-out.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-postexpression-with-capture.cpp.execution b/regression-tests/test-results/gcc-13/mixed-parameter-passing-with-forward.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-postexpression-with-capture.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-parameter-passing-with-forward.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-postexpression-with-capture.cpp.output b/regression-tests/test-results/gcc-13/mixed-parameter-passing-with-forward.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-postexpression-with-capture.cpp.output rename to regression-tests/test-results/gcc-13/mixed-parameter-passing-with-forward.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-postfix-expression-custom-formatting.cpp.execution b/regression-tests/test-results/gcc-13/mixed-parameter-passing.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-postfix-expression-custom-formatting.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-parameter-passing.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-postfix-expression-custom-formatting.cpp.output b/regression-tests/test-results/gcc-13/mixed-parameter-passing.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-postfix-expression-custom-formatting.cpp.output rename to regression-tests/test-results/gcc-13/mixed-parameter-passing.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-string-interpolation.cpp.output b/regression-tests/test-results/gcc-13/mixed-postexpression-with-capture.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-string-interpolation.cpp.output rename to regression-tests/test-results/gcc-13/mixed-postexpression-with-capture.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-test-parens.cpp.output b/regression-tests/test-results/gcc-13/mixed-postexpression-with-capture.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-test-parens.cpp.output rename to regression-tests/test-results/gcc-13/mixed-postexpression-with-capture.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-type-safety-1.cpp.output b/regression-tests/test-results/gcc-13/mixed-postfix-expression-custom-formatting.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-type-safety-1.cpp.output rename to regression-tests/test-results/gcc-13/mixed-postfix-expression-custom-formatting.cpp.execution diff --git a/regression-tests/test-results/gcc-10/mixed-ufcs-multiple-template-arguments.cpp.output b/regression-tests/test-results/gcc-13/mixed-postfix-expression-custom-formatting.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-ufcs-multiple-template-arguments.cpp.output rename to regression-tests/test-results/gcc-13/mixed-postfix-expression-custom-formatting.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-string-interpolation.cpp.execution b/regression-tests/test-results/gcc-13/mixed-string-interpolation.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-string-interpolation.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-string-interpolation.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-bounds-safety-span.cpp.output b/regression-tests/test-results/gcc-13/mixed-string-interpolation.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-bounds-safety-span.cpp.output rename to regression-tests/test-results/gcc-13/mixed-string-interpolation.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-test-parens.cpp.execution b/regression-tests/test-results/gcc-13/mixed-test-parens.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-test-parens.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-test-parens.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-break-continue.cpp.output b/regression-tests/test-results/gcc-13/mixed-test-parens.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-break-continue.cpp.output rename to regression-tests/test-results/gcc-13/mixed-test-parens.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-type-safety-1.cpp.execution b/regression-tests/test-results/gcc-13/mixed-type-safety-1.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-type-safety-1.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-type-safety-1.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-name-lookup-and-value-decoration.cpp.execution b/regression-tests/test-results/gcc-13/mixed-type-safety-1.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-bugfix-for-name-lookup-and-value-decoration.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-type-safety-1.cpp.output diff --git a/regression-tests/test-results/gcc-10/mixed-ufcs-multiple-template-arguments.cpp.execution b/regression-tests/test-results/gcc-13/mixed-ufcs-multiple-template-arguments.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/mixed-ufcs-multiple-template-arguments.cpp.execution rename to regression-tests/test-results/gcc-13/mixed-ufcs-multiple-template-arguments.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-bugfix-for-name-lookup-and-value-decoration.cpp.output b/regression-tests/test-results/gcc-13/mixed-ufcs-multiple-template-arguments.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-bugfix-for-name-lookup-and-value-decoration.cpp.output rename to regression-tests/test-results/gcc-13/mixed-ufcs-multiple-template-arguments.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-bounds-safety-span.cpp.execution b/regression-tests/test-results/gcc-13/pure2-bounds-safety-span.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-bounds-safety-span.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-bounds-safety-span.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-chained-comparisons.cpp.output b/regression-tests/test-results/gcc-13/pure2-bounds-safety-span.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-chained-comparisons.cpp.output rename to regression-tests/test-results/gcc-13/pure2-bounds-safety-span.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-break-continue.cpp.execution b/regression-tests/test-results/gcc-13/pure2-break-continue.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-break-continue.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-break-continue.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-defaulted-comparisons-and-final-types.cpp.output b/regression-tests/test-results/gcc-13/pure2-break-continue.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-defaulted-comparisons-and-final-types.cpp.output rename to regression-tests/test-results/gcc-13/pure2-break-continue.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-forward-return.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-name-lookup-and-value-decoration.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-forward-return.cpp.output rename to regression-tests/test-results/gcc-13/pure2-bugfix-for-name-lookup-and-value-decoration.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-function-multiple-forward-arguments.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-name-lookup-and-value-decoration.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-function-multiple-forward-arguments.cpp.output rename to regression-tests/test-results/gcc-13/pure2-bugfix-for-name-lookup-and-value-decoration.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-hello.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-optional-template-argument-list.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-hello.cpp.output rename to regression-tests/test-results/gcc-13/pure2-bugfix-for-optional-template-argument-list.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-initialization-safety-with-else-if.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-optional-template-argument-list.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-initialization-safety-with-else-if.cpp.output rename to regression-tests/test-results/gcc-13/pure2-bugfix-for-optional-template-argument-list.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-expression-in-generic-function-multiple-types.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-inspect-expression-in-generic-function-multiple-types.cpp.output rename to regression-tests/test-results/gcc-13/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-expression-with-as-in-generic-function.cpp.output b/regression-tests/test-results/gcc-13/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-inspect-expression-with-as-in-generic-function.cpp.output rename to regression-tests/test-results/gcc-13/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-chained-comparisons.cpp.execution b/regression-tests/test-results/gcc-13/pure2-chained-comparisons.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-chained-comparisons.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-chained-comparisons.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-fallback-with-variant-any-optional.cpp.output b/regression-tests/test-results/gcc-13/pure2-chained-comparisons.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-inspect-fallback-with-variant-any-optional.cpp.output rename to regression-tests/test-results/gcc-13/pure2-chained-comparisons.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-defaulted-comparisons-and-final-types.cpp.execution b/regression-tests/test-results/gcc-13/pure2-defaulted-comparisons-and-final-types.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-defaulted-comparisons-and-final-types.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-defaulted-comparisons-and-final-types.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp.output b/regression-tests/test-results/gcc-13/pure2-defaulted-comparisons-and-final-types.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp.output rename to regression-tests/test-results/gcc-13/pure2-defaulted-comparisons-and-final-types.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-forward-return.cpp.execution b/regression-tests/test-results/gcc-13/pure2-forward-return.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-forward-return.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-forward-return.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-interpolation.cpp.output b/regression-tests/test-results/gcc-13/pure2-forward-return.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-interpolation.cpp.output rename to regression-tests/test-results/gcc-13/pure2-forward-return.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-function-multiple-forward-arguments.cpp.execution b/regression-tests/test-results/gcc-13/pure2-function-multiple-forward-arguments.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-function-multiple-forward-arguments.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-function-multiple-forward-arguments.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-intro-example-hello-2022.cpp.output b/regression-tests/test-results/gcc-13/pure2-function-multiple-forward-arguments.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-intro-example-hello-2022.cpp.output rename to regression-tests/test-results/gcc-13/pure2-function-multiple-forward-arguments.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-hello.cpp.execution b/regression-tests/test-results/gcc-13/pure2-hello.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-hello.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-hello.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-intro-example-three-loops.cpp.output b/regression-tests/test-results/gcc-13/pure2-hello.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-intro-example-three-loops.cpp.output rename to regression-tests/test-results/gcc-13/pure2-hello.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-initialization-safety-with-else-if.cpp.execution b/regression-tests/test-results/gcc-13/pure2-initialization-safety-with-else-if.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-initialization-safety-with-else-if.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-initialization-safety-with-else-if.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-look-up-parameter-across-unnamed-function.cpp.output b/regression-tests/test-results/gcc-13/pure2-initialization-safety-with-else-if.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-look-up-parameter-across-unnamed-function.cpp.output rename to regression-tests/test-results/gcc-13/pure2-initialization-safety-with-else-if.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-expression-in-generic-function-multiple-types.cpp.execution b/regression-tests/test-results/gcc-13/pure2-inspect-expression-in-generic-function-multiple-types.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-inspect-expression-in-generic-function-multiple-types.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-inspect-expression-in-generic-function-multiple-types.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-main-args.cpp.output b/regression-tests/test-results/gcc-13/pure2-inspect-expression-in-generic-function-multiple-types.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-main-args.cpp.output rename to regression-tests/test-results/gcc-13/pure2-inspect-expression-in-generic-function-multiple-types.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-expression-with-as-in-generic-function.cpp.execution b/regression-tests/test-results/gcc-13/pure2-inspect-expression-with-as-in-generic-function.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-inspect-expression-with-as-in-generic-function.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-inspect-expression-with-as-in-generic-function.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-more-wildcards.cpp.output b/regression-tests/test-results/gcc-13/pure2-inspect-expression-with-as-in-generic-function.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-more-wildcards.cpp.output rename to regression-tests/test-results/gcc-13/pure2-inspect-expression-with-as-in-generic-function.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-fallback-with-variant-any-optional.cpp.execution b/regression-tests/test-results/gcc-13/pure2-inspect-fallback-with-variant-any-optional.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-inspect-fallback-with-variant-any-optional.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-inspect-fallback-with-variant-any-optional.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-raw-string-literal-and-interpolation.cpp.output b/regression-tests/test-results/gcc-13/pure2-inspect-fallback-with-variant-any-optional.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-raw-string-literal-and-interpolation.cpp.output rename to regression-tests/test-results/gcc-13/pure2-inspect-fallback-with-variant-any-optional.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp.execution b/regression-tests/test-results/gcc-13/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-repeated-call.cpp.output b/regression-tests/test-results/gcc-13/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-repeated-call.cpp.output rename to regression-tests/test-results/gcc-13/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-interpolation.cpp.execution b/regression-tests/test-results/gcc-13/pure2-interpolation.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-interpolation.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-interpolation.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-requires-clauses.cpp.output b/regression-tests/test-results/gcc-13/pure2-interpolation.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-requires-clauses.cpp.output rename to regression-tests/test-results/gcc-13/pure2-interpolation.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-intro-example-hello-2022.cpp.execution b/regression-tests/test-results/gcc-13/pure2-intro-example-hello-2022.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-intro-example-hello-2022.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-intro-example-hello-2022.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-statement-scope-parameters.cpp.output b/regression-tests/test-results/gcc-13/pure2-intro-example-hello-2022.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-statement-scope-parameters.cpp.output rename to regression-tests/test-results/gcc-13/pure2-intro-example-hello-2022.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-intro-example-three-loops.cpp.execution b/regression-tests/test-results/gcc-13/pure2-intro-example-three-loops.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-intro-example-three-loops.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-intro-example-three-loops.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-stdio-with-raii.cpp.execution b/regression-tests/test-results/gcc-13/pure2-intro-example-three-loops.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-stdio-with-raii.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-intro-example-three-loops.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-look-up-parameter-across-unnamed-function.cpp.execution b/regression-tests/test-results/gcc-13/pure2-look-up-parameter-across-unnamed-function.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-look-up-parameter-across-unnamed-function.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-look-up-parameter-across-unnamed-function.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-stdio-with-raii.cpp.output b/regression-tests/test-results/gcc-13/pure2-look-up-parameter-across-unnamed-function.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-stdio-with-raii.cpp.output rename to regression-tests/test-results/gcc-13/pure2-look-up-parameter-across-unnamed-function.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-main-args.cpp.execution b/regression-tests/test-results/gcc-13/pure2-main-args.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-main-args.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-main-args.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-stdio.cpp.execution b/regression-tests/test-results/gcc-13/pure2-main-args.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-stdio.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-main-args.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-more-wildcards.cpp.execution b/regression-tests/test-results/gcc-13/pure2-more-wildcards.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-more-wildcards.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-more-wildcards.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-stdio.cpp.output b/regression-tests/test-results/gcc-13/pure2-more-wildcards.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-stdio.cpp.output rename to regression-tests/test-results/gcc-13/pure2-more-wildcards.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-raw-string-literal-and-interpolation.cpp.execution b/regression-tests/test-results/gcc-13/pure2-raw-string-literal-and-interpolation.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-raw-string-literal-and-interpolation.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-raw-string-literal-and-interpolation.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-synthesize-rightshift-and-rightshifteq.cpp.output b/regression-tests/test-results/gcc-13/pure2-raw-string-literal-and-interpolation.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-synthesize-rightshift-and-rightshifteq.cpp.output rename to regression-tests/test-results/gcc-13/pure2-raw-string-literal-and-interpolation.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-repeated-call.cpp.execution b/regression-tests/test-results/gcc-13/pure2-repeated-call.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-repeated-call.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-repeated-call.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-template-parameter-lists.cpp.output b/regression-tests/test-results/gcc-13/pure2-repeated-call.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-template-parameter-lists.cpp.output rename to regression-tests/test-results/gcc-13/pure2-repeated-call.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-requires-clauses.cpp.execution b/regression-tests/test-results/gcc-13/pure2-requires-clauses.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-requires-clauses.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-requires-clauses.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-type-and-namespace-aliases.cpp.output b/regression-tests/test-results/gcc-13/pure2-requires-clauses.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-type-and-namespace-aliases.cpp.output rename to regression-tests/test-results/gcc-13/pure2-requires-clauses.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-statement-scope-parameters.cpp.execution b/regression-tests/test-results/gcc-13/pure2-statement-scope-parameters.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-statement-scope-parameters.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-statement-scope-parameters.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-type-safety-1.cpp.output b/regression-tests/test-results/gcc-13/pure2-statement-scope-parameters.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-type-safety-1.cpp.output rename to regression-tests/test-results/gcc-13/pure2-statement-scope-parameters.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-type-safety-2-with-inspect-expression.cpp.output b/regression-tests/test-results/gcc-13/pure2-stdio-with-raii.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-type-safety-2-with-inspect-expression.cpp.output rename to regression-tests/test-results/gcc-13/pure2-stdio-with-raii.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-basics.cpp.output b/regression-tests/test-results/gcc-13/pure2-stdio-with-raii.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-basics.cpp.output rename to regression-tests/test-results/gcc-13/pure2-stdio-with-raii.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-inheritance.cpp.output b/regression-tests/test-results/gcc-13/pure2-stdio.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-inheritance.cpp.output rename to regression-tests/test-results/gcc-13/pure2-stdio.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-order-independence-and-nesting.cpp.output b/regression-tests/test-results/gcc-13/pure2-stdio.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-order-independence-and-nesting.cpp.output rename to regression-tests/test-results/gcc-13/pure2-stdio.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-synthesize-rightshift-and-rightshifteq.cpp.execution b/regression-tests/test-results/gcc-13/pure2-synthesize-rightshift-and-rightshifteq.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-synthesize-rightshift-and-rightshifteq.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-synthesize-rightshift-and-rightshifteq.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-ordering-via-meta-functions.cpp.output b/regression-tests/test-results/gcc-13/pure2-synthesize-rightshift-and-rightshifteq.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-ordering-via-meta-functions.cpp.output rename to regression-tests/test-results/gcc-13/pure2-synthesize-rightshift-and-rightshifteq.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-template-parameter-lists.cpp.execution b/regression-tests/test-results/gcc-13/pure2-template-parameter-lists.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-template-parameter-lists.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-template-parameter-lists.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-1-provide-everything.cpp.output b/regression-tests/test-results/gcc-13/pure2-template-parameter-lists.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-1-provide-everything.cpp.output rename to regression-tests/test-results/gcc-13/pure2-template-parameter-lists.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-type-and-namespace-aliases.cpp.execution b/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-type-and-namespace-aliases.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp.output b/regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp.output rename to regression-tests/test-results/gcc-13/pure2-type-and-namespace-aliases.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-type-safety-1.cpp.execution b/regression-tests/test-results/gcc-13/pure2-type-safety-1.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-type-safety-1.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-type-safety-1.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp.output b/regression-tests/test-results/gcc-13/pure2-type-safety-1.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp.output rename to regression-tests/test-results/gcc-13/pure2-type-safety-1.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-type-safety-2-with-inspect-expression.cpp.execution b/regression-tests/test-results/gcc-13/pure2-type-safety-2-with-inspect-expression.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-type-safety-2-with-inspect-expression.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-type-safety-2-with-inspect-expression.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp.output b/regression-tests/test-results/gcc-13/pure2-type-safety-2-with-inspect-expression.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp.output rename to regression-tests/test-results/gcc-13/pure2-type-safety-2-with-inspect-expression.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-basics.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-basics.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-basics.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-basics.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-basics.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp.output rename to regression-tests/test-results/gcc-13/pure2-types-basics.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-inheritance.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-inheritance.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-inheritance.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-inheritance.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-that-parameters.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-inheritance.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-that-parameters.cpp.output rename to regression-tests/test-results/gcc-13/pure2-types-inheritance.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-order-independence-and-nesting.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-order-independence-and-nesting.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-order-independence-and-nesting.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-order-independence-and-nesting.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-types-value-types-via-meta-functions.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-order-independence-and-nesting.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-value-types-via-meta-functions.cpp.output rename to regression-tests/test-results/gcc-13/pure2-types-order-independence-and-nesting.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-ordering-via-meta-functions.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-ordering-via-meta-functions.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-ordering-via-meta-functions.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-ordering-via-meta-functions.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-ufcs-member-access-and-chaining.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-ordering-via-meta-functions.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-ufcs-member-access-and-chaining.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-ordering-via-meta-functions.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-1-provide-everything.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-1-provide-everything.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-1-provide-everything.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-smf-and-that-1-provide-everything.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-ufcs-member-access-and-chaining.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-1-provide-everything.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-ufcs-member-access-and-chaining.cpp.output rename to regression-tests/test-results/gcc-13/pure2-types-smf-and-that-1-provide-everything.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-various-string-literals.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-various-string-literals.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-smf-and-that-2-provide-mvconstruct-and-cpassign.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp.execution diff --git a/regression-tests/test-results/gcc-10/pure2-various-string-literals.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp.output similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-various-string-literals.cpp.output rename to regression-tests/test-results/gcc-13/pure2-types-smf-and-that-3-provide-mvconstruct-and-mvassign.cpp.output diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp.execution diff --git a/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-4-provide-cpassign-and-mvassign.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp.execution diff --git a/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-smf-and-that-5-provide-nothing-but-general-case.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-types-that-parameters.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-that-parameters.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-that-parameters.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-that-parameters.cpp.execution diff --git a/regression-tests/test-results/gcc-13/pure2-types-that-parameters.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-that-parameters.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/pure2-types-value-types-via-meta-functions.cpp.execution b/regression-tests/test-results/gcc-13/pure2-types-value-types-via-meta-functions.cpp.execution similarity index 100% rename from regression-tests/test-results/gcc-10/pure2-types-value-types-via-meta-functions.cpp.execution rename to regression-tests/test-results/gcc-13/pure2-types-value-types-via-meta-functions.cpp.execution diff --git a/regression-tests/test-results/gcc-13/pure2-types-value-types-via-meta-functions.cpp.output b/regression-tests/test-results/gcc-13/pure2-types-value-types-via-meta-functions.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-13/pure2-ufcs-member-access-and-chaining.cpp.execution b/regression-tests/test-results/gcc-13/pure2-ufcs-member-access-and-chaining.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-13/pure2-ufcs-member-access-and-chaining.cpp.output b/regression-tests/test-results/gcc-13/pure2-ufcs-member-access-and-chaining.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-13/pure2-various-string-literals.cpp.execution b/regression-tests/test-results/gcc-13/pure2-various-string-literals.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-13/pure2-various-string-literals.cpp.output b/regression-tests/test-results/gcc-13/pure2-various-string-literals.cpp.output new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/gcc-10/run-tests-gcc-10.sh b/regression-tests/test-results/gcc-13/run-tests-gcc-13.sh similarity index 63% rename from regression-tests/test-results/gcc-10/run-tests-gcc-10.sh rename to regression-tests/test-results/gcc-13/run-tests-gcc-13.sh index ea917ece97..f053e03fcc 100644 --- a/regression-tests/test-results/gcc-10/run-tests-gcc-10.sh +++ b/regression-tests/test-results/gcc-13/run-tests-gcc-13.sh @@ -1,15 +1,15 @@ -# This is intended to be run in the /test-results/gcc-10 subdirectory -# in a Linux shell with g++-10 installed +# This is intended to be run in the /test-results/gcc-13 subdirectory +# in a Linux shell with gcc 13 installed # cp ../*.cpp . rm -f *.output count=0 exe_count=0 -g++-10 --version > gcc-version.output 2>&1 +gcc --version > gcc-version.output 2>&1 for f in *.cpp do - printf "Starting g++-10 %s\n" "$f" - g++-10 -I../../../include -std=c++20 -pthread -o test.exe $f > $f.output 2>&1 + printf "Starting gcc 13 %s\n" "$f" + g++ -I../../../include -std=c++20 -pthread -o test.exe $f > $f.output 2>&1 rm -f $f let count=count+1 if test -f "test.exe"; then diff --git a/regression-tests/test-results/gcc-13/xyzzy b/regression-tests/test-results/gcc-13/xyzzy new file mode 100644 index 0000000000..68d214b54b --- /dev/null +++ b/regression-tests/test-results/gcc-13/xyzzy @@ -0,0 +1 @@ +Hello Freddy with UFCS! \ No newline at end of file diff --git a/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp b/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp index 23e7a12dd1..fdb89680d4 100644 --- a/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp +++ b/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp @@ -48,6 +48,6 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS_0(ssize, vec)), ""); auto post_21_5 = cpp2::finally_success([_0 = CPP2_UFCS_0(ssize, vec)]{cpp2::Default.expects(CPP2_UFCS_0(ssize, vec)==_0 + 1, "");} ); #line 23 "mixed-captures-in-expressions-and-postconditions.cpp2" - CPP2_UFCS(insert, vec, CPP2_UFCS_0(begin, vec) + where, val); + (void) CPP2_UFCS(insert, vec, CPP2_UFCS_0(begin, vec) + where, val); } diff --git a/regression-tests/test-results/msvc-2022/MSVC-version.output b/regression-tests/test-results/msvc-2022/MSVC-version.output index 1712fd1bfa..1ce6aa26c4 100644 --- a/regression-tests/test-results/msvc-2022/MSVC-version.output +++ b/regression-tests/test-results/msvc-2022/MSVC-version.output @@ -1,3 +1,3 @@ -Microsoft (R) C/C++ Optimizing Compiler Version 19.35.32217.1 for x86 +Microsoft (R) C/C++ Optimizing Compiler Version 19.36.32534 for x86 Copyright (C) Microsoft Corporation. All rights reserved. diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-optional-template-argument-list.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-optional-template-argument-list.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-optional-template-argument-list.cpp.output b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-optional-template-argument-list.cpp.output new file mode 100644 index 0000000000..d49488a644 --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-optional-template-argument-list.cpp.output @@ -0,0 +1 @@ +pure2-bugfix-for-optional-template-argument-list.cpp diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.execution new file mode 100644 index 0000000000..e69de29bb2 diff --git a/regression-tests/test-results/msvc-2022/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.output b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.output new file mode 100644 index 0000000000..2e5bc8e9f0 --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp.output @@ -0,0 +1 @@ +pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp diff --git a/regression-tests/test-results/msvc-2022/pure2-cpp1-multitoken-fundamental-types.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-cpp1-multitoken-fundamental-types.cpp.execution deleted file mode 100644 index a7a4bc3792..0000000000 --- a/regression-tests/test-results/msvc-2022/pure2-cpp1-multitoken-fundamental-types.cpp.execution +++ /dev/null @@ -1 +0,0 @@ --50.250000 diff --git a/regression-tests/test-results/msvc-2022/pure2-inspect-values.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-inspect-values.cpp.execution deleted file mode 100644 index 582ab3ce5d..0000000000 --- a/regression-tests/test-results/msvc-2022/pure2-inspect-values.cpp.execution +++ /dev/null @@ -1,10 +0,0 @@ -zero -rev dodgson -(no match) -the answer -zero -plugh -zero -integer -42 -xyzzy -(no match) diff --git a/regression-tests/test-results/pure2-bugfix-for-optional-template-argument-list.cpp b/regression-tests/test-results/pure2-bugfix-for-optional-template-argument-list.cpp new file mode 100644 index 0000000000..3b78d806f0 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-optional-template-argument-list.cpp @@ -0,0 +1,23 @@ + +#define CPP2_USE_MODULES Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-optional-template-argument-list.cpp2" +extern std::plus<> const plus; +[[nodiscard]] auto main() -> int; + + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-bugfix-for-optional-template-argument-list.cpp2" +std::plus<> const plus {}; +[[nodiscard]] auto main() -> int { return std::plus<>()(0, 0); } + diff --git a/regression-tests/test-results/pure2-bugfix-for-optional-template-argument-list.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-optional-template-argument-list.cpp2.output new file mode 100644 index 0000000000..cd793f10af --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-optional-template-argument-list.cpp2.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-optional-template-argument-list.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/regression-tests/test-results/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp b/regression-tests/test-results/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp new file mode 100644 index 0000000000..53b7a823dd --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp @@ -0,0 +1,26 @@ + +#define CPP2_USE_MODULES Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2" +template auto f() -> void; +auto main() -> int; + + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2" +template auto f() -> void +requires (std::regular) +#line 1 "pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2" + { g(T()); } +auto main() -> int {} + diff --git a/regression-tests/test-results/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2.output new file mode 100644 index 0000000000..f849c57b62 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-requires-clause-unbraced-function-initializer.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/regression-tests/test-results/pure2-cpp1-multitoken-fundamental-types-error.cpp2.output b/regression-tests/test-results/pure2-cpp1-multitoken-fundamental-types-error.cpp2.output index ea256a33bd..2cd5bba7f1 100644 --- a/regression-tests/test-results/pure2-cpp1-multitoken-fundamental-types-error.cpp2.output +++ b/regression-tests/test-results/pure2-cpp1-multitoken-fundamental-types-error.cpp2.output @@ -23,7 +23,7 @@ pure2-cpp1-multitoken-fundamental-types-error.cpp2(6,8): error: 'long double' is - using those when you need them is fine, but name them with these short names instead: short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, __schar, __uchar - see also cpp2util.h > "Convenience names for integer types" -pure2-cpp1-multitoken-fundamental-types-error.cpp2(7,8): error: 'unsigned char' - did you mean 'u8' (usually best) or '__uchar'? +pure2-cpp1-multitoken-fundamental-types-error.cpp2(7,8): error: 'unsigned char' - did you mean 'u8' (usually best) or 'cpp2::__uchar'? pure2-cpp1-multitoken-fundamental-types-error.cpp2(7,8): error: 'unsigned char' is an old-style C/C++ multi-word keyword type - most such types should be used only for interoperability with older code - using those when you need them is fine, but name them with these short names instead: diff --git a/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp b/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp index 9fe635a1a6..6a879b6562 100644 --- a/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp +++ b/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp @@ -31,7 +31,7 @@ auto test_generic(auto const& x, auto const& msg) -> void; test_generic(a, "any"); test_generic(o, "optional"); - CPP2_UFCS_TEMPLATE(emplace, (<0>), v, 1); + (void) CPP2_UFCS_TEMPLATE(emplace, (<0>), v, 1); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/test-results/pure2-stdio-with-raii.cpp b/regression-tests/test-results/pure2-stdio-with-raii.cpp index 4d2880abfc..d9b5012756 100644 --- a/regression-tests/test-results/pure2-stdio-with-raii.cpp +++ b/regression-tests/test-results/pure2-stdio-with-raii.cpp @@ -24,6 +24,6 @@ [[nodiscard]] auto main() -> int{ std::string s {"Freddy"}; auto myfile {cpp2::fopen("xyzzy", "w")}; - CPP2_UFCS(fprintf, std::move(myfile), "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s))); + (void) CPP2_UFCS(fprintf, std::move(myfile), "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s))); } diff --git a/regression-tests/test-results/pure2-stdio.cpp b/regression-tests/test-results/pure2-stdio.cpp index eba354c30b..13bbdf97f8 100644 --- a/regression-tests/test-results/pure2-stdio.cpp +++ b/regression-tests/test-results/pure2-stdio.cpp @@ -27,7 +27,7 @@ [[nodiscard]] auto main() -> int{ std::string s {"Fred"}; auto myfile {fopen("xyzzy", "w")}; - CPP2_UFCS(fprintf, myfile, "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s))); - CPP2_UFCS_0(fclose, std::move(myfile)); + (void) CPP2_UFCS(fprintf, myfile, "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s))); + (void) CPP2_UFCS_0(fclose, std::move(myfile)); } diff --git a/regression-tests/test-results/pure2-type-safety-1.cpp b/regression-tests/test-results/pure2-type-safety-1.cpp index bb1e1365ce..469305b464 100644 --- a/regression-tests/test-results/pure2-type-safety-1.cpp +++ b/regression-tests/test-results/pure2-type-safety-1.cpp @@ -42,7 +42,7 @@ auto print(cpp2::in msg, cpp2::in b) -> void; std::cout << "\n"; - CPP2_UFCS_TEMPLATE(emplace, (<1>), v, 1); + (void) CPP2_UFCS_TEMPLATE(emplace, (<1>), v, 1); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp b/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp index 4f4c83f3e8..16da06a01d 100644 --- a/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp +++ b/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp @@ -31,7 +31,7 @@ auto test_generic(auto const& x, auto const& msg) -> void; test_generic(a, "any"); test_generic(o, "optional"); - CPP2_UFCS_TEMPLATE(emplace, (<2>), v, 1); + (void) CPP2_UFCS_TEMPLATE(emplace, (<2>), v, 1); a = 2; o = 3; test_generic(42, "int"); diff --git a/regression-tests/test-results/pure2-types-basics.cpp b/regression-tests/test-results/pure2-types-basics.cpp index 1a1a983963..3429feb0f9 100644 --- a/regression-tests/test-results/pure2-types-basics.cpp +++ b/regression-tests/test-results/pure2-types-basics.cpp @@ -38,7 +38,7 @@ class myclass { #line 20 "pure2-types-basics.cpp2" - public: myclass(cpp2::in x, cpp2::in s); + public: explicit myclass(cpp2::in x, cpp2::in s); #line 27 "pure2-types-basics.cpp2" diff --git a/regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp b/regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp index caaaaecd03..2020cd3b22 100644 --- a/regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp +++ b/regression-tests/test-results/pure2-types-order-independence-and-nesting.cpp @@ -153,7 +153,7 @@ namespace N { #line 35 "pure2-types-order-independence-and-nesting.cpp2" auto X::exx(cpp2::in count) const -> void{ // Exercise '_' anonymous objects too while we're at it - auto auto_37_9 {cpp2::finally([&]() -> void { std::cout << "leaving call to 'why(" + cpp2::to_string(count) + ")'\n"; })}; + cpp2::finally auto_37_9 {[&]() -> void { std::cout << "leaving call to 'why(" + cpp2::to_string(count) + ")'\n"; }}; if (cpp2::cmp_less(count,5)) { CPP2_UFCS(why, (*cpp2::assert_not_null(py)), count + 1);// use Y object from X } diff --git a/regression-tests/test-results/pure2-types-ordering-via-meta-functions.cpp b/regression-tests/test-results/pure2-types-ordering-via-meta-functions.cpp index e73a66ed2b..9f035f55b2 100644 --- a/regression-tests/test-results/pure2-types-ordering-via-meta-functions.cpp +++ b/regression-tests/test-results/pure2-types-ordering-via-meta-functions.cpp @@ -68,14 +68,6 @@ public: [[nodiscard]] auto operator<=>(person_in_family_tree const& that) const class mystruct { public: int val {0}; - public: mystruct(mystruct const& that); - -public: auto operator=(mystruct const& that) -> mystruct& ; -public: mystruct(mystruct&& that) noexcept; -public: auto operator=(mystruct&& that) noexcept -> mystruct& ; -public: explicit mystruct(); - -#line 19 "pure2-types-ordering-via-meta-functions.cpp2" }; auto main() -> int; @@ -123,18 +115,6 @@ auto main() -> int; } - mystruct::mystruct(mystruct const& that) - : val{ that.val }{} - -auto mystruct::operator=(mystruct const& that) -> mystruct& { - val = that.val; - return *this;} -mystruct::mystruct(mystruct&& that) noexcept - : val{ std::move(that).val }{} -auto mystruct::operator=(mystruct&& that) noexcept -> mystruct& { - val = std::move(that).val; - return *this;} -mystruct::mystruct(){} #line 21 "pure2-types-ordering-via-meta-functions.cpp2" auto main() -> int{ my_integer a {1}; diff --git a/regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp b/regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp index aab2de3ded..350d5cc2e9 100644 --- a/regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp +++ b/regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp @@ -14,21 +14,23 @@ [[nodiscard]] auto main() -> int; -#line 22 "pure2-ufcs-member-access-and-chaining.cpp2" +#line 24 "pure2-ufcs-member-access-and-chaining.cpp2" +auto no_return(cpp2::in x) -> void; + [[nodiscard]] auto ufcs(cpp2::in i) -> int; struct fun__ret { int i; }; -#line 26 "pure2-ufcs-member-access-and-chaining.cpp2" +#line 30 "pure2-ufcs-member-access-and-chaining.cpp2" [[nodiscard]] auto fun() -> fun__ret; -#line 31 "pure2-ufcs-member-access-and-chaining.cpp2" +#line 35 "pure2-ufcs-member-access-and-chaining.cpp2" [[nodiscard]] auto get_i(auto const& r) -> int; -#line 35 "pure2-ufcs-member-access-and-chaining.cpp2" +#line 39 "pure2-ufcs-member-access-and-chaining.cpp2" // And a test for non-local UFCS, which shouldn't do a [&] capture [[nodiscard]] auto f(auto const& x) -> int; extern int y; @@ -38,32 +40,36 @@ extern int y; #line 1 "pure2-ufcs-member-access-and-chaining.cpp2" [[nodiscard]] auto main() -> int{ auto i {42}; - CPP2_UFCS_0(ufcs, std::move(i)); + (void) CPP2_UFCS_0(ufcs, std::move(i)); auto j {fun()}; - CPP2_UFCS_0(ufcs, j.i); + (void) CPP2_UFCS_0(ufcs, j.i); - CPP2_UFCS_0(ufcs, fun().i); + (void) CPP2_UFCS_0(ufcs, fun().i); auto k {fun().i}; - CPP2_UFCS_0(ufcs, std::move(k)); + (void) CPP2_UFCS_0(ufcs, std::move(k)); - CPP2_UFCS_0(ufcs, get_i(j)); + (void) CPP2_UFCS_0(ufcs, get_i(j)); - CPP2_UFCS_0(ufcs, get_i(fun())); + (void) CPP2_UFCS_0(ufcs, get_i(fun())); auto res {CPP2_UFCS_0(ufcs, (42))}; - CPP2_UFCS_0(ufcs, (std::move(j).i)); + (void) CPP2_UFCS_0(ufcs, (std::move(j).i)); + + CPP2_UFCS_0(no_return, 42); } +auto no_return(cpp2::in x) -> void{} + [[nodiscard]] auto ufcs(cpp2::in i) -> int{ return i + 2; } [[nodiscard]] auto fun() -> fun__ret{ cpp2::deferred_init i; -#line 27 "pure2-ufcs-member-access-and-chaining.cpp2" +#line 31 "pure2-ufcs-member-access-and-chaining.cpp2" i.construct(42); return { std::move(i.value()) }; } @@ -72,7 +78,7 @@ extern int y; return r.i; } -#line 36 "pure2-ufcs-member-access-and-chaining.cpp2" +#line 40 "pure2-ufcs-member-access-and-chaining.cpp2" [[nodiscard]] auto f(auto const& x) -> int { return 0; } int y {CPP2_UFCS_0_NONLOCAL(f, 0)}; diff --git a/regression-tests/test-results/version b/regression-tests/test-results/version index 8e8a9cf312..c2b005ca21 100644 --- a/regression-tests/test-results/version +++ b/regression-tests/test-results/version @@ -1,5 +1,5 @@ -cppfront compiler v0.2.1 Build 8529:1625 +cppfront compiler v0.2.1 Build 8618:1139 Copyright(c) Herb Sutter All rights reserved SPDX-License-Identifier: CC-BY-NC-ND-4.0 diff --git a/source/build.info b/source/build.info index a9418cc12e..11c8f52d3b 100644 --- a/source/build.info +++ b/source/build.info @@ -1 +1 @@ -"8529:1625" \ No newline at end of file +"8618:1139" \ No newline at end of file diff --git a/source/common.h b/source/common.h index c7a834ebb6..a156da34bc 100644 --- a/source/common.h +++ b/source/common.h @@ -501,6 +501,15 @@ auto contains( != range.end(); } +auto contains( + std::string const& s, + auto const& value +) + -> bool +{ + return s.find(value) != s.npos; +} + //----------------------------------------------------------------------- // diff --git a/source/cppfront.cpp b/source/cppfront.cpp index 382dfe122d..1bad85a53f 100644 --- a/source/cppfront.cpp +++ b/source/cppfront.cpp @@ -1666,7 +1666,7 @@ class cppfront assert(n.identifier); emit(*n.identifier, is_qualified); // inform the identifier if we know this is qualified - if (!n.template_args.empty()) { + if (n.open_angle != source_position{}) { printer.print_cpp2("<", n.open_angle); auto first = true; for (auto& a : n.template_args) { @@ -3434,7 +3434,23 @@ class cppfront { suppress_move_from_last_use = true; } - emit(*n.expr); + // If it's "_ =" then emit (void) + bool suppress_operator = false; + if ( + !n.terms.empty() + && n.terms.front().op->type() == lexeme::Assignment + && n.expr->get_postfix_expression_node() + && n.expr->get_postfix_expression_node()->get_first_token_ignoring_this() + && *n.expr->get_postfix_expression_node()->get_first_token_ignoring_this() == "_" + ) + { + printer.print_cpp2( "(void)", n.position() ); + suppress_operator = true; + } + else + { + emit(*n.expr); + } suppress_move_from_last_use = false; // Check that this isn't an illegal pointer operation @@ -3496,9 +3512,18 @@ class cppfront emit(*x.expr); printer.print_cpp2( ")", n.position() ); } - else { - printer.print_cpp2(" ", n.position()); - emit(*x.op); + else + { + // For the first operator only, if we are emitting a "_ =" discard + // then we've already emitted the cast to void and don't need the = + if (suppress_operator) { + assert( x.op->type() == lexeme::Assignment ); + suppress_operator = false; + } + else { + printer.print_cpp2(" ", n.position()); + emit(*x.op); + } printer.print_cpp2(" ", n.position()); emit(*x.expr); } @@ -3655,6 +3680,10 @@ class cppfront ) -> void { + if (!sema.check(n)) { + return; + } + auto emit_parameters = !n.emitted && n.parameters @@ -4459,7 +4488,8 @@ class cppfront // We'll use this common guidance in several errors, // so write it once to keep the guidance consistent - auto error_msg = "an operator= body must start with a series of 'member = value;' initialization statements for each of the type-scope objects in the same order they are declared"; + assert (n.parent_declaration && n.parent_declaration->name()); + auto error_msg = "an operator= body must start with a series of 'member = value;' initialization statements for each of the type-scope objects in the same order they are declared, or the member must have a default initializer (in type '" + n.parent_declaration->name()->to_string(true) + "')"; // If this constructor's type has data members, handle their initialization // - objects is the list of this type's declarations @@ -4490,6 +4520,9 @@ class cppfront { assert (*statement); stmt_pos = (*statement)->position(); + if (stmt_pos.lineno < 0) { + stmt_pos = n.position(); + } auto lhs = std::string{}; auto rhs = std::string{}; @@ -4586,7 +4619,15 @@ class cppfront { errors.emplace_back( stmt_pos, - "expected '" + object_name + " = ...' initialization statement - " + error_msg + "in operator=, expected '" + object_name + " = ...' initialization statement (because type scope object '" + object_name + "' does not have a default initializer)" + ); + errors.emplace_back( + (*object)->position(), + "see declaration for '" + object_name + "' here" + ); + errors.emplace_back( + stmt_pos, + error_msg ); return; } @@ -4702,7 +4743,15 @@ class cppfront { errors.emplace_back( (*object)->position(), - canonize_object_name(*object) + " was not initialized - " + error_msg + canonize_object_name(*object) + " was not initialized - did you forget to write a default initializer, or assign to it in the operator= body?" + ); + errors.emplace_back( + (*object)->position(), + "see declaration for '" + canonize_object_name(*object) + "' here" + ); + errors.emplace_back( + (*object)->position(), + error_msg ); return; } @@ -4744,7 +4793,13 @@ class cppfront ) -> void { - if (!sema.check(n)) { + // Declarations are handled in multiple passes, + // but we only want to do the sema checks once + if ( + printer.get_phase() == printer.phase2_func_defs + && !sema.check(n) + ) + { return; } @@ -4925,9 +4980,14 @@ class cppfront for (auto& stmt : compound_stmt->statements) { + if (!stmt->is_declaration()) { + // We will already have emitted an error for this in sema.check + return; + } auto& decl = std::get(stmt->statement); assert(decl); assert(decl->name()); + auto emit_as_base = decl->get_decl_if_type_scope_object_name_before_a_base_type(*decl->name()); @@ -5067,10 +5127,7 @@ class cppfront { assert(stmt); if (!stmt->is_declaration()) { - errors.emplace_back( - stmt->position(), - "a user-defined type body must contain only declarations, not other code" - ); + // We will already have emitted an error for this in sema.check return; } @@ -5154,21 +5211,24 @@ class cppfront ); auto prefix = "\n" + std::string( indent, ' ' ) + "public: "; - // If no constructor was defined, there should only be - // a default constructor, so generate that - if (!found_constructor) { - printer.print_extra( prefix + id + "() = default;" ); - } + if (n.member_function_generation) + { + // If no constructor was defined, there should only be + // a default constructor, so generate that + if (!found_constructor) { + printer.print_extra( prefix + id + "() = default;" ); + } - // If no 'that' constructor was defined, disable copy/move - // so that Cpp1 doesn't silently generate it anyway - if (!found_that_constructor) { - printer.print_extra( prefix + id + "(" + id + " const&) = delete; /* No 'that' constructor, suppress copy */" ); - printer.print_extra( prefix + "auto operator=(" + id + " const&) -> void = delete;" ); - } + // If no 'that' constructor was defined, disable copy/move + // so that Cpp1 doesn't silently generate it anyway + if (!found_that_constructor) { + printer.print_extra( prefix + id + "(" + id + " const&) = delete; /* No 'that' constructor, suppress copy */" ); + printer.print_extra( prefix + "auto operator=(" + id + " const&) -> void = delete;" ); + } - if (!found_constructor || !found_that_constructor) { - printer.print_extra( "\n" ); + if (!found_constructor || !found_that_constructor) { + printer.print_extra( "\n" ); + } } printer.print_cpp2("};\n", compound_stmt->close_brace); @@ -5313,7 +5373,6 @@ class cppfront break;default: if ( func->is_constructor() - && (func->is_default_constructor() || func->parameters->ssize() == 2) && !func->is_constructor_with_that() && generating_assignment_from != &n ) @@ -5409,6 +5468,7 @@ class cppfront ( n.is_constructor() && !n.is_constructor_with_that() + && !contains( current_functions.back().declared_that_functions.assignments_from, n.nth_parameter_type_name(2) ) ) ) { @@ -5741,6 +5801,14 @@ class cppfront // If this is anonymous object (named "_"), generate a unique name if (n.has_name("_")) { + if (n.has_wildcard_type()) { + errors.emplace_back( + n.identifier->position(), + "an object can have an anonymous name or an anonymous type, but not both at the same type (rationale: if '_ := f();' were allowed to keep the returned object alive, that syntax would be dangerously close to '_ = f();' to discard the returned object, and such importantly opposite meanings deserve more than a one-character typo distance; and explicit discarding gets the nice syntax because it's likely more common)" + ); + return; + } + printer.print_cpp2( "auto_" + labelized_position(n.identifier->get_token()), n.identifier->position() @@ -5961,8 +6029,7 @@ auto main( exit_status = EXIT_FAILURE; } - // In any case, emit the debug information (during early development this is - // on by default, later we'll flip the switch to turn it on instead of off) + // And, if requested, the debug information if (enable_debug_output_files) { c.debug_print(); } diff --git a/source/io.h b/source/io.h index 60a4124950..9bb2b31e16 100644 --- a/source/io.h +++ b/source/io.h @@ -22,7 +22,6 @@ #include #include #include -#include #include @@ -115,16 +114,22 @@ auto is_preprocessor( auto starts_with_import(std::string const& line) -> bool { - const auto ws = std::regex("\\s+"); // whitespace - auto i = 1; - for (std::sregex_token_iterator iter(std::begin(line), std::end(line), ws, -1); - iter != std::sregex_token_iterator(); - ++iter, ++i) { - if (iter->length() > 0) { - return *iter == "import"; - } + auto i = 0; + + // find first non-whitespace character + if (!move_next(line, i, isspace)) { + return false; } - return false; + + static constexpr auto import_keyword = std::string_view{"import"}; + + // the first token must begin with 'import' + if (!std::string_view(line).substr(i).starts_with(import_keyword)) { + return false; + } + + // and not be immediately followed by an _identifier-continue_ + return !is_identifier_continue(line[i + import_keyword.size()]); } @@ -221,6 +226,10 @@ auto starts_with_operator(std::string_view s) break;case '/': case '=': case '!': + case '*': + case '%': + case '^': + case '~': if (c2 == '=') { return j+2; } return j+1; @@ -239,7 +248,7 @@ auto starts_with_operator(std::string_view s) break;case '|': case '&': if (c2 == c1 && c3 == '=') { return j+3; } - if (c2 == c1) { return j+2; } + if (c2 == c1 || c2 == '=') { return j+2; } return j+1; // >>= >> >= > @@ -853,6 +862,8 @@ class source // if (auto pre = is_preprocessor(buf, true); pre.is_preprocessor + && !in_comment + && !in_raw_string_literal ) { cpp1_found = true; diff --git a/source/lex.h b/source/lex.h index 84ca036359..805bf7e5bc 100644 --- a/source/lex.h +++ b/source/lex.h @@ -226,10 +226,9 @@ class token source_position pos, lexeme type ) - : start {start} - , count {int16_t(count)} - , pos {pos } - , lex_type{type } + : sv {start, unsafe_narrow(count)} + , pos {pos} + , lex_type{type} { } @@ -238,18 +237,17 @@ class token source_position pos, lexeme type ) - : start {sz} - , count {__as(std::strlen(sz))} - , pos {pos } - , lex_type{type } + : sv {sz} + , pos {pos} + , lex_type{type} { } auto as_string_view() const -> std::string_view { - assert (start); - return {start, static_cast(count)}; + assert (sv.data()); + return sv; } operator std::string_view() const @@ -272,7 +270,7 @@ class token auto to_string( bool text_only = false ) const -> std::string { - auto text = std::string{start, static_cast(count)}; + auto text = std::string{sv}; if (text_only) { return text; } @@ -294,13 +292,13 @@ class token pos.colno += offset; } - auto position() const -> source_position { return pos; } + auto position() const -> source_position { return pos; } - auto length () const -> int { return count; } + auto length () const -> int { return sv.size(); } - auto type () const -> lexeme { return lex_type; } + auto type () const -> lexeme { return lex_type; } - auto set_type(lexeme l) -> void { lex_type = l; } + auto set_type(lexeme l) -> void { lex_type = l; } auto visit(auto& v, int depth) const -> void @@ -309,12 +307,9 @@ class token } private: - // Store (char*,count) because it's smaller than a string_view - // - char const* start; - int16_t count; - source_position pos; - lexeme lex_type; + std::string_view sv; + source_position pos; + lexeme lex_type; }; static_assert (CHAR_BIT == 8); @@ -429,9 +424,9 @@ auto expand_string_literal( // Then put interpolated chunk into ret auto chunk = std::string{text.substr(open, pos - open)}; { // unescape chunk string - auto last_it = std::copy_if(std::begin(chunk), std::end(chunk), std::begin(chunk), [escape = false](const auto& e) mutable { + auto last_it = std::remove_if(std::begin(chunk), std::end(chunk), [escape = false](const auto& e) mutable { escape = !escape && e == '\\'; - return !escape; + return escape; }); chunk.erase(last_it, std::end(chunk)); } @@ -654,8 +649,8 @@ auto lex_line( if (num_merged_tokens > 1) { auto alt = std::string{}; - if (is_char && is_signed) { alt = "'i8' (usually best) or '__schar'"; } - else if (is_char && is_unsigned) { alt = "'u8' (usually best) or '__uchar'"; } + if (is_char && is_signed) { alt = "'i8' (usually best) or 'cpp2::__schar'"; } + else if (is_char && is_unsigned) { alt = "'u8' (usually best) or 'cpp2::__uchar'"; } else if (is_short && !is_unsigned) { alt = "'short'" ; } else if (is_short && is_unsigned) { alt = "'ushort'" ; } else if (is_long == 1 && !is_unsigned) { alt = "'long'" ; } @@ -933,17 +928,19 @@ auto lex_line( //G any Cpp1-and-Cpp2 keyword //G one of: 'import' 'module' 'export' 'is' 'as' //G - auto do_is_keyword = [&](std::regex const& r) { - std::cmatch m; - if (std::regex_search(&line[i], m, r)) { - assert (m.position(0) == 0); + auto do_is_keyword = [&](std::vector const& r) { + auto remaining_line = std::string_view(line).substr(unsafe_narrow(i)); + auto m = std::find_if(r.begin(), r.end(), [&](std::string_view s) { + return remaining_line.starts_with(s); + }); + if (m != r.end()) { // If we matched and what's next is EOL or a non-identifier char, we matched! if ( - i+m[0].length() == std::ssize(line) // EOL - || !is_identifier_continue(line[i+m[0].length()]) // non-identifier char + i+std::ssize(*m) == std::ssize(line) // EOL + || !is_identifier_continue(line[unsafe_narrow(i)+std::size(*m)]) // non-identifier char ) { - return static_cast(m[0].length()); + return static_cast(std::ssize(*m)); } } return 0; @@ -955,53 +952,53 @@ auto lex_line( // reserve all the ones Cpp1 has both for compatibility and to not give up a keyword // Some keywords like "delete" and "union" are not in this list because we reject them elsewhere // Cpp2 also adds a couple, notably "is" and "as" - const auto keys = std::regex( - "^alignas|^alignof|^asm|^as|^auto|" - "^bool|^break|" - "^case|^catch|^char16_t|^char32_t|^char8_t|^char|^co_await|^co_return|" - "^co_yield|^concept|^const_cast|^consteval|^constexpr|^constinit|^const|^continue|" - "^decltype|^default|^double|^do|^dynamic_cast|" - "^else|^enum|^explicit|^export|^extern|" - "^float|^for|^friend|" - "^goto|" - "^if|^import|^inline|^int|^is|" - "^long|" - "^module|^mutable|" - "^namespace|^noexcept|" - "^operator|" - "^private|^protected|^public|" - "^register|^reinterpret_cast|^requires|^return|" - "^short|^signed|^sizeof|^static_assert|^static_cast|^static|^switch|" - "^template|^this|^thread_local|^throws|^throw|^try|^typedef|^typeid|^typename|" - "^unsigned|^using|" - "^virtual|^void|^volatile|" - "^wchar_t|^while" - ); + static const auto keys = std::vector{ + "alignas", "alignof", "asm", "as", "auto", + "bool", "break", + "case", "catch", "char16_t", "char32_t", "char8_t", "char", "co_await", "co_return", + "co_yield", "concept", "const_cast", "consteval", "constexpr", "constinit", "const", "continue", + "decltype", "default", "double", "do", "dynamic_cast", + "else", "enum", "explicit", "export", "extern", + "float", "for", "friend", + "goto", + "if", "import", "inline", "int", "is", + "long", + "module", "mutable", + "namespace", "noexcept", + "operator", + "private", "protected", "public", + "register", "reinterpret_cast", "requires", "return", + "short", "signed", "sizeof", "static_assert", "static_cast", "static", "switch", + "template", "this", "thread_local", "throws", "throw", "try", "typedef", "typeid", "typename", + "unsigned", "using", + "virtual", "void", "volatile", + "wchar_t", "while" + }; return do_is_keyword(keys); }; auto peek_is_cpp2_fundamental_type_keyword = [&] { - const auto keys = std::regex( - "^i8|^i16|^i32|^i64|^u8|^u16|^u32|^u64" - ); + static const auto keys = std::vector{ + "i8", "i16", "i32", "i64", "longdouble", "longlong", "u8", "u16", "u32", "u64", "ulong", "ulonglong", "ushort" + }; return do_is_keyword(keys); }; auto peek_is_cpp1_multi_token_fundamental_keyword = [&] { - const auto multi_keys = std::regex( - "^char16_t|^char32_t|^char8_t|^char|^double|^float|^int|^long|^short|^signed|^unsigned" - ); + static const auto multi_keys = std::vector{ + "char16_t", "char32_t", "char8_t", "char", "double", "float", "int", "long", "short", "signed", "unsigned" + }; return do_is_keyword(multi_keys); }; auto reset_processing_of_the_line = [&]() { // Redo processing of this whole line now that the string is expanded, // which may have moved it in memory... move i back to the line start - // and discard any tokens we already tokenized for this line + // and _ = any tokens we already tokenized for this line i = colno_t{-1}; while ( !tokens.empty() @@ -1665,7 +1662,7 @@ auto lex_line( if (tokens.back() == "static_cast") { errors.emplace_back( source_position(lineno, i), - "'static_cast(val)' is not supported in Cpp2 - use 'val as T' for safe conversions instead, or if necessary unsafe_narrow(val) for a possibly-lossy narrowing conversion" + "'static_cast(val)' is not supported in Cpp2 - use 'val as T' for safe conversions instead, or if necessary cpp2::unsafe_narrow(val) for a possibly-lossy narrowing conversion" ); } if (tokens.back() == "dynamic_cast") { diff --git a/source/parse.h b/source/parse.h index 7e6704ce05..4fe1a44f31 100644 --- a/source/parse.h +++ b/source/parse.h @@ -144,14 +144,32 @@ struct primary_expression_node std::unique_ptr > expr; + // API + // + auto is_identifier() const + -> bool; + + auto is_id_expression() const + -> bool; + auto is_expression_list() const -> bool; auto get_expression_list() const -> expression_list_node const*; + auto is_literal() const + -> bool; + auto template_args_count() -> int; + auto get_token() const -> token const*; + + auto to_string() const + -> std::string; + + // Internals + // auto position() const -> source_position; auto visit(auto& v, int depth) -> void; }; @@ -161,17 +179,32 @@ struct literal_node { token const* literal = {}; token const* user_defined_suffix = {}; - auto position() const - -> source_position + // API + // + auto get_token() const + -> token const* + { + return literal; + } + + auto to_string() const + -> std::string { assert (literal); - return literal->position(); + auto ret = literal->to_string(true); + if (user_defined_suffix) { + ret += user_defined_suffix->to_string(true); + } + return ret; } - auto get_token() const - -> token const* + // Internals + // + auto position() const + -> source_position { - return literal; + assert (literal); + return literal->position(); } auto visit(auto& v, int depth) -> void @@ -194,6 +227,14 @@ struct prefix_expression_node std::vector ops; std::unique_ptr expr; + // API + // + auto is_identifier() const + -> bool; + + auto is_id_expression() const + -> bool; + auto is_expression_list() const -> bool; @@ -207,8 +248,16 @@ struct prefix_expression_node return expr.get(); } + auto is_literal() const + -> bool; + auto is_result_a_temporary_variable() const -> bool; + auto to_string() const + -> std::string; + + // Internals + // auto position() const -> source_position; auto visit(auto& v, int depth) -> void; }; @@ -231,6 +280,18 @@ struct binary_expression_node // API // + auto is_identifier() const + -> bool + { + return terms.empty() && expr->is_identifier(); + } + + auto is_id_expression() const + -> bool + { + return terms.empty() && expr->is_id_expression(); + } + auto is_expression_list() const -> bool { @@ -246,6 +307,12 @@ struct binary_expression_node return {}; } + auto is_literal() const + -> bool + { + return terms.empty() && expr->is_literal(); + } + // Get left-hand postfix-expression auto get_postfix_expression_node() const -> postfix_expression_node * @@ -302,6 +369,22 @@ struct binary_expression_node } } + auto to_string() const + -> std::string + { + assert (expr); + auto ret = expr->to_string(); + for (auto const& x : terms) { + assert (x.op); + ret += " " + x.op->to_string(true); + assert (x.expr); + ret += " " + x.expr->to_string(); + } + return ret; + } + + // Internals + // auto position() const -> source_position { @@ -354,6 +437,18 @@ struct expression_node // API // + auto is_identifier() const + -> bool + { + return expr->is_identifier(); + } + + auto is_id_expression() const + -> bool + { + return expr->is_id_expression(); + } + auto is_expression_list() const -> bool { @@ -369,9 +464,24 @@ struct expression_node return {}; } + auto is_literal() const + -> bool + { + return expr->is_literal(); + } + auto get_lhs_rhs_if_simple_assignment() const -> assignment_expression_lhs_rhs; + auto to_string() const + -> std::string + { + assert (expr); + return expr->to_string(); + } + + // Internals + // auto position() const -> source_position { assert (expr); @@ -452,6 +562,18 @@ struct expression_list_node } }; +auto primary_expression_node::is_identifier() const + -> bool +{ + return expr.index() == identifier; +} + +auto primary_expression_node::is_id_expression() const + -> bool +{ + return expr.index() == id_expression; +} + auto primary_expression_node::is_expression_list() const -> bool { @@ -467,12 +589,29 @@ auto primary_expression_node::get_expression_list() const return {}; } +auto primary_expression_node::is_literal() const + -> bool +{ + return expr.index() == literal; +} + struct expression_statement_node { std::unique_ptr expr; bool has_semicolon = false; + // API + // + auto to_string() const + -> std::string + { + assert (expr); + return expr->to_string(); + } + + // Internals + // auto position() const -> source_position { @@ -542,6 +681,18 @@ struct postfix_expression_node // API // + auto is_identifier() const + -> bool + { + return ops.empty() && expr->is_identifier(); + } + + auto is_id_expression() const + -> bool + { + return ops.empty() && expr->is_id_expression(); + } + auto is_expression_list() const -> bool { @@ -557,6 +708,12 @@ struct postfix_expression_node return {}; } + auto is_literal() const + -> bool + { + return ops.empty() && expr->is_literal(); + } + auto get_first_token_ignoring_this() const -> token const*; @@ -569,6 +726,9 @@ struct postfix_expression_node } } + auto to_string() const + -> std::string; + // Internals // auto position() const -> source_position @@ -580,6 +740,18 @@ struct postfix_expression_node auto visit(auto& v, int depth) -> void; }; +auto prefix_expression_node::is_identifier() const + -> bool +{ + return ops.empty() && expr->is_identifier(); +} + +auto prefix_expression_node::is_id_expression() const + -> bool +{ + return ops.empty() && expr->is_id_expression(); +} + auto prefix_expression_node::is_expression_list() const -> bool { @@ -595,6 +767,12 @@ auto prefix_expression_node::get_expression_list() const return {}; } +auto prefix_expression_node::is_literal() const + -> bool +{ + return ops.empty() && expr->is_literal(); +} + auto prefix_expression_node::is_result_a_temporary_variable() const -> bool { if (ops.empty()) { return expr->is_result_a_temporary_variable(); @@ -636,6 +814,21 @@ capture_group::~capture_group() } +auto prefix_expression_node::to_string() const + -> std::string +{ + auto ret = std::string{}; + + for (auto const& x : ops) { + assert (x); + ret += x->as_string_view(); + } + + assert (expr); + return ret + expr->to_string(); +} + + auto prefix_expression_node::position() const -> source_position { @@ -693,7 +886,7 @@ struct unqualified_id_node auto get_token() const -> token const* { - if (template_args.empty()) { + if (open_angle == source_position{}) { assert (identifier); return identifier; } @@ -718,12 +911,13 @@ struct unqualified_id_node assert (identifier); v.start(*identifier, depth+1); - if (!template_args.empty()) { + if (open_angle != source_position{}) { // Inform the visitor that this is a template args list v.start(template_args_tag{}, depth); assert(open_angle != source_position{}); assert(close_angle != source_position{}); - assert(template_args.front().comma == source_position{}); + assert(template_args.empty() + || template_args.front().comma == source_position{}); for (auto& a : template_args) { try_visit(a.arg, v, depth+1); try_visit(a.arg, v, depth+1); @@ -925,7 +1119,7 @@ auto unqualified_id_node::to_string() const { assert(identifier); auto ret = identifier->to_string(true); - if (!template_args.empty()) { + if (open_angle != source_position{}) { auto separator = std::string{"<"}; for (auto& t : template_args) { ret += separator; @@ -960,6 +1154,20 @@ struct is_as_expression_node }; std::vector ops; + // API + // + auto is_identifier() const + -> bool + { + return ops.empty() && expr->is_identifier(); + } + + auto is_id_expression() const + -> bool + { + return ops.empty() && expr->is_id_expression(); + } + auto is_expression_list() const -> bool { @@ -975,6 +1183,12 @@ struct is_as_expression_node return {}; } + auto is_literal() const + -> bool + { + return ops.empty() && expr->is_literal(); + } + auto get_postfix_expression_node() const -> postfix_expression_node * { @@ -991,6 +1205,26 @@ struct is_as_expression_node } } + auto to_string() const + -> std::string + { + assert (expr); + auto ret = expr->to_string(); + for (auto const& x : ops) { + assert (x.op); + ret += " " + x.op->to_string(true); + if (x.type) { + ret += " " + x.type->to_string(); + } + if (x.expr) { + ret += " " + x.expr->to_string(); + } + } + return ret; + } + + // Internals + // auto position() const -> source_position { @@ -1114,6 +1348,27 @@ auto postfix_expression_node::get_first_token_ignoring_this() const } +auto postfix_expression_node::to_string() const + -> std::string +{ + assert (expr); + auto ret = expr->to_string(); + + for (auto const& x : ops) { + assert (x.op); + ret += x.op->as_string_view(); + if (x.id_expr) { + ret += x.id_expr->to_string(); + } + if (x.expr_list) { + return "(*ERROR*) temporary alpha limitation: type metafunctions cannot stringize expressions that involve nested expression-lists, declarations, or inspect expressions"; + } + } + + return ret; +} + + auto postfix_expression_node::visit(auto& v, int depth) -> void { @@ -1381,6 +1636,11 @@ struct parameter_declaration_list_node; struct statement_node { std::unique_ptr parameters; + compound_statement_node* compound_parent = nullptr; + + statement_node(compound_statement_node* compound_parent_ = nullptr) + : compound_parent{ compound_parent_ } + { } enum active { expression=0, compound, selection, declaration, return_, iteration, contract, inspect, jump }; std::variant< @@ -1443,6 +1703,17 @@ struct statement_node return {}; } + auto to_string() const + -> std::string + { + switch (statement.index()) { + break;case expression: + return std::get(statement)->to_string(); + break;default: + return "(*ERROR*) temporary alpha limitation: type metafunctions cannot stringize expressions that involve initializer statements other than expression-statements"; + } + } + // Internals // auto position() const @@ -1787,6 +2058,9 @@ struct function_type_node return false; } + auto nth_parameter_type_name(int n) const + -> std::string; + auto has_in_parameter_named(std::string_view s) const -> bool { @@ -1988,19 +2262,78 @@ struct declaration_node std::vector> meta_functions; std::unique_ptr template_parameters; source_position requires_pos = {}; - std::unique_ptr requires_clause_expression; + std::unique_ptr requires_clause_expression; source_position equal_sign = {}; std::unique_ptr initializer; declaration_node* parent_declaration = {}; + // Attributes currently configurable only via metafunction API, + // not directly in the base language grammar + bool member_function_generation = true; + bool is_constexpr = false; + bool is_static = false; + + // Constructor + // declaration_node(declaration_node* parent) : parent_declaration{parent} { } // API // + auto type_remove_all_members() + -> void + { + assert (is_type() && initializer->is_compound()); + auto body = initializer->get_if(); + assert (body); + + // Drop all statements in the body + body->statements.clear(); + + // Then also drop captures - (only) statements in + // the body should have been able to refer to it + captures = {}; + } + + auto type_disable_member_function_generation() + -> void + { + member_function_generation = false; + } + + auto make_constexpr() + -> void + { + is_constexpr = true; + } + + auto make_static() + -> void + { + is_static = true; + } + + auto object_type() const + -> std::string + { + if (!is_object()) { + return "(*ERROR*) not an object"; + } + return std::get(type)->to_string(); + } + + auto object_initializer() const + -> std::string + { + if (!is_object()) { + return "(*ERROR*) not an object"; + } + return initializer->to_string(); + } + auto get_parent() const -> declaration_node* { @@ -2139,6 +2472,15 @@ struct declaration_node return std::get(type)->has_move_parameter_named(s); } + auto nth_parameter_type_name(int n) const + -> std::string + { + if (!is_function()) { + return ""; + } + return std::get(type)->nth_parameter_type_name(n); + } + auto is_global () const -> bool { return !parent_declaration; } @@ -2534,10 +2876,11 @@ struct declaration_node } struct declared_that_funcs { - declaration_node const* out_this_in_that = {}; - declaration_node const* out_this_move_that = {}; - declaration_node const* inout_this_in_that = {}; - declaration_node const* inout_this_move_that = {}; + declaration_node const* out_this_in_that = {}; + declaration_node const* out_this_move_that = {}; + declaration_node const* inout_this_in_that = {}; + declaration_node const* inout_this_move_that = {}; + std::vector assignments_from = {}; }; auto find_declared_that_functions() const @@ -2568,6 +2911,9 @@ struct declaration_node if (decl->is_assignment_with_move_that()) { ret.inout_this_move_that = decl; } + if (decl->is_assignment() && !decl->is_assignment_with_that()) { + ret.assignments_from.emplace_back( decl->nth_parameter_type_name(2) ); + } } } @@ -2753,6 +3099,18 @@ auto parameter_declaration_node::has_name(std::string_view s) const } +auto function_type_node::nth_parameter_type_name(int n) const + -> std::string +{ + if (std::ssize(parameters->parameters) >= n) + { + return parameters->parameters[n-1]->declaration->get_object_type()->to_string(); + } + // Else + return ""; +} + + auto function_type_node::is_function_with_this() const -> bool { @@ -3024,6 +3382,38 @@ auto primary_expression_node::get_token() const } +auto primary_expression_node::to_string() const + -> std::string +{ + switch (expr.index()) + { + break;case empty: + return {}; + + break;case identifier: { + auto const& s = std::get(expr); + assert (s); + return s->to_string(); + } + + break;case id_expression: { + auto const& s = std::get(expr); + assert (s); + return s->to_string(); + } + + break;case literal: { + auto const& i = std::get(expr); + assert (i); + return i->to_string(); + } + + break;default: + return "(*ERROR*) temporary alpha limitation: type metafunctions cannot stringize expressions that involve nested expression-lists, declarations, or inspect expressions"; + } +} + + auto primary_expression_node::position() const -> source_position { @@ -4458,18 +4848,9 @@ class parser // Remember current position, in case this < is isn't a template argument list auto start_pos = pos; - // And since we'll do this in two places, factor it into a local function - auto back_out_template_arg_list = [&]{ - // Aha, this wasn't a template argument list after all, - // so back out just that part and return the identifier - n->open_angle = source_position{}; - n->template_args.clear(); - pos = start_pos; - }; - n->open_angle = curr().position(); next(); - + auto term = unqualified_id_node::term{}; do { @@ -4481,8 +4862,7 @@ class parser term.arg = std::move(i); } else { - back_out_template_arg_list(); - return n; + break; } n->template_args.push_back( std::move(term) ); } @@ -4496,7 +4876,11 @@ class parser // next term.comma = curr().position(); if (curr().type() != lexeme::Greater) { - back_out_template_arg_list(); + // Aha, this wasn't a template argument list after all, + // so back out just that part and return the identifier + n->open_angle = source_position{}; + n->template_args.clear(); + pos = start_pos; return n; } n->close_angle = curr().position(); @@ -5208,9 +5592,10 @@ class parser //GTODO try-block //G auto statement( - bool semicolon_required = true, - source_position equal_sign = source_position{}, - bool parameters_allowed = false + bool semicolon_required = true, + source_position equal_sign = source_position{}, + bool parameters_allowed = false, + compound_statement_node* compound_parent = nullptr ) -> std::unique_ptr { @@ -5219,7 +5604,7 @@ class parser return {}; } - auto n = std::make_unique(); + auto n = std::make_unique(compound_parent); // If a parameter list is allowed here, try to parse one if (parameters_allowed) { @@ -5361,20 +5746,9 @@ class parser ) ) { - if ( - ( - is_literal(curr().type()) - || curr().type() == lexeme::Identifier - ) - && peek(1) && peek(1)->type() == lexeme::Semicolon - ) { - error("unused literal or identifier"); - return {}; - } - // Only inside a compound-statement, a // contained statement() may have parameters - auto s = statement(true, source_position{}, true); + auto s = statement(true, source_position{}, true, n.get()); if (!s) { pos = start_pos; // backtrack return {}; @@ -5869,7 +6243,7 @@ class parser //G meta-functions-list '@' id-expression //G //G requires-clause: - //G 'requires' expression + //G 'requires' logical-or-expression //G //G template-parameter-declaration-list //G '<' parameter-declaration-seq '>' @@ -5892,6 +6266,22 @@ class parser n->identifier = std::move(id); n->access = access; + // If we're in a type scope and the next token is ';', treat this as if + // ': _;' without an initializer. + // This is for type metafunctions that want to use the incomplete name-only + // declaration, and transform it to something else. If unchanged the + // incomplete declaration will be rejected later by sema.check rule. + if ( + n->parent_is_type() + && curr().type() == lexeme::Semicolon + ) + { + n->type = std::make_unique(); + assert (n->is_object()); + next(); + return n; + } + // For a template parameter, ':' is not required and // we default to ': type' if ( @@ -6102,11 +6492,6 @@ class parser // Or nothing, declaring an object of deduced type, // which we'll represent using an empty type-id else { - if (n->parent_is_type()) { - error("a type scope variable must have a declared type"); - return {}; - } - n->type = std::make_unique(); assert (n->is_object()); deduced_type = true; @@ -6116,7 +6501,7 @@ class parser if (curr() == "requires") { n->requires_pos = curr().position(); next(); - auto e = expression(); + auto e = logical_or_expression(); if (!e) { error("'requires' must be followed by an expression"); return {}; @@ -6129,11 +6514,6 @@ class parser // If there is no = if (!done() && curr().type() != lexeme::Assignment) { - if (deduced_type) { - error("a variable with a deduced type must have an = initializer"); - return {}; - } - if ( n->is_type() && !is_template_parameter @@ -6229,72 +6609,6 @@ class parser } } - // If this is an object with an initializer, the initializer must be an expression - if ( - n->is_object() - && n->initializer - && !n->initializer->is_expression() - ) - { - error( - "an object initializer must be an expression", - false, - {}, - true - ); - return {}; - } - - // If this is a user-defined type with an initializer, the initializer must be a compound expression - if ( - n->is_type() - && n->initializer - && !n->initializer->is_compound() - ) - { - error( - "a user-defined type initializer must be a compound-expression consisting of declarations", - false, - {}, - true - ); - return {}; - } - - // If this is a namespace, it must have an initializer, which must be a compound expression - if ( - n->is_namespace() - && ( - !n->initializer - || !n->initializer->is_compound() - ) - ) - { - error( - "a namespace must be = initialized with a { } body containing declarations", - false, - n->initializer->position(), - true - ); - return {}; - } - - // If this is a function, its body must be an expression-statement or - // a compound-statement - if ( - n->is_function() - && n->initializer - && n->initializer->is_return() - ) - { - error( - "a function with a single-expression body doesn't need to say 'return' - either omit 'return' or write a full { }-enclosed function body", - false, - n->initializer->position() - ); - return {}; - } - if ( n->is_function() && n->initializer @@ -6310,24 +6624,6 @@ class parser } } - // If this is an implicit constructor, it must have two parameters - if (n->is_constructor()) - { - auto& params = std::get(n->type)->parameters; - assert(params->ssize() > 0); - if ( - params->parameters[0]->is_implicit() - && params->ssize() > 2 - ) - { - error( - "an 'implicit' constructor must have exactly one additional parameter besides 'this'", - false, - params->parameters[2]->position() - ); - } - } - // If this is a function with a list of multiple/named return values, // and the function body's end doesn't already have "return" as the // last statement, then generate "return;" as the last statement diff --git a/source/reflect.h b/source/reflect.h index c9e6ef9429..5193c73a67 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -23,16 +23,16 @@ class declaration_base; #line 165 "reflect.h2" class declaration; -#line 221 "reflect.h2" +#line 228 "reflect.h2" class function_declaration; -#line 276 "reflect.h2" +#line 285 "reflect.h2" class object_declaration; -#line 302 "reflect.h2" +#line 321 "reflect.h2" class type_declaration; -#line 698 "reflect.h2" +#line 722 "reflect.h2" } } @@ -167,6 +167,10 @@ class declaration public: [[nodiscard]] auto is_private() const -> bool; public: [[nodiscard]] auto is_default_access() const -> bool; + public: auto default_to_public() -> void; + public: auto default_to_protected() -> void; + public: auto default_to_private() -> void; + public: [[nodiscard]] auto make_public() -> bool; public: [[nodiscard]] auto make_protected() -> bool; public: [[nodiscard]] auto make_private() -> bool; @@ -177,7 +181,7 @@ class declaration public: [[nodiscard]] auto name() const -> std::string_view; -#line 195 "reflect.h2" +#line 199 "reflect.h2" public: [[nodiscard]] auto has_initializer() const -> bool; public: [[nodiscard]] auto is_global() const -> bool; @@ -199,26 +203,29 @@ class declaration public: [[nodiscard]] auto parent_is_alias() const -> bool; public: [[nodiscard]] auto parent_is_polymorphic() const -> bool; + public: auto make_constexpr() -> void; + public: auto make_static() -> void; + public: virtual ~declaration() noexcept; public: declaration(declaration const& that); -#line 215 "reflect.h2" +#line 222 "reflect.h2" }; -#line 218 "reflect.h2" +#line 225 "reflect.h2" //----------------------------------------------------------------------- // Function declarations // class function_declaration : public declaration { -#line 225 "reflect.h2" +#line 232 "reflect.h2" public: function_declaration( declaration_node* n_, cpp2::in s ); -#line 235 "reflect.h2" +#line 242 "reflect.h2" public: [[nodiscard]] auto index_of_parameter_named(cpp2::in s) const -> int; public: [[nodiscard]] auto has_parameter_named(cpp2::in s) const -> bool; public: [[nodiscard]] auto has_in_parameter_named(cpp2::in s) const -> bool; @@ -253,53 +260,59 @@ class function_declaration public: [[nodiscard]] auto is_binary_comparison_function() const -> bool; + public: auto default_to_virtual() -> void; + public: [[nodiscard]] auto make_virtual() -> bool; public: function_declaration(function_declaration const& that); -#line 270 "reflect.h2" +#line 279 "reflect.h2" }; -#line 273 "reflect.h2" +#line 282 "reflect.h2" //----------------------------------------------------------------------- // Object declarations // class object_declaration : public declaration { -#line 280 "reflect.h2" +#line 289 "reflect.h2" public: object_declaration( declaration_node* n_, cpp2::in s ); -#line 290 "reflect.h2" +#line 299 "reflect.h2" public: [[nodiscard]] auto is_const() const -> bool; - public: [[nodiscard]] auto has_wildcard_type() const -> bool; -public: object_declaration(object_declaration const& that); + public: [[nodiscard]] auto type() const -> std::string; + + +#line 309 "reflect.h2" + public: [[nodiscard]] auto initializer() const -> std::string; + + public: object_declaration(object_declaration const& that); - // TODO: auto get_type() const -> -#line 296 "reflect.h2" +#line 315 "reflect.h2" }; -#line 299 "reflect.h2" +#line 318 "reflect.h2" //----------------------------------------------------------------------- // Type declarations // class type_declaration : public declaration { -#line 306 "reflect.h2" +#line 325 "reflect.h2" public: type_declaration( declaration_node* n_, cpp2::in s ); -#line 316 "reflect.h2" +#line 335 "reflect.h2" public: [[nodiscard]] auto is_polymorphic() const -> bool; public: [[nodiscard]] auto is_final() const -> bool; public: [[nodiscard]] auto make_final() -> bool; @@ -307,34 +320,38 @@ class type_declaration public: [[nodiscard]] auto get_member_functions() const -> std::vector; -#line 330 "reflect.h2" +#line 349 "reflect.h2" public: [[nodiscard]] auto get_member_objects() const -> std::vector; -#line 340 "reflect.h2" +#line 359 "reflect.h2" public: [[nodiscard]] auto get_member_types() const -> std::vector; -#line 350 "reflect.h2" +#line 369 "reflect.h2" public: [[nodiscard]] auto get_members() const -> std::vector; struct query_declared_that_functions__ret { bool out_this_in_that; bool out_this_move_that; bool inout_this_in_that; bool inout_this_move_that; }; -#line 360 "reflect.h2" +#line 379 "reflect.h2" public: [[nodiscard]] auto query_declared_that_functions() const -> query_declared_that_functions__ret; -#line 375 "reflect.h2" +#line 394 "reflect.h2" public: [[nodiscard]] auto add_member(cpp2::in source) -> bool; - public: type_declaration(type_declaration const& that); +#line 404 "reflect.h2" + public: auto remove_all_members() -> void; + + public: auto disable_member_function_generation() -> void; -#line 384 "reflect.h2" +public: type_declaration(type_declaration const& that); +#line 407 "reflect.h2" }; -#line 387 "reflect.h2" +#line 410 "reflect.h2" //----------------------------------------------------------------------- // // Metafunctions - these are hardwired for now until we get to the @@ -349,7 +366,7 @@ class type_declaration // auto add_virtual_destructor(meta::type_declaration& t) -> void; -#line 406 "reflect.h2" +#line 429 "reflect.h2" //----------------------------------------------------------------------- // // "... an abstract base class defines an interface ..." @@ -364,7 +381,7 @@ auto add_virtual_destructor(meta::type_declaration& t) -> void; // auto interface(meta::type_declaration& t) -> void; -#line 445 "reflect.h2" +#line 468 "reflect.h2" //----------------------------------------------------------------------- // // "C.35: A base class destructor should be either public and @@ -386,7 +403,7 @@ auto interface(meta::type_declaration& t) -> void; // auto polymorphic_base(meta::type_declaration& t) -> void; -#line 489 "reflect.h2" +#line 512 "reflect.h2" //----------------------------------------------------------------------- // // "... A totally ordered type ... requires operator<=> that @@ -412,7 +429,7 @@ auto ordered_impl( cpp2::in ordering// must be "strong_ordering" etc. ) -> void; -#line 534 "reflect.h2" +#line 557 "reflect.h2" //----------------------------------------------------------------------- // ordered - a totally ordered type // @@ -420,19 +437,19 @@ auto ordered_impl( // auto ordered(meta::type_declaration& t) -> void; -#line 544 "reflect.h2" +#line 567 "reflect.h2" //----------------------------------------------------------------------- // weakly_ordered - a weakly ordered type // auto weakly_ordered(meta::type_declaration& t) -> void; -#line 552 "reflect.h2" +#line 575 "reflect.h2" //----------------------------------------------------------------------- // partially_ordered - a partially ordered type // auto partially_ordered(meta::type_declaration& t) -> void; -#line 561 "reflect.h2" +#line 584 "reflect.h2" //----------------------------------------------------------------------- // // "A value is ... a regular type. It must have all public @@ -451,7 +468,7 @@ auto partially_ordered(meta::type_declaration& t) -> void; // auto copyable(meta::type_declaration& t) -> void; -#line 599 "reflect.h2" +#line 622 "reflect.h2" //----------------------------------------------------------------------- // // basic_value @@ -461,10 +478,11 @@ auto copyable(meta::type_declaration& t) -> void; // auto basic_value(meta::type_declaration& t) -> void; -#line 625 "reflect.h2" +#line 648 "reflect.h2" //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." +// // -- P0707R4, section 3 // // value - a value type that is totally ordered @@ -473,13 +491,13 @@ auto basic_value(meta::type_declaration& t) -> void; // auto value(meta::type_declaration& t) -> void; -#line 640 "reflect.h2" +#line 664 "reflect.h2" auto weakly_ordered_value(meta::type_declaration& t) -> void; -#line 646 "reflect.h2" +#line 670 "reflect.h2" auto partially_ordered_value(meta::type_declaration& t) -> void; -#line 653 "reflect.h2" +#line 677 "reflect.h2" //----------------------------------------------------------------------- // // "By definition, a `struct` is a `class` in which members @@ -501,13 +519,13 @@ auto partially_ordered_value(meta::type_declaration& t) -> void; // // struct // -// a basic_value with only public bases, objects, and functions, +// a type with only public bases, objects, and functions, // no virtual functions, and no user-defined constructors // (i.e., no invariants) or assignment or destructors. // auto cpp2_struct(meta::type_declaration& t) -> void; -#line 696 "reflect.h2" +#line 720 "reflect.h2" //======================================================================= // Switch to Cpp1 and close subnamespace meta } @@ -619,7 +637,7 @@ namespace meta { auto lines {&CPP2_UFCS_0(back, generated_lines)}; auto add_line {[&, _1 = lines](cpp2::in s) -> void{ - CPP2_UFCS(emplace_back, (*cpp2::assert_not_null(_1)), s, source_line::category::cpp2); + (void) CPP2_UFCS(emplace_back, (*cpp2::assert_not_null(_1)), s, source_line::category::cpp2); }}; { auto newline_pos = CPP2_UFCS(find, source, '\n'); @@ -648,7 +666,7 @@ auto newline_pos = CPP2_UFCS(find, source, '\n'); // Now lex this source fragment to generate // a single grammar_map entry, whose .second // is the vector of tokens - CPP2_UFCS(emplace_back, generated_lexers, *cpp2::assert_not_null(errors)); + (void) CPP2_UFCS(emplace_back, generated_lexers, *cpp2::assert_not_null(errors)); auto tokens {&CPP2_UFCS_0(back, generated_lexers)}; CPP2_UFCS(lex, (*cpp2::assert_not_null(tokens)), *cpp2::assert_not_null(std::move(lines)), true); @@ -685,7 +703,7 @@ auto newline_pos = CPP2_UFCS(find, source, '\n'); if (!(CPP2_UFCS_0(empty, meta_function_name))) { message = "while applying @" + meta_function_name + " - " + message; } - CPP2_UFCS(emplace_back, (*cpp2::assert_not_null(errors)), position(), std::move(message)); + (void) CPP2_UFCS(emplace_back, (*cpp2::assert_not_null(errors)), position(), std::move(message)); } compiler_services::~compiler_services() noexcept{} @@ -735,6 +753,10 @@ declaration_base::declaration_base(declaration_base const& that) [[nodiscard]] auto declaration::is_private() const -> bool { return CPP2_UFCS_0(is_private, (*cpp2::assert_not_null(n))); } [[nodiscard]] auto declaration::is_default_access() const -> bool { return CPP2_UFCS_0(is_default_access, (*cpp2::assert_not_null(n))); } + auto declaration::default_to_public() -> void { (void) CPP2_UFCS_0(make_public, (*cpp2::assert_not_null(n))); } + auto declaration::default_to_protected() -> void { (void) CPP2_UFCS_0(make_protected, (*cpp2::assert_not_null(n))); } + auto declaration::default_to_private() -> void { (void) CPP2_UFCS_0(make_private, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto declaration::make_public() -> bool { return CPP2_UFCS_0(make_public, (*cpp2::assert_not_null(n))); } [[nodiscard]] auto declaration::make_protected() -> bool { return CPP2_UFCS_0(make_protected, (*cpp2::assert_not_null(n))); } [[nodiscard]] auto declaration::make_private() -> bool { return CPP2_UFCS_0(make_private, (*cpp2::assert_not_null(n))); } @@ -768,18 +790,21 @@ declaration_base::declaration_base(declaration_base const& that) [[nodiscard]] auto declaration::parent_is_alias() const -> bool { return CPP2_UFCS_0(parent_is_alias, (*cpp2::assert_not_null(n))); } [[nodiscard]] auto declaration::parent_is_polymorphic() const -> bool { return CPP2_UFCS_0(parent_is_polymorphic, (*cpp2::assert_not_null(n))); } + auto declaration::make_constexpr() -> void { CPP2_UFCS_0(make_constexpr, (*cpp2::assert_not_null(n))); } + auto declaration::make_static() -> void { CPP2_UFCS_0(make_static, (*cpp2::assert_not_null(n))); } + declaration::~declaration() noexcept{} declaration::declaration(declaration const& that) : declaration_base{ that }{} -#line 225 "reflect.h2" +#line 232 "reflect.h2" function_declaration::function_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 230 "reflect.h2" +#line 237 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS_0(is_function, (*cpp2::assert_not_null(n))), ""); @@ -819,39 +844,54 @@ declaration::declaration(declaration const& that) [[nodiscard]] auto function_declaration::is_binary_comparison_function() const -> bool { return CPP2_UFCS_0(is_binary_comparison_function, (*cpp2::assert_not_null(n))); } + auto function_declaration::default_to_virtual() -> void { (void) CPP2_UFCS_0(make_function_virtual, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto function_declaration::make_virtual() -> bool { return CPP2_UFCS_0(make_function_virtual, (*cpp2::assert_not_null(n))); } function_declaration::function_declaration(function_declaration const& that) : declaration{ that }{} -#line 280 "reflect.h2" +#line 289 "reflect.h2" object_declaration::object_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 285 "reflect.h2" +#line 294 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS_0(is_object, (*cpp2::assert_not_null(n))), ""); } - [[nodiscard]] auto object_declaration::is_const() const -> bool { return CPP2_UFCS_0(is_const, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto object_declaration::is_const() const -> bool { return CPP2_UFCS_0(is_const, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto object_declaration::has_wildcard_type() const -> bool { return CPP2_UFCS_0(has_wildcard_type, (*cpp2::assert_not_null(n))); } + + [[nodiscard]] auto object_declaration::type() const -> std::string{ + auto ret {CPP2_UFCS_0(object_type, (*cpp2::assert_not_null(n)))}; + require(!(contains(ret, "(*ERROR*)")), + "cannot to_string this type: " + ret); + return ret; + } - [[nodiscard]] auto object_declaration::has_wildcard_type() const -> bool { return CPP2_UFCS_0(has_wildcard_type, (*cpp2::assert_not_null(n))); } + [[nodiscard]] auto object_declaration::initializer() const -> std::string{ + auto ret {CPP2_UFCS_0(object_initializer, (*cpp2::assert_not_null(n)))}; + require(!(contains(ret, "(*ERROR*)")), + "cannot to_string this initializer: " + ret); + return ret; + } object_declaration::object_declaration(object_declaration const& that) : declaration{ that }{} -#line 306 "reflect.h2" +#line 325 "reflect.h2" type_declaration::type_declaration( declaration_node* n_, cpp2::in s ) : declaration{ n_, s } -#line 311 "reflect.h2" +#line 330 "reflect.h2" { cpp2::Default.expects(CPP2_UFCS_0(is_type, (*cpp2::assert_not_null(n))), ""); @@ -866,7 +906,7 @@ declaration::declaration(declaration const& that) { std::vector ret {}; for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::functions) ) { - CPP2_UFCS(emplace_back, ret, d, (*this)); + (void) CPP2_UFCS(emplace_back, ret, d, (*this)); } return ret; } @@ -876,7 +916,7 @@ declaration::declaration(declaration const& that) { std::vector ret {}; for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::objects) ) { - CPP2_UFCS(emplace_back, ret, d, (*this)); + (void) CPP2_UFCS(emplace_back, ret, d, (*this)); } return ret; } @@ -886,7 +926,7 @@ declaration::declaration(declaration const& that) { std::vector ret {}; for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::types) ) { - CPP2_UFCS(emplace_back, ret, d, (*this)); + (void) CPP2_UFCS(emplace_back, ret, d, (*this)); } return ret; } @@ -896,20 +936,20 @@ declaration::declaration(declaration const& that) { std::vector ret {}; for ( auto const& d : CPP2_UFCS(get_type_scope_declarations, (*cpp2::assert_not_null(n)), declaration_node::all) ) { - CPP2_UFCS(emplace_back, ret, d, (*this)); + (void) CPP2_UFCS(emplace_back, ret, d, (*this)); } return ret; } [[nodiscard]] auto type_declaration::query_declared_that_functions() const -> query_declared_that_functions__ret -#line 367 "reflect.h2" +#line 386 "reflect.h2" { cpp2::deferred_init out_this_in_that; cpp2::deferred_init out_this_move_that; cpp2::deferred_init inout_this_in_that; cpp2::deferred_init inout_this_move_that; -#line 368 "reflect.h2" +#line 387 "reflect.h2" auto declared {CPP2_UFCS_0(find_declared_that_functions, (*cpp2::assert_not_null(n)))}; out_this_in_that.construct(declared.out_this_in_that != nullptr); out_this_move_that.construct(declared.out_this_move_that!=nullptr); @@ -927,17 +967,21 @@ declaration::declaration(declaration const& that) return false; } + auto type_declaration::remove_all_members() -> void { CPP2_UFCS_0(type_remove_all_members, (*cpp2::assert_not_null(n))); } + + auto type_declaration::disable_member_function_generation() -> void { CPP2_UFCS_0(type_disable_member_function_generation, (*cpp2::assert_not_null(n))); } + type_declaration::type_declaration(type_declaration const& that) : declaration{ that }{} -#line 399 "reflect.h2" +#line 422 "reflect.h2" auto add_virtual_destructor(meta::type_declaration& t) -> void { CPP2_UFCS(require, t, CPP2_UFCS(add_member, t, "operator=: (virtual move this) = { }"), "could not add virtual destructor"); } -#line 418 "reflect.h2" +#line 441 "reflect.h2" auto interface(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -954,7 +998,7 @@ auto interface(meta::type_declaration& t) -> void "interface functions must not have a function body; remove the '=' initializer"); CPP2_UFCS(require, mf, CPP2_UFCS_0(make_public, mf), "interface functions must be public"); - CPP2_UFCS_0(make_virtual, mf); + CPP2_UFCS_0(default_to_virtual, mf); has_dtor |= CPP2_UFCS_0(is_destructor, mf); } } @@ -964,7 +1008,7 @@ auto interface(meta::type_declaration& t) -> void } } -#line 464 "reflect.h2" +#line 487 "reflect.h2" auto polymorphic_base(meta::type_declaration& t) -> void { auto has_dtor {false}; @@ -972,7 +1016,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void for ( auto& mf : CPP2_UFCS_0(get_member_functions, t) ) { if (CPP2_UFCS_0(is_default_access, mf)) { - CPP2_UFCS_0(make_public, mf); + CPP2_UFCS_0(default_to_public, mf); } CPP2_UFCS(require, mf, !(CPP2_UFCS_0(is_copy_or_move, mf)), "polymorphic base types may not copy or move; consider a virtual clone() instead"); @@ -989,7 +1033,7 @@ auto polymorphic_base(meta::type_declaration& t) -> void } } -#line 509 "reflect.h2" +#line 532 "reflect.h2" auto ordered_impl( meta::type_declaration& t, cpp2::in ordering @@ -1015,25 +1059,25 @@ auto ordered_impl( } } -#line 539 "reflect.h2" +#line 562 "reflect.h2" auto ordered(meta::type_declaration& t) -> void { ordered_impl(t, "strong_ordering"); } -#line 547 "reflect.h2" +#line 570 "reflect.h2" auto weakly_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "weak_ordering"); } -#line 555 "reflect.h2" +#line 578 "reflect.h2" auto partially_ordered(meta::type_declaration& t) -> void { ordered_impl(t, "partial_ordering"); } -#line 577 "reflect.h2" +#line 600 "reflect.h2" auto copyable(meta::type_declaration& t) -> void { // If the user explicitly wrote any of the copy/move functions, @@ -1056,7 +1100,7 @@ auto copyable(meta::type_declaration& t) -> void }} } -#line 606 "reflect.h2" +#line 629 "reflect.h2" auto basic_value(meta::type_declaration& t) -> void { copyable(t); @@ -1076,7 +1120,7 @@ auto basic_value(meta::type_declaration& t) -> void } } -#line 634 "reflect.h2" +#line 658 "reflect.h2" auto value(meta::type_declaration& t) -> void { ordered(t); @@ -1095,7 +1139,7 @@ auto partially_ordered_value(meta::type_declaration& t) -> void basic_value(t); } -#line 678 "reflect.h2" +#line 702 "reflect.h2" auto cpp2_struct(meta::type_declaration& t) -> void { for ( auto& m : CPP2_UFCS_0(get_members, t) ) @@ -1110,10 +1154,10 @@ auto cpp2_struct(meta::type_declaration& t) -> void "a struct may not have a user-defined operator="); } } - basic_value(t); // a plain_struct is-a basic_value + CPP2_UFCS_0(disable_member_function_generation, t); } -#line 698 "reflect.h2" +#line 722 "reflect.h2" } } diff --git a/source/reflect.h2 b/source/reflect.h2 index 6a6c64aa16..7647e0996a 100644 --- a/source/reflect.h2 +++ b/source/reflect.h2 @@ -63,7 +63,7 @@ compiler_services: @polymorphic_base @copyable type = lines := generated_lines.back()&; add_line := :(s: std::string_view) = { - lines$*.emplace_back( s, source_line::category::cpp2 ); + _ = lines$*.emplace_back( s, source_line::category::cpp2 ); }; // First split this string into source_lines @@ -87,7 +87,7 @@ compiler_services: @polymorphic_base @copyable type = // Now lex this source fragment to generate // a single grammar_map entry, whose .second // is the vector of tokens - generated_lexers.emplace_back( errors* ); + _ = generated_lexers.emplace_back( errors* ); tokens := generated_lexers.back()&; tokens*.lex( lines*, true ); @@ -124,7 +124,7 @@ compiler_services: @polymorphic_base @copyable type = if !meta_function_name.empty() { message = "while applying @" + meta_function_name + " - " + message; } - errors*.emplace_back( position(), message); + _ = errors*.emplace_back( position(), message); } } @@ -180,6 +180,10 @@ declaration: @polymorphic_base @copyable type = is_private : (this) -> bool = n*.is_private(); is_default_access: (this) -> bool = n*.is_default_access(); + default_to_public : (inout this) = _ = n*.make_public(); + default_to_protected: (inout this) = _ = n*.make_protected(); + default_to_private : (inout this) = _ = n*.make_private(); + make_public : (inout this) -> bool = n*.make_public(); make_protected : (inout this) -> bool = n*.make_protected(); make_private : (inout this) -> bool = n*.make_private(); @@ -212,6 +216,9 @@ declaration: @polymorphic_base @copyable type = parent_is_namespace : (this) -> bool = n*.parent_is_namespace(); parent_is_alias : (this) -> bool = n*.parent_is_alias(); parent_is_polymorphic: (this) -> bool = n*.parent_is_polymorphic(); + + make_constexpr : (inout this) = n*.make_constexpr(); + make_static : (inout this) = n*.make_static(); } @@ -266,6 +273,8 @@ function_declaration: @copyable type = is_binary_comparison_function: (this) -> bool = n*.is_binary_comparison_function(); + default_to_virtual : (inout this) = _ = n*.make_function_virtual(); + make_virtual : (inout this) -> bool = n*.make_function_virtual(); } @@ -287,12 +296,22 @@ object_declaration: @copyable type = [[assert: n*.is_object()]] } - is_const: (this)->bool = n*.is_const(); + is_const : (this) -> bool = n*.is_const(); + has_wildcard_type: (this) -> bool = n*.has_wildcard_type(); - has_wildcard_type: (this)->bool = n*.has_wildcard_type(); - - // TODO: auto get_type() const -> + type: (this) -> std::string = { + ret := n*.object_type(); + require( !contains(ret, "(*ERROR*)"), + "cannot to_string this type: " + ret); + return ret; + } + initializer: (this) -> std::string = { + ret := n*.object_initializer(); + require( !contains(ret, "(*ERROR*)"), + "cannot to_string this initializer: " + ret); + return ret; + } } @@ -322,7 +341,7 @@ type_declaration: @copyable type = = { ret: std::vector = (); for n*.get_type_scope_declarations(declaration_node::functions) do (d) { - ret.emplace_back( d, this ); + _ = ret.emplace_back( d, this ); } return ret; } @@ -332,7 +351,7 @@ type_declaration: @copyable type = = { ret: std::vector = (); for n*.get_type_scope_declarations(declaration_node::objects) do (d) { - ret.emplace_back( d, this ); + _ = ret.emplace_back( d, this ); } return ret; } @@ -342,7 +361,7 @@ type_declaration: @copyable type = = { ret: std::vector = (); for n*.get_type_scope_declarations(declaration_node::types) do (d) { - ret.emplace_back( d, this ); + _ = ret.emplace_back( d, this ); } return ret; } @@ -352,7 +371,7 @@ type_declaration: @copyable type = = { ret: std::vector = (); for n*.get_type_scope_declarations(declaration_node::all) do (d) { - ret.emplace_back( d, this ); + _ = ret.emplace_back( d, this ); } return ret; } @@ -372,7 +391,7 @@ type_declaration: @copyable type = inout_this_move_that = declared.inout_this_move_that != nullptr; } - add_member: ( inout this, source: std::string_view ) + add_member: (inout this, source: std::string_view) -> bool = { decl := parse_statement(source); @@ -381,6 +400,10 @@ type_declaration: @copyable type = } return false; } + + remove_all_members: (inout this) = n*.type_remove_all_members(); + + disable_member_function_generation: (inout this) = n*.type_disable_member_function_generation(); } @@ -431,7 +454,7 @@ interface: (inout t: meta::type_declaration) = "interface functions must not have a function body; remove the '=' initializer"); mf.require( mf.make_public(), "interface functions must be public"); - mf.make_virtual(); + mf.default_to_virtual(); has_dtor |= mf.is_destructor(); } } @@ -468,7 +491,7 @@ polymorphic_base: (inout t: meta::type_declaration) = for t.get_member_functions() do (inout mf) { if mf.is_default_access() { - mf.make_public(); + mf.default_to_public(); } mf.require( !mf.is_copy_or_move(), "polymorphic base types may not copy or move; consider a virtual clone() instead"); @@ -625,6 +648,7 @@ basic_value: (inout t: meta::type_declaration) = //----------------------------------------------------------------------- // // "A 'value' is a totally ordered basic_value..." +// // -- P0707R4, section 3 // // value - a value type that is totally ordered @@ -671,7 +695,7 @@ partially_ordered_value: (inout t: meta::type_declaration) = // // struct // -// a basic_value with only public bases, objects, and functions, +// a type with only public bases, objects, and functions, // no virtual functions, and no user-defined constructors // (i.e., no invariants) or assignment or destructors. // @@ -689,7 +713,7 @@ struct: (inout t: meta::type_declaration) = "a struct may not have a user-defined operator="); } } - basic_value(t); // a plain_struct is-a basic_value + t.disable_member_function_generation(); } diff --git a/source/sema.h b/source/sema.h index e69273f299..cfaf589582 100644 --- a/source/sema.h +++ b/source/sema.h @@ -983,8 +983,97 @@ class sema auto check(declaration_node const& n) -> bool { - // If this is a nonvirtual and nondefaultable function, - // it must have an initializer + // An object of deduced type must have an initializer + if ( + n.is_object() + && n.has_wildcard_type() + && !n.has_initializer() + ) + { + errors.emplace_back( + n.position(), + "an object with a deduced type must have an = initializer" + ); + return false; + } + + // An object initializer must be an expression + if ( + n.is_object() + && n.initializer + && !n.initializer->is_expression() + ) + { + errors.emplace_back( + n.position(), + "an object initializer must be an expression" + ); + return false; + } + + // A type initializer must be a compound expression + if ( + n.is_type() + && n.initializer + && !n.initializer->is_compound() + ) + { + errors.emplace_back( + n.position(), + "a user-defined type initializer must be a compound-expression consisting of declarations" + ); + return false; + } + + // A namespace must be initialized with a compound expression + if ( + n.is_namespace() + && ( + !n.initializer + || !n.initializer->is_compound() + ) + ) + { + errors.emplace_back( + n.position(), + "a namespace must be = initialized with a { } body containing declarations" + ); + return false; + } + + // A function body must be an expression-statement or a compound-statement + if ( + n.is_function() + && n.initializer + && n.initializer->is_return() + ) + { + errors.emplace_back( + n.position(), + "a function with a single-expression body doesn't need to say 'return' - either omit 'return' or write a full { }-enclosed function body" + ); + return false; + } + + // An implicit constructor must have two parameters + if (n.is_constructor()) + { + auto& params = std::get(n.type)->parameters; + assert(params->ssize() > 0); + if ( + params->parameters[0]->is_implicit() + && params->ssize() > 2 + ) + { + errors.emplace_back( + n.position(), + "an 'implicit' constructor must have at most one additional parameter besides 'this'" + ); + return false; + } + } + + // A nonvirtual and nondefaultable function must have an initializer if ( n.is_function() && !n.is_virtual_function() @@ -999,6 +1088,32 @@ class sema return false; } + if ( + n.is_type() + && !n.parent_is_namespace() + && !n.parent_is_type() + ) + { + errors.emplace_back( + n.position(), + "(temporary alpha limitation) a type must be in a namespace or type scope - function-local types are not yet supported" + ); + return false; + } + + // A type scope variable must have a declared type + if ( + n.parent_is_type() + && n.has_wildcard_type() + ) + { + errors.emplace_back( + n.position(), + "a type scope variable must have a declared type" + ); + return false; + } + { auto this_index = n.index_of_parameter_named("this"); auto that_index = n.index_of_parameter_named("that"); @@ -1290,6 +1405,44 @@ class sema } } + if (n.is_type()) { + auto compound_stmt = n.initializer->get_if(); + assert (compound_stmt); + for (auto& stmt : compound_stmt->statements) { + if (!stmt->is_declaration()) { + errors.emplace_back( + stmt->position(), + "a user-defined type body must contain only declarations, not other code" + ); + return false; + } + } + } + + return true; + } + + + auto check(statement_node const& n) + -> bool + { + if (auto expr_stmt = n.get_if(); + expr_stmt + && n.compound_parent + && ( + expr_stmt->expr->is_identifier() + || expr_stmt->expr->is_id_expression() + || expr_stmt->expr->is_literal() + ) + ) + { + errors.emplace_back( + n.position(), + "unused literal or identifier" + ); + return false; + } + return true; }