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. 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. Signed-off-by: Yangyu Chen <c...@cyyself.name> --- This should also be backported to GCC stable branches. --- 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 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index fff8d9da49d..fd77e24ce12 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -20763,7 +20763,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 31f3ee2ef17..043e86ece8e 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -4421,7 +4421,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 a0657323f65..90f2cbce68e 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -13747,7 +13747,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 12dbde2bc63..0c13d524124 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -25656,7 +25656,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); -- 2.49.0