On Mon, 23 Feb 2026, Yangyu Chen wrote: > 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 also check > DECL_VIRTUAL_P in addition to DECL_VINDEX when handling virtual > functions during multiversioning.
My last comment still stands. Please replace the DECL_VINDEX entirely by a DECL_VIRTUAL_P check. Richard. > Signed-off-by: Yangyu Chen <[email protected]> > > 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. > > gcc/testsuite/ChangeLog: > > * g++.target/aarch64/virtual-lto.C: New test. > --- > Changes since v2: > - Rebase with latest master. > > v2: > https://patchwork.sourceware.org/project/gcc/patch/[email protected]/ > > Changes since v1: > - Add testcase > > v1: > https://patchwork.sourceware.org/project/gcc/patch/[email protected]/ > --- > gcc/config/aarch64/aarch64.cc | 2 +- > gcc/config/i386/i386-features.cc | 2 +- > gcc/config/riscv/riscv.cc | 2 +- > gcc/config/rs6000/rs6000.cc | 2 +- > gcc/testsuite/g++.target/aarch64/virtual-lto.C | 16 ++++++++++++++++ > 5 files changed, 20 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.target/aarch64/virtual-lto.C > > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index 00e619f26c5..10ff27a7821 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -21708,7 +21708,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) || DECL_VINDEX (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 d5435f009cb..f3e388775a0 100644 > --- a/gcc/config/i386/i386-features.cc > +++ b/gcc/config/i386/i386-features.cc > @@ -5703,7 +5703,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) || DECL_VINDEX (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 3baf0a936b5..0f82b38b02a 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -15530,7 +15530,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) || DECL_VINDEX (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 a4f60ecb58a..5f3c0ef959f 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) || DECL_VINDEX (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 00000000000..41ebdcd006d > --- /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" } */ > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
