Hi,
as requested by Jakub, this patch makes devirtualization code to turn off
transformations based on assumption that cxa_pure_virtual will never be called
by a virtual call when -fsanitize=undefined is used.
Bootstrapped/regtested x86_64-linux, will commit it shortly.
PR ipa/66223
* ipa-devirt.c (maybe_record_node): Do not optimize cxa_pure_virtual
calls when sanitizing.
(possible_polymorphic_call_target_p)" FIx formating.
* g++.dg/ipa/devirt-51.C: New testcase.
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c (revision 234715)
+++ ipa-devirt.c (working copy)
@@ -2438,10 +2438,14 @@ maybe_record_node (vec <cgraph_node *> &
{
gcc_assert (!target_node->global.inlined_to);
gcc_assert (target_node->real_symbol_p ());
+ /* When sanitizing, do not asume that cxa_pure_virutal is not called
+ by valid program. */
+ if (flag_sanitize & SANITIZE_UNDEFINED)
+ ;
/* Only add pure virtual if it is the only possible target. This way
we will preserve the diagnostics about pure virtual called in many
cases without disabling optimization in other. */
- if (pure_virtual)
+ else if (pure_virtual)
{
if (nodes.length ())
return;
@@ -3374,8 +3378,7 @@ possible_polymorphic_call_target_p (tree
bool final;
if (TREE_CODE (TREE_TYPE (n->decl)) == FUNCTION_TYPE
- && ((fcode = DECL_FUNCTION_CODE (n->decl))
- == BUILT_IN_UNREACHABLE
+ && ((fcode = DECL_FUNCTION_CODE (n->decl)) == BUILT_IN_UNREACHABLE
|| fcode == BUILT_IN_TRAP))
return true;
Index: testsuite/g++.dg/ipa/devirt-51.C
===================================================================
--- testsuite/g++.dg/ipa/devirt-51.C (revision 0)
+++ testsuite/g++.dg/ipa/devirt-51.C (working copy)
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fsanitize=undefined -fdump-tree-optimized" } */
+namespace {
+ struct B {
+ B* self;
+ B() : self( this ) { self->f(); }
+ void E(void);
+ virtual void f() = 0;
+ };
+
+ struct D : B
+ {
+ void f() {}
+ };
+}
+
+struct D e;
+
+__attribute__ ((used))
+void B::E(void)
+ {
+ this->f();
+}
+
+ int main()
+ {
+ D d;
+ }
+/* { dg-final { scan-tree-dump "cxa_pure_virtual" "optimized" } } */