On Mon, Oct 13, 2025 at 5:59 AM Yangyu Chen <[email protected]> wrote:
>
> Ping.

My comment still stands and Jason seems to agree.

Richard.

> Thanks,
> Yangyu Chen
>
> > On 2 Oct 2025, at 17:19, Yangyu Chen <[email protected]> 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.
> >
> > 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 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 031da863860..2e04c32b51c 100644
> > --- a/gcc/config/aarch64/aarch64.cc
> > +++ b/gcc/config/aarch64/aarch64.cc
> > @@ -21120,7 +21120,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");
> >
> >       fn_ver_vec.safe_push (versn->decl);
> > diff --git a/gcc/config/i386/i386-features.cc 
> > b/gcc/config/i386/i386-features.cc
> > index c313fb85f9b..705407114f0 100644
> > --- a/gcc/config/i386/i386-features.cc
> > +++ b/gcc/config/i386/i386-features.cc
> > @@ -5559,7 +5559,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 41ee4014c0d..bc2e9738242 100644
> > --- a/gcc/config/riscv/riscv.cc
> > +++ b/gcc/config/riscv/riscv.cc
> > @@ -14613,7 +14613,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 1049c446c40..1a30f9ad835 100644
> > --- a/gcc/config/rs6000/rs6000.cc
> > +++ b/gcc/config/rs6000/rs6000.cc
> > @@ -25646,7 +25646,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" } */
> > --
> > 2.51.0
>

Reply via email to