[gcc r16-8182] fmv: Check DECL_VIRTUAL_P for virtual functions for LTO handling
Richard Biener
rguenth@gcc.gnu.org
Fri Mar 20 07:16:14 GMT 2026
https://gcc.gnu.org/g:4ca1de5662a2ab4934c13982c72be01f407d8cc7
commit r16-8182-g4ca1de5662a2ab4934c13982c72be01f407d8cc7
Author: Yangyu Chen <cyy@cyyself.name>
Date: Mon Feb 23 18:27:25 2026 +0800
fmv: Check DECL_VIRTUAL_P for virtual functions for LTO handling
When building with LTO, DECL_VINDEX is not always set for virtual
functions, which allows virtual functions to be incorrectly treated as
non-virtual and then being multi-versioned, and causes errors sometimes.
This patch addresses the issue by ensuring that we check DECL_VIRTUAL_P
instead of DECL_VINDEX when handling virtual functions during
multiversioning.
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
gcc/ChangeLog:
* config/aarch64/aarch64.cc (aarch64_generate_version_dispatcher_body):
Check DECL_VIRTUAL_P for virtual functions for LTO handling.
* config/i386/i386-features.cc (ix86_generate_version_dispatcher_body):
Ditto.
* config/riscv/riscv.cc (riscv_generate_version_dispatcher_body): Ditto.
* config/rs6000/rs6000.cc (rs6000_generate_version_dispatcher_body):
Ditto.
* config/loongarch/loongarch.cc
(loongarch_generate_version_dispatcher_body): Ditto.
gcc/testsuite/ChangeLog:
* g++.target/aarch64/virtual-lto.C: New test.
Diff:
---
gcc/config/aarch64/aarch64.cc | 2 +-
gcc/config/i386/i386-features.cc | 2 +-
gcc/config/loongarch/loongarch.cc | 2 +-
gcc/config/riscv/riscv.cc | 2 +-
gcc/config/rs6000/rs6000.cc | 2 +-
gcc/testsuite/g++.target/aarch64/virtual-lto.C | 16 ++++++++++++++++
6 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index f2ecb0ee8cb7..1902a4ee9fa3 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -21722,7 +21722,7 @@ aarch64_generate_version_dispatcher_body (void *node_p)
not. This happens for methods in derived classes that override
virtual methods in base classes but are not explicitly marked as
virtual. */
- if (DECL_VINDEX (versn->decl))
+ if (DECL_VIRTUAL_P (versn->decl))
sorry ("virtual function multiversioning not supported");
if (dump_enabled_p ())
diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index e866581dc3c8..c0706c8935c6 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -5736,7 +5736,7 @@ ix86_generate_version_dispatcher_body (void *node_p)
not. This happens for methods in derived classes that override
virtual methods in base classes but are not explicitly marked as
virtual. */
- if (DECL_VINDEX (versn->decl))
+ if (DECL_VIRTUAL_P (versn->decl))
sorry ("virtual function multiversioning not supported");
fn_ver_vec.safe_push (versn->decl);
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 998cfb9a26a2..37ef30ec6d98 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -12044,7 +12044,7 @@ loongarch_generate_version_dispatcher_body (void *node_p)
not. This happens for methods in derived classes that override
virtual methods in base classes but are not explicitly marked as
virtual. */
- if (DECL_VINDEX (versn->decl))
+ if (DECL_VIRTUAL_P (versn->decl))
sorry ("virtual function multiversioning not supported");
fn_ver_vec.safe_push (versn->decl);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 282cf71ad61c..e1d885e38cc3 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -15543,7 +15543,7 @@ riscv_generate_version_dispatcher_body (void *node_p)
not. This happens for methods in derived classes that override
virtual methods in base classes but are not explicitly marked as
virtual. */
- if (DECL_VINDEX (versn->decl))
+ if (DECL_VIRTUAL_P (versn->decl))
sorry ("virtual function multiversioning not supported");
fn_ver_vec.safe_push (versn->decl);
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index a4f60ecb58a8..3838059a7e25 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -25645,7 +25645,7 @@ rs6000_generate_version_dispatcher_body (void *node_p)
not. This happens for methods in derived classes that override
virtual methods in base classes but are not explicitly marked as
virtual. */
- if (DECL_VINDEX (version->decl))
+ if (DECL_VIRTUAL_P (version->decl))
sorry ("Virtual function multiversioning not supported");
fn_ver_vec.safe_push (version->decl);
diff --git a/gcc/testsuite/g++.target/aarch64/virtual-lto.C b/gcc/testsuite/g++.target/aarch64/virtual-lto.C
new file mode 100644
index 000000000000..41ebdcd006d1
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/virtual-lto.C
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-additional-options "-flto" } */
+class foo {
+public:
+ virtual void bar () = 0;
+};
+
+class baz : public foo {
+public:
+ void bar ();
+};
+
+__attribute__((target_clones("default", "flagm")))
+void baz::bar () {
+} /* { dg-message "sorry, unimplemented: virtual function multiversioning not supported" } */
More information about the Gcc-cvs
mailing list