]> gcc.gnu.org Git - gcc.git/commitdiff
ipa: Fix throw in multi-versioned functions [PR106627]
authorSimon Rainer <gcc.gnu@vvalter.com>
Wed, 31 Aug 2022 21:00:08 +0000 (23:00 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 2 Sep 2022 06:06:14 +0000 (08:06 +0200)
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.

gcc/config/i386/i386-features.cc
gcc/config/rs6000/rs6000.cc
gcc/testsuite/g++.target/i386/pr106627.C [new file with mode: 0644]

index d6bb66cbe018c8aeb13c26350d335131bb5c15eb..fd212262f503d8b2dd716f0f972525b8b906aed9 100644 (file)
@@ -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);
index 2f3146e56f870204a166f7c83caa6a6fea19f4f0..937954b6351c58cd7d2f6057e18e86b0a36a2f19 100644 (file)
@@ -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 (file)
index 0000000..e993d82
--- /dev/null
@@ -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 ();
+}
This page took 0.12547 seconds and 5 git commands to generate.