aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2020-11-05 18:19:07 +0100
committerJan Hubicka <jh@suse.cz>2020-11-05 18:19:07 +0100
commit58c9de46541ade795987b8949cfa685f02b0318a (patch)
tree611f10a41c0cdb8c0d952d3f4e210334748e4837 /gcc
parent9f87fcf3034d0e774c4dee380f9113d1453e0e72 (diff)
downloadgcc-58c9de46541ade795987b8949cfa685f02b0318a.zip
gcc-58c9de46541ade795987b8949cfa685f02b0318a.tar.gz
gcc-58c9de46541ade795987b8949cfa685f02b0318a.tar.bz2
Add fnspecs for C++ new and delete operators
gcc/ChangeLog: * gimple.c (gimple_call_fnspec): Handle C++ new and delete. * gimple.h (gimple_call_from_new_or_delete): Constify parameter. gcc/testsuite/ChangeLog: * g++.dg/ipa/devirt-24.C: Update template.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple.c13
-rw-r--r--gcc/gimple.h2
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-24.C2
3 files changed, 15 insertions, 2 deletions
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 469e6f3..1afed88 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1510,6 +1510,19 @@ gimple_call_fnspec (const gcall *stmt)
}
if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
return builtin_fnspec (gimple_call_fndecl (stmt));
+ tree fndecl = gimple_call_fndecl (stmt);
+ /* If the call is to a replaceable operator delete and results
+ from a delete expression as opposed to a direct call to
+ such operator, then we can treat it as free. */
+ if (fndecl
+ && DECL_IS_OPERATOR_DELETE_P (fndecl)
+ && gimple_call_from_new_or_delete (stmt))
+ return ".co ";
+ /* Similarly operator new can be treated as malloc. */
+ if (fndecl
+ && DECL_IS_OPERATOR_NEW_P (fndecl)
+ && gimple_call_from_new_or_delete (stmt))
+ return "mC";
return "";
}
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 87c90be..62b5a8a 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -3405,7 +3405,7 @@ gimple_call_set_from_new_or_delete (gcall *s, bool from_new_or_delete_p)
from a new or delete expression. */
static inline bool
-gimple_call_from_new_or_delete (gcall *s)
+gimple_call_from_new_or_delete (const gcall *s)
{
return (s->subcode & GF_CALL_FROM_NEW_OR_DELETE) != 0;
}
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-24.C b/gcc/testsuite/g++.dg/ipa/devirt-24.C
index eaef1f5..7b5b806 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-24.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-24.C
@@ -37,4 +37,4 @@ C *b = new (C);
}
}
/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 1 "inline" { xfail *-*-* } } } */
-/* { dg-final { scan-ipa-dump-times "Aggregate passed by reference" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Aggregate passed by reference" 2 "cp" } } */