[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