From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id 4609C3858404; Fri, 2 Sep 2022 06:06:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4609C3858404 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1662098797; bh=eksMGfmdnYT70OcDww8d1tFrzCow+yRS51eUkSsTgbA=; h=From:To:Subject:Date:From; b=Zr7Kq6/OS+uKI/RZLkl2qYYRx2Ub1049bJx1H7RbBgS2ep8B/gOGoSVpnJSTNYPDe lfxX9A/3rPGs27gRMf9jUgVIU1MeIt/8QRfaSpGtJG3mJ4AmsEV/ajSKj66+6ObD7V uLUFSHLr5RHMLdscqlw9idwntYTYUyFIw+G+s7fo= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-2360] ipa: Fix throw in multi-versioned functions [PR106627] X-Act-Checkin: gcc X-Git-Author: Simon Rainer X-Git-Refname: refs/heads/master X-Git-Oldrev: bb0a1556df79d02cf570f5eb17a1b02a509f0be4 X-Git-Newrev: 0b0a3cdbff64d97e7de3e0e2c26e965708064193 Message-Id: <20220902060637.4609C3858404@sourceware.org> Date: Fri, 2 Sep 2022 06:06:37 +0000 (GMT) List-Id: https://gcc.gnu.org/g:0b0a3cdbff64d97e7de3e0e2c26e965708064193 commit r13-2360-g0b0a3cdbff64d97e7de3e0e2c26e965708064193 Author: Simon Rainer Date: Wed Aug 31 23:00:08 2022 +0200 ipa: Fix throw in multi-versioned functions [PR106627] Any multi-versioned function was implicitly declared as noexcept, which leads to an abort if an exception is thrown inside the function. The reason for this is that the function declaration is replaced by a newly created dispatcher declaration, which has TREE_NOTHROW always set to 1. Instead we need to set TREE_NOTHROW to the value of the original declaration. PR ipa/106627 gcc/ChangeLog: * config/i386/i386-features.cc (ix86_get_function_versions_dispatcher): Set TREE_NOTHROW correctly for dispatcher declaration. * config/rs6000/rs6000.cc (rs6000_get_function_versions_dispatcher): Likewise. gcc/testsuite/ChangeLog: * g++.target/i386/pr106627.C: New test. Diff: --- gcc/config/i386/i386-features.cc | 1 + gcc/config/rs6000/rs6000.cc | 1 + gcc/testsuite/g++.target/i386/pr106627.C | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index d6bb66cbe01..fd212262f50 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -3268,6 +3268,7 @@ ix86_get_function_versions_dispatcher (void *decl) /* Right now, the dispatching is done via ifunc. */ dispatch_decl = make_dispatcher_decl (default_node->decl); + TREE_NOTHROW (dispatch_decl) = TREE_NOTHROW (fn); dispatcher_node = cgraph_node::get_create (dispatch_decl); gcc_assert (dispatcher_node != NULL); diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 2f3146e56f8..937954b6351 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -24861,6 +24861,7 @@ rs6000_get_function_versions_dispatcher (void *decl) /* Right now, the dispatching is done via ifunc. */ dispatch_decl = make_dispatcher_decl (default_node->decl); + TREE_NOTHROW (dispatch_decl) = TREE_NOTHROW (fn); dispatcher_node = cgraph_node::get_create (dispatch_decl); gcc_assert (dispatcher_node != NULL); diff --git a/gcc/testsuite/g++.target/i386/pr106627.C b/gcc/testsuite/g++.target/i386/pr106627.C new file mode 100644 index 00000000000..e993d825f20 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr106627.C @@ -0,0 +1,28 @@ +/* PR c++/103012 Exception handling with multiversioned functions */ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ + +extern "C" void abort (void); + +__attribute__((target("default"))) +void f() { + throw 1; +} + +__attribute__((target("sse4.2,bmi"))) +void f() { + throw 2; +} + +int main() +{ + try { + f(); + } + catch(...) + { + return 0; + } + + abort (); +}