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)

Reply via email to