diff options
author | Jan Hubicka <jh@suse.cz> | 2020-11-05 18:19:07 +0100 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2020-11-05 18:19:07 +0100 |
commit | 58c9de46541ade795987b8949cfa685f02b0318a (patch) | |
tree | 611f10a41c0cdb8c0d952d3f4e210334748e4837 | |
parent | 9f87fcf3034d0e774c4dee380f9113d1453e0e72 (diff) | |
download | gcc-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.
-rw-r--r-- | gcc/gimple.c | 13 | ||||
-rw-r--r-- | gcc/gimple.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/devirt-24.C | 2 |
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" } } */ |