From ca394fe46b6a7ffa6ee3c26cd46f30dcbc2beb94 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 14 Jan 2025 13:11:09 +0100 Subject: [PATCH] 15.0.1-0.3 --- gcc.spec | 7 +- gcc15-pr117231.patch | 177 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 gcc15-pr117231.patch diff --git a/gcc.spec b/gcc.spec index db61327..5746ff6 100644 --- a/gcc.spec +++ b/gcc.spec @@ -143,7 +143,7 @@ Summary: Various compilers (C, C++, Objective-C, ...) Name: gcc Version: %{gcc_version} -Release: %{gcc_release}.2%{?dist} +Release: %{gcc_release}.3%{?dist} # License notes for some of the less obvious ones: # gcc/doc/cppinternals.texi: Linux-man-pages-copyleft-2-para # isl: MIT, BSD-2-Clause @@ -301,6 +301,7 @@ Patch11: gcc15-d-shared-libphobos.patch Patch12: gcc15-pr118206.patch Patch13: gcc15-d-deps.patch Patch14: gcc15-pr118438.patch +Patch15: gcc15-pr117231.patch Patch50: isl-rh2155127.patch @@ -918,6 +919,7 @@ so that there cannot be any synchronization problems. %patch -P12 -p0 -b .pr118206~ %patch -P13 -p0 -b .d-deps~ %patch -P14 -p0 -b .pr118438~ +%patch -P15 -p0 -b .pr117231~ %patch -P50 -p0 -b .rh2155127~ touch -r isl-0.24/m4/ax_prog_cxx_for_build.m4 isl-0.24/m4/ax_prog_cc_for_build.m4 @@ -3677,6 +3679,9 @@ end %endif %changelog +* Tue Jan 14 2025 Jakub Jelinek 15.0.1-0.3 +- temporary fix for coroutine range for handling (PR c++/117231) + * Tue Jan 14 2025 Jakub Jelinek 15.0.1-0.2 - update from trunk - PRs ada/118459, c/116871, c++/118445, modula2/116557, target/116030, diff --git a/gcc15-pr117231.patch b/gcc15-pr117231.patch new file mode 100644 index 0000000..ad1a83a --- /dev/null +++ b/gcc15-pr117231.patch @@ -0,0 +1,177 @@ +In the current implementation, statement expressions were intentionally +unsupported (as a C++ extension). However since they are quite heavily +used by end-users and also now emitted by the compiler in some cases +we are now working to add them. This first patch ensures that we +recurse into statement expressions (and therefore handle coroutine +keywords that might appear inside them). + + PR c++/115851 + PR c++/116914 + PR c++/117231 + +gcc/cp/ChangeLog: + + * coroutines.cc (await_statement_expander): Walk into + statement expressions. + (await_statement_walker): Likewise. + +gcc/testsuite/ChangeLog: + + * g++.dg/coroutines/pr115851.C: New test. + * g++.dg/coroutines/pr116914.C: New test. + * g++.dg/coroutines/pr117231.C: New test. + +Signed-off-by: Iain Sandoe +--- + gcc/cp/coroutines.cc | 22 ++++++++++++ + gcc/testsuite/g++.dg/coroutines/pr115851.C | 35 +++++++++++++++++++ + gcc/testsuite/g++.dg/coroutines/pr116914.C | 40 ++++++++++++++++++++++ + gcc/testsuite/g++.dg/coroutines/pr117231.C | 21 ++++++++++++ + 4 files changed, 118 insertions(+) + create mode 100644 gcc/testsuite/g++.dg/coroutines/pr115851.C + create mode 100644 gcc/testsuite/g++.dg/coroutines/pr116914.C + create mode 100644 gcc/testsuite/g++.dg/coroutines/pr117231.C + +--- gcc/cp/coroutines.cc ++++ gcc/cp/coroutines.cc +@@ -2128,6 +2128,14 @@ await_statement_expander (tree *stmt, int *do_subtree, void *d) + } + else if (EXPR_P (*stmt)) + { ++ /* Look for ({}) at the top level - just recurse into these. */ ++ if (TREE_CODE (*stmt) == EXPR_STMT) ++ { ++ tree inner = EXPR_STMT_EXPR (*stmt); ++ if (TREE_CODE (inner) == STATEMENT_LIST ++ || TREE_CODE (inner) == BIND_EXPR) ++ return NULL_TREE; // process contents ++ } + process_one_statement (stmt, d); + *do_subtree = 0; /* Done subtrees. */ + } +@@ -3857,6 +3865,20 @@ await_statement_walker (tree *stmt, int *do_subtree, void *d) + if (!(cp_walk_tree (stmt, find_any_await, &await_ptr, &visited))) + return NULL_TREE; /* Nothing special to do here. */ + ++ /* Handle statement expressions. */ ++ if (TREE_CODE (expr) == EXPR_STMT) ++ { ++ tree inner = EXPR_STMT_EXPR (expr); ++ if (TREE_CODE (inner) == STATEMENT_LIST ++ || TREE_CODE (inner) == BIND_EXPR) ++ { ++ res = cp_walk_tree (&EXPR_STMT_EXPR (expr), ++ await_statement_walker, d, NULL); ++ *do_subtree = 0; ++ return res; ++ } ++ } ++ + visited.empty (); + awpts->saw_awaits = 0; + hash_set truth_aoif_to_expand; +--- gcc/testsuite/g++.dg/coroutines/pr115851.C ++++ gcc/testsuite/g++.dg/coroutines/pr115851.C +@@ -0,0 +1,35 @@ ++// { dg-additional-options "-Wno-pedantic " } ++#include ++ ++struct SuspendNever { ++ bool await_ready() noexcept; ++ void await_suspend(std::coroutine_handle<>) noexcept; ++ void await_resume() noexcept; ++}; ++ ++struct Coroutine; ++ ++struct PromiseType { ++ Coroutine get_return_object(); ++ SuspendNever initial_suspend(); ++ SuspendNever final_suspend() noexcept; ++ void unhandled_exception () {} ++}; ++ ++struct Coroutine { ++ using promise_type = PromiseType; ++}; ++ ++struct ErrorOr { ++ int release_error(); ++}; ++ ++void warnln(int const&); ++ ++Coroutine __async_test_input_basic() { ++ ({ ++ co_await SuspendNever{}; ++ ErrorOr _temporary_result2; ++ warnln(_temporary_result2.release_error()); ++ }); ++} +--- gcc/testsuite/g++.dg/coroutines/pr116914.C ++++ gcc/testsuite/g++.dg/coroutines/pr116914.C +@@ -0,0 +1,40 @@ ++// { dg-additional-options "-std=gnu++20 -fpreprocessed" } ++ ++namespace std { ++template struct coroutine_traits : a {}; ++template struct coroutine_handle { ++ static coroutine_handle from_address(void *); ++ operator coroutine_handle<>(); ++ void *address(); ++}; ++struct b { ++ int await_ready() noexcept; ++ void await_suspend(coroutine_handle<>) noexcept; ++ void await_resume() noexcept; ++}; ++} // namespace std ++struct c; ++struct d { ++ c get_return_object(); ++ std::b initial_suspend(); ++ std::b final_suspend() noexcept; ++ void unhandled_exception(); ++ std::b yield_value(int); ++}; ++struct e { ++ void operator++(); ++ int operator*(); ++ int operator!=(e); ++}; ++struct c { ++ using promise_type = d; ++ e begin(); ++ e end(); ++ c f() { ++ c g; ++ for (auto h : g) { ++ auto i = 1; ++ co_yield i; ++ } ++ } ++}; +--- gcc/testsuite/g++.dg/coroutines/pr117231.C ++++ gcc/testsuite/g++.dg/coroutines/pr117231.C +@@ -0,0 +1,21 @@ ++// { dg-additional-options "-std=c++23 " } ++// { dg-do run } ++#include ++//#include ++#include ++ ++std::generator get_seq() ++{ ++ std::vector data_{1, 2, 3}; ++ for (auto item : data_) ++ co_yield item; ++} ++ ++int main() ++{ ++ int res = 0; ++ for (auto item : get_seq()) ++ res = item; //std::println("{}", item); ++ if (res != 3) ++ __builtin_abort (); ++}