diff --git a/easybuild/easyconfigs/g/GCCcore/GCCcore-12.1.0.eb b/easybuild/easyconfigs/g/GCCcore/GCCcore-12.1.0.eb index 4d35ae69304..bfbba25110c 100644 --- a/easybuild/easyconfigs/g/GCCcore/GCCcore-12.1.0.eb +++ b/easybuild/easyconfigs/g/GCCcore/GCCcore-12.1.0.eb @@ -34,6 +34,7 @@ patches = [ 'GCCcore-6.2.0-fix-find-isl.patch', 'GCCcore-9.3.0_gmp-c99.patch', 'GCCcore-12.1.0_allow-pragma-wself-init.patch', + 'GCCcore-12.1.0_fix-double-destruct.patch', 'GCCcore-12.1.0_fix-Wuninitialized-in-AVX-headers.patch', 'GCCcore-12.2.0_fix-avx512-misoptimization.patch', 'GCCcore-12.2.0_fix-vectorizer.patch', @@ -50,6 +51,7 @@ checksums = [ {'GCCcore-9.3.0_gmp-c99.patch': '0e135e1cc7cec701beea9d7d17a61bab34cfd496b4b555930016b98db99f922e'}, {'GCCcore-12.1.0_allow-pragma-wself-init.patch': '464f5faa9b23e805995d10dcdacca83df6321cac70826e9a3bc5bc9cd737f6a1'}, + {'GCCcore-12.1.0_fix-double-destruct.patch': '2e09c125318b6c15ec60f1807d77fb7d1f32b64a4e5d1c9a3da89ba2ca738d35'}, {'GCCcore-12.1.0_fix-Wuninitialized-in-AVX-headers.patch': '0ea675960795e238a43ae7d685a0082b21f0b63cf2fe499f6d55e89e0aaee392'}, {'GCCcore-12.2.0_fix-avx512-misoptimization.patch': diff --git a/easybuild/easyconfigs/g/GCCcore/GCCcore-12.1.0_fix-double-destruct.patch b/easybuild/easyconfigs/g/GCCcore/GCCcore-12.1.0_fix-double-destruct.patch new file mode 100644 index 00000000000..55c77a2427d --- /dev/null +++ b/easybuild/easyconfigs/g/GCCcore/GCCcore-12.1.0_fix-double-destruct.patch @@ -0,0 +1,195 @@ +Backport of upstream commit 7fae9873a74c7a5a62044bb6a4cde8e3ac1a5e5d (by Jason Merrill ) +Fixes a misoptimization in C++ where an object might get destroyed twice +when an exception is throw while it is returned. +See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112301 + +Author: Alexander Grund (TU Dresden) + +diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc +index da0a65c613d..31138ebc75f 100644 +--- a/gcc/cp/except.cc ++++ b/gcc/cp/except.cc +@@ -1355,6 +1355,14 @@ maybe_splice_retval_cleanup (tree compound_stmt) + tsi_delink (&iter); + } + tree dtor = build_cleanup (retval); ++ if (!function_body) ++ { ++ /* Clear the sentinel so we don't try to destroy the retval again on ++ rethrow (c++/112301). */ ++ tree clear = build2 (MODIFY_EXPR, boolean_type_node, ++ current_retval_sentinel, boolean_false_node); ++ dtor = build2 (COMPOUND_EXPR, void_type_node, clear, dtor); ++ } + tree cond = build3 (COND_EXPR, void_type_node, current_retval_sentinel, + dtor, void_node); + tree cleanup = build_stmt (loc, CLEANUP_STMT, +diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc +index ab48f11c9be..3520360225c 100644 +--- a/gcc/cp/semantics.cc ++++ b/gcc/cp/semantics.cc +@@ -4817,6 +4817,7 @@ public: + tree var; + tree result; + hash_table > visited; ++ bool in_nrv_cleanup; + }; + + /* Helper function for walk_tree, used by finalize_nrv below. */ +@@ -4840,7 +4841,35 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data) + thrown. */ + else if (TREE_CODE (*tp) == CLEANUP_STMT + && CLEANUP_DECL (*tp) == dp->var) +- CLEANUP_EH_ONLY (*tp) = 1; ++ { ++ dp->in_nrv_cleanup = true; ++ cp_walk_tree (&CLEANUP_BODY (*tp), finalize_nrv_r, data, 0); ++ dp->in_nrv_cleanup = false; ++ cp_walk_tree (&CLEANUP_EXPR (*tp), finalize_nrv_r, data, 0); ++ *walk_subtrees = 0; ++ ++ CLEANUP_EH_ONLY (*tp) = true; ++ ++ /* If a cleanup might throw, we need to clear current_retval_sentinel on ++ the exception path so an outer cleanup added by ++ maybe_splice_retval_cleanup doesn't run. */ ++ if (cp_function_chain->throwing_cleanup) ++ { ++ tree clear = build2 (MODIFY_EXPR, boolean_type_node, ++ current_retval_sentinel, ++ boolean_false_node); ++ ++ /* We're already only on the EH path, just prepend it. */ ++ tree &exp = CLEANUP_EXPR (*tp); ++ exp = build2 (COMPOUND_EXPR, void_type_node, clear, exp); ++ } ++ } ++ /* Disable maybe_splice_retval_cleanup within the NRV cleanup scope, we don't ++ want to destroy the retval before the variable goes out of scope. */ ++ else if (TREE_CODE (*tp) == CLEANUP_STMT ++ && dp->in_nrv_cleanup ++ && CLEANUP_DECL (*tp) == dp->result) ++ CLEANUP_EXPR (*tp) = void_node; + /* Replace the DECL_EXPR for the NRV with an initialization of the + RESULT_DECL, if needed. */ + else if (TREE_CODE (*tp) == DECL_EXPR +@@ -4896,6 +4925,7 @@ finalize_nrv (tree *tp, tree var, tree result) + + data.var = var; + data.result = result; ++ data.in_nrv_cleanup = false; + cp_walk_tree (tp, finalize_nrv_r, &data, 0); + } + +diff --git a/gcc/testsuite/g++.dg/eh/return1.C b/gcc/testsuite/g++.dg/eh/return1.C +index ac2225405da..7224b2c162e 100644 +--- a/gcc/testsuite/g++.dg/eh/return1.C ++++ b/gcc/testsuite/g++.dg/eh/return1.C +@@ -16,13 +16,14 @@ extern "C" int printf (const char *, ...); + + struct X + { +- X(bool throws) : throws_(throws) { ++c; DEBUG; } +- X(const X& x); // not defined ++ X(bool throws) : i(-42), throws_(throws) { ++c; DEBUG; } ++ X(const X& x): i(x.i), throws_(x.throws_) { ++c; DEBUG; } + ~X() THROWS + { +- ++d; DEBUG; ++ i = ++d; DEBUG; + if (throws_) { throw 1; } + } ++ int i; + private: + bool throws_; + }; +@@ -54,6 +55,75 @@ X i() + return X(false); + } + ++// c++/112301 ++X i3() ++{ ++ try { ++ X x(true); ++ return X(false); ++ } catch(...) { throw; } ++} ++ ++X i4() ++{ ++ try { ++ X x(true); ++ X x2(false); ++ return x2; ++ } catch(...) { throw; } ++} ++ ++X i4a() ++{ ++ try { ++ X x2(false); ++ X x(true); ++ return x2; ++ } catch(...) { throw; } ++} ++ ++X i4b() ++{ ++ X x(true); ++ X x2(false); ++ return x2; ++} ++ ++X i4c() ++{ ++ X x2(false); ++ X x(true); ++ return x2; ++} ++ ++X i5() ++{ ++ X x2(false); ++ ++ try { ++ X x(true); ++ return x2; ++ } catch(...) { ++ if (x2.i != -42) ++ d += 42; ++ throw; ++ } ++} ++ ++X i6() ++{ ++ X x2(false); ++ ++ try { ++ X x(true); ++ return x2; ++ } catch(...) { ++ if (x2.i != -42) ++ d += 42; ++ } ++ return x2; ++} ++ + X j() + { + try { +@@ -92,6 +162,13 @@ int main() + + try { i(); } + catch (...) {} ++ try { i3(); } catch (...) {} ++ try { i4(); } catch (...) {} ++ try { i4a(); } catch (...) {} ++ try { i4b(); } catch (...) {} ++ try { i4c(); } catch (...) {} ++ try { i5(); } catch (...) {} ++ try { i6(); } catch (...) {} + + try { j(); } catch (...) {} + diff --git a/easybuild/easyconfigs/g/GCCcore/GCCcore-12.2.0.eb b/easybuild/easyconfigs/g/GCCcore/GCCcore-12.2.0.eb index 06a43b75d9c..77c3d798705 100644 --- a/easybuild/easyconfigs/g/GCCcore/GCCcore-12.2.0.eb +++ b/easybuild/easyconfigs/g/GCCcore/GCCcore-12.2.0.eb @@ -34,6 +34,7 @@ patches = [ 'GCCcore-6.2.0-fix-find-isl.patch', 'GCCcore-9.3.0_gmp-c99.patch', 'GCCcore-12.1.0_allow-pragma-wself-init.patch', + 'GCCcore-12.1.0_fix-double-destruct.patch', 'GCCcore-12.1.0_fix-Wuninitialized-in-AVX-headers.patch', 'GCCcore-12.2.0_fix-avx512-misoptimization.patch', 'GCCcore-12.2.0_fix-vectorizer.patch', @@ -51,6 +52,7 @@ checksums = [ {'GCCcore-9.3.0_gmp-c99.patch': '0e135e1cc7cec701beea9d7d17a61bab34cfd496b4b555930016b98db99f922e'}, {'GCCcore-12.1.0_allow-pragma-wself-init.patch': '464f5faa9b23e805995d10dcdacca83df6321cac70826e9a3bc5bc9cd737f6a1'}, + {'GCCcore-12.1.0_fix-double-destruct.patch': '2e09c125318b6c15ec60f1807d77fb7d1f32b64a4e5d1c9a3da89ba2ca738d35'}, {'GCCcore-12.1.0_fix-Wuninitialized-in-AVX-headers.patch': '0ea675960795e238a43ae7d685a0082b21f0b63cf2fe499f6d55e89e0aaee392'}, {'GCCcore-12.2.0_fix-avx512-misoptimization.patch': diff --git a/easybuild/easyconfigs/g/GCCcore/GCCcore-12.3.0.eb b/easybuild/easyconfigs/g/GCCcore/GCCcore-12.3.0.eb index eb7afd9a068..91dd99aa90d 100644 --- a/easybuild/easyconfigs/g/GCCcore/GCCcore-12.3.0.eb +++ b/easybuild/easyconfigs/g/GCCcore/GCCcore-12.3.0.eb @@ -33,6 +33,7 @@ sources = [ patches = [ 'GCCcore-6.2.0-fix-find-isl.patch', 'GCCcore-9.3.0_gmp-c99.patch', + 'GCCcore-12.1.0_fix-double-destruct.patch', 'GCCcore-12.2.0_fix-avx512-misoptimization.patch', 'GCCcore-12.2.0_improve-cuda-compatibility.patch', ] @@ -46,6 +47,7 @@ checksums = [ {'nvptx-tools-20230122.tar.gz': 'af05fac26e9a83d337758a5495dc35f7a7bbfd90cd09f4a5d3242d059f235e08'}, {'GCCcore-6.2.0-fix-find-isl.patch': '5ad909606d17d851c6ad629b4fddb6c1621844218b8d139fed18c502a7696c68'}, {'GCCcore-9.3.0_gmp-c99.patch': '0e135e1cc7cec701beea9d7d17a61bab34cfd496b4b555930016b98db99f922e'}, + {'GCCcore-12.1.0_fix-double-destruct.patch': '2e09c125318b6c15ec60f1807d77fb7d1f32b64a4e5d1c9a3da89ba2ca738d35'}, {'GCCcore-12.2.0_fix-avx512-misoptimization.patch': 'bb3db707727b9975b0005346ef04230a96b3ad896f004a34262a82a244b5d436'}, {'GCCcore-12.2.0_improve-cuda-compatibility.patch': diff --git a/easybuild/easyconfigs/g/GCCcore/GCCcore-13.1.0.eb b/easybuild/easyconfigs/g/GCCcore/GCCcore-13.1.0.eb index 005f4794d63..6b8e8a19de6 100644 --- a/easybuild/easyconfigs/g/GCCcore/GCCcore-13.1.0.eb +++ b/easybuild/easyconfigs/g/GCCcore/GCCcore-13.1.0.eb @@ -33,6 +33,7 @@ sources = [ patches = [ 'GCCcore-6.2.0-fix-find-isl.patch', 'GCCcore-9.3.0_gmp-c99.patch', + 'GCCcore-12.1.0_fix-double-destruct.patch', 'GCCcore-12.2.0_fix-avx512-misoptimization.patch', ] checksums = [ @@ -45,6 +46,7 @@ checksums = [ {'nvptx-tools-20230122.tar.gz': 'af05fac26e9a83d337758a5495dc35f7a7bbfd90cd09f4a5d3242d059f235e08'}, {'GCCcore-6.2.0-fix-find-isl.patch': '5ad909606d17d851c6ad629b4fddb6c1621844218b8d139fed18c502a7696c68'}, {'GCCcore-9.3.0_gmp-c99.patch': '0e135e1cc7cec701beea9d7d17a61bab34cfd496b4b555930016b98db99f922e'}, + {'GCCcore-12.1.0_fix-double-destruct.patch': '2e09c125318b6c15ec60f1807d77fb7d1f32b64a4e5d1c9a3da89ba2ca738d35'}, {'GCCcore-12.2.0_fix-avx512-misoptimization.patch': 'bb3db707727b9975b0005346ef04230a96b3ad896f004a34262a82a244b5d436'}, ] diff --git a/easybuild/easyconfigs/g/GCCcore/GCCcore-13.2.0.eb b/easybuild/easyconfigs/g/GCCcore/GCCcore-13.2.0.eb index 3749681657f..85c2772cbfa 100644 --- a/easybuild/easyconfigs/g/GCCcore/GCCcore-13.2.0.eb +++ b/easybuild/easyconfigs/g/GCCcore/GCCcore-13.2.0.eb @@ -33,6 +33,7 @@ sources = [ patches = [ 'GCCcore-6.2.0-fix-find-isl.patch', 'GCCcore-9.3.0_gmp-c99.patch', + 'GCCcore-12.1.0_fix-double-destruct.patch', 'GCCcore-12.2.0_fix-avx512-misoptimization.patch', ] checksums = [ @@ -45,6 +46,7 @@ checksums = [ {'nvptx-tools-20230725.tar.gz': '17ce1f2c64f09c6f1cb709e3af869bb90b0102c412f25da55f338e35bc74b2e2'}, {'GCCcore-6.2.0-fix-find-isl.patch': '5ad909606d17d851c6ad629b4fddb6c1621844218b8d139fed18c502a7696c68'}, {'GCCcore-9.3.0_gmp-c99.patch': '0e135e1cc7cec701beea9d7d17a61bab34cfd496b4b555930016b98db99f922e'}, + {'GCCcore-12.1.0_fix-double-destruct.patch': '2e09c125318b6c15ec60f1807d77fb7d1f32b64a4e5d1c9a3da89ba2ca738d35'}, {'GCCcore-12.2.0_fix-avx512-misoptimization.patch': 'bb3db707727b9975b0005346ef04230a96b3ad896f004a34262a82a244b5d436'}, ]