From: "Martin Liška" <mliska@suse.cz>
To: Jason Merrill <jason@redhat.com>, Jakub Jelinek <jakub@redhat.com>
Cc: Richard Biener <richard.guenther@gmail.com>,
Marc Glisse <marc.glisse@inria.fr>,
Jonathan Wakely <jwakely.gcc@gmail.com>,
GCC Patches <gcc-patches@gcc.gnu.org>,
Nathan Sidwell <nathan@acm.org>, Jan Hubicka <hubicka@ucw.cz>
Subject: Re: [PATCH] Allow new/delete operator deletion only for replaceable.
Date: Wed, 8 Apr 2020 17:16:10 +0200 [thread overview]
Message-ID: <e832e47e-451e-8b17-f4d0-5bfc93c9b97f@suse.cz> (raw)
In-Reply-To: <e3d38543-33e8-2939-f20a-5269b3f4776f@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 1542 bytes --]
On 4/8/20 3:34 PM, Jason Merrill wrote:
> On 4/8/20 9:32 AM, Jakub Jelinek wrote:
>> On Wed, Apr 08, 2020 at 09:20:07AM -0400, Jason Merrill via Gcc-patches wrote:
>>> On 4/8/20 4:47 AM, Richard Biener wrote:
>>>> On Tue, Apr 7, 2020 at 5:01 PM Martin Liška <mliska@suse.cz> wrote:
>>>>>
>>>>> Hi.
>>>>>
>>>>> The patch allows DCE to remove only replaceable operators new and delete.
>>>>> That's achieved by proper mark up of all these operators in C++ FE.
>>>>> The patch also brings all tests we've collected so far for the PR.
>>>>>
>>>>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>>>>
>>>>> Ready to be installed?
>>>>
>>>> Grepping for uses of DECL_IS_OPERATOR_* reveals you miss comparing
>>>> the new flag in ipa-icf.c and cgraph node dumping in cgraph.c might want
>>>> to dump it as well.
>>>>
>>>> Otherwise it looks reasonable.
>>>>
>>>> So the mid-end parts are OK in case FE people are happy with this solution
>>>> for GCC 10.
>>>
>>> This seems fine for GCC 10, though I wonder about using an attribute for
>>> DECL_REPLACEABLE_OPERATOR rather than taking a bit in all FUNCTION_DECLs
>>> that will only ever be set on a small handful.
>>
>> If it is just for GCC 10 and we'll return the bit back to unused in GCC 11,
>> I'd think it is acceptable.
>
> Agreed.
>
> Jason
>
All right, thanks for review. There's updated version of the patch that fullfils
Richi's comments.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
I'm going to install the patch.
Thanks,
Martin
[-- Attachment #2: 0001-Allow-new-delete-operator-deletion-only-for-replacea.patch --]
[-- Type: text/x-patch, Size: 17870 bytes --]
From 2f8ba3418f10b41bb839aadb292447bd757238d0 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Tue, 7 Apr 2020 16:23:27 +0200
Subject: [PATCH] Allow new/delete operator deletion only for replaceable.
gcc/ChangeLog:
2020-04-07 Martin Liska <mliska@suse.cz>
PR c++/94314
* gimple.c (gimple_call_operator_delete_p): Rename to...
(gimple_call_replaceable_operator_delete_p): ... this.
Use DECL_IS_REPLACEABLE_OPERATOR_DELETE_P.
* gimple.h (gimple_call_operator_delete_p): Rename to ...
(gimple_call_replaceable_operator_delete_p): ... this.
* tree-core.h (tree_function_decl): Add replaceable_operator
flag.
* tree-ssa-dce.c (mark_all_reaching_defs_necessary_1):
Use DECL_IS_REPLACEABLE_OPERATOR_DELETE_P.
(propagate_necessity): Use gimple_call_replaceable_operator_delete_p.
(eliminate_unnecessary_stmts): Likewise.
* tree-streamer-in.c (unpack_ts_function_decl_value_fields):
Pack DECL_IS_REPLACEABLE_OPERATOR.
* tree-streamer-out.c (pack_ts_function_decl_value_fields):
Unpack the field here.
* tree.h (DECL_IS_REPLACEABLE_OPERATOR): New.
(DECL_IS_REPLACEABLE_OPERATOR_NEW_P): New.
(DECL_IS_REPLACEABLE_OPERATOR_DELETE_P): New.
* cgraph.c (cgraph_node::dump): Dump if an operator is replaceable.
* ipa-icf.c (sem_item::compare_referenced_symbol_properties): Compare
replaceable operator flags.
gcc/cp/ChangeLog:
2020-04-07 Martin Liska <mliska@suse.cz>
PR c++/94314
* decl.c (duplicate_decls): Duplicate also DECL_IS_REPLACEABLE_OPERATOR.
(cxx_init_decl_processing): Mark replaceable all implicitly defined
operators.
gcc/lto/ChangeLog:
2020-04-07 Martin Liska <mliska@suse.cz>
PR c++/94314
* lto-common.c (compare_tree_sccs_1): Compare also
DECL_IS_REPLACEABLE_OPERATOR.
gcc/testsuite/ChangeLog:
2020-04-07 Martin Liska <mliska@suse.cz>
PR c++/94314
* g++.dg/pr94314-2.C: New test.
* g++.dg/pr94314-3.C: New test.
* g++.dg/pr94314.C: New test.
---
gcc/cgraph.c | 7 +--
gcc/cp/decl.c | 14 ++++++
gcc/gimple.c | 6 +--
gcc/gimple.h | 2 +-
gcc/ipa-icf.c | 4 ++
gcc/lto/lto-common.c | 1 +
gcc/testsuite/g++.dg/pr94314-2.C | 26 ++++++++++
gcc/testsuite/g++.dg/pr94314-3.C | 55 +++++++++++++++++++++
gcc/testsuite/g++.dg/pr94314.C | 85 ++++++++++++++++++++++++++++++++
gcc/tree-core.h | 3 +-
gcc/tree-ssa-dce.c | 8 +--
gcc/tree-streamer-in.c | 1 +
gcc/tree-streamer-out.c | 1 +
gcc/tree.h | 10 +++-
14 files changed, 210 insertions(+), 13 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/pr94314-2.C
create mode 100644 gcc/testsuite/g++.dg/pr94314-3.C
create mode 100644 gcc/testsuite/g++.dg/pr94314.C
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 6b780f80eb3..ecb234d032f 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -2157,10 +2157,11 @@ cgraph_node::dump (FILE *f)
if (parallelized_function)
fprintf (f, " parallelized_function");
if (DECL_IS_OPERATOR_NEW_P (decl))
- fprintf (f, " operator_new");
+ fprintf (f, " %soperator_new",
+ DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
if (DECL_IS_OPERATOR_DELETE_P (decl))
- fprintf (f, " operator_delete");
-
+ fprintf (f, " %soperator_delete",
+ DECL_IS_REPLACEABLE_OPERATOR (decl) ? "replaceable_" : "");
fprintf (f, "\n");
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a127734af69..a731702bdd2 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2368,6 +2368,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
DECL_SET_IS_OPERATOR_NEW (newdecl, true);
DECL_LOOPING_CONST_OR_PURE_P (newdecl)
|= DECL_LOOPING_CONST_OR_PURE_P (olddecl);
+ DECL_IS_REPLACEABLE_OPERATOR (newdecl)
+ |= DECL_IS_REPLACEABLE_OPERATOR (olddecl);
if (merge_attr)
merge_attribute_bits (newdecl, olddecl);
@@ -4438,13 +4440,17 @@ cxx_init_decl_processing (void)
tree opnew = push_cp_library_fn (NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
DECL_SET_IS_OPERATOR_NEW (opnew, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opnew) = 1;
opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
DECL_SET_IS_OPERATOR_NEW (opnew, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opnew) = 1;
tree opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opdel) = 1;
opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opdel) = 1;
if (flag_sized_deallocation)
{
/* Also push the sized deallocation variants:
@@ -4458,8 +4464,10 @@ cxx_init_decl_processing (void)
deltype = build_exception_variant (deltype, empty_except_spec);
opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opdel) = 1;
opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opdel) = 1;
}
if (aligned_new_threshold)
@@ -4478,9 +4486,11 @@ cxx_init_decl_processing (void)
opnew = push_cp_library_fn (NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
DECL_SET_IS_OPERATOR_NEW (opnew, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opnew) = 1;
opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
DECL_SET_IS_OPERATOR_NEW (opnew, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opnew) = 1;
/* operator delete (void *, align_val_t); */
deltype = build_function_type_list (void_type_node, ptr_type_node,
@@ -4489,8 +4499,10 @@ cxx_init_decl_processing (void)
deltype = build_exception_variant (deltype, empty_except_spec);
opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opdel) = 1;
opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opdel) = 1;
if (flag_sized_deallocation)
{
@@ -4502,8 +4514,10 @@ cxx_init_decl_processing (void)
deltype = build_exception_variant (deltype, empty_except_spec);
opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opdel) = 1;
opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ DECL_IS_REPLACEABLE_OPERATOR (opdel) = 1;
}
}
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 61a400b356f..10c562f4def 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2730,15 +2730,15 @@ gimple_builtin_call_types_compatible_p (const gimple *stmt, tree fndecl)
return true;
}
-/* Return true when STMT is operator delete call. */
+/* Return true when STMT is operator a replaceable delete call. */
bool
-gimple_call_operator_delete_p (const gcall *stmt)
+gimple_call_replaceable_operator_delete_p (const gcall *stmt)
{
tree fndecl;
if ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE)
- return DECL_IS_OPERATOR_DELETE_P (fndecl);
+ return DECL_IS_REPLACEABLE_OPERATOR_DELETE_P (fndecl);
return false;
}
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 305d98f5438..ca7fec6247e 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1615,7 +1615,7 @@ extern alias_set_type gimple_get_alias_set (tree);
extern bool gimple_ior_addresses_taken (bitmap, gimple *);
extern bool gimple_builtin_call_types_compatible_p (const gimple *, tree);
extern combined_fn gimple_call_combined_fn (const gimple *);
-extern bool gimple_call_operator_delete_p (const gcall *);
+extern bool gimple_call_replaceable_operator_delete_p (const gcall *);
extern bool gimple_call_builtin_p (const gimple *);
extern bool gimple_call_builtin_p (const gimple *, enum built_in_class);
extern bool gimple_call_builtin_p (const gimple *, enum built_in_function);
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 17a0ed9760b..069de9d82fb 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -347,6 +347,10 @@ sem_item::compare_referenced_symbol_properties (symtab_node *used_by,
if (DECL_IS_OPERATOR_NEW_P (n1->decl)
!= DECL_IS_OPERATOR_NEW_P (n2->decl))
return return_false_with_msg ("operator new flags are different");
+
+ if (DECL_IS_REPLACEABLE_OPERATOR (n1->decl)
+ != DECL_IS_REPLACEABLE_OPERATOR (n2->decl))
+ return return_false_with_msg ("replaceable operator flags are different");
}
/* Merging two definitions with a reference to equivalent vtables, but
diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c
index c95a9b00d9e..e073abce2e7 100644
--- a/gcc/lto/lto-common.c
+++ b/gcc/lto/lto-common.c
@@ -1236,6 +1236,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (DECL_DISREGARD_INLINE_LIMITS);
compare_values (DECL_PURE_P);
compare_values (DECL_LOOPING_CONST_OR_PURE_P);
+ compare_values (DECL_IS_REPLACEABLE_OPERATOR);
compare_values (DECL_FINAL_P);
compare_values (DECL_CXX_CONSTRUCTOR_P);
compare_values (DECL_CXX_DESTRUCTOR_P);
diff --git a/gcc/testsuite/g++.dg/pr94314-2.C b/gcc/testsuite/g++.dg/pr94314-2.C
new file mode 100644
index 00000000000..36b93ed6d4d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr94314-2.C
@@ -0,0 +1,26 @@
+/* PR c++/94314. */
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-cddce-details" } */
+/* { dg-additional-options "-fdelete-null-pointer-checks" } */
+
+#include <stdio.h>
+
+struct A
+{
+ __attribute__((always_inline)) A(int x)
+ {
+ if (x == 123)
+ throw x;
+ }
+};
+
+int
+main(int argc, char **argv)
+{
+ A *a = new A (argc);
+ delete a;
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleting : operator delete" 2 "cddce1"} } */
diff --git a/gcc/testsuite/g++.dg/pr94314-3.C b/gcc/testsuite/g++.dg/pr94314-3.C
new file mode 100644
index 00000000000..a5b10139290
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr94314-3.C
@@ -0,0 +1,55 @@
+/* PR c++/94314. */
+/* { dg-do run } */
+/* { dg-options "-O2 --param early-inlining-insns=100 -fdump-tree-cddce-details" } */
+/* { dg-additional-options "-fdelete-null-pointer-checks" } */
+
+#include <stdio.h>
+
+volatile int idx;
+
+struct base
+{
+ __attribute__ ((malloc, noinline)) static void *
+ operator new (unsigned long sz)
+ {
+ return ::operator new (sz);
+ }
+
+ __attribute__ ((noinline)) static void operator delete (void *ptr)
+ {
+ int c = count[idx];
+ count[idx] = c - 1;
+ ::operator delete (ptr);
+ }
+ volatile static int count[2];
+};
+
+volatile int base::count[2] = {0, 0};
+
+struct B : base
+{
+ static void *operator new (unsigned long sz)
+ {
+ int c = count[idx];
+ count[idx] = c + 1;
+ return base::operator new (sz);
+ }
+};
+
+volatile int c = 1;
+
+int
+main ()
+{
+ for (int i; i < c; i++)
+ {
+ idx = 0;
+ delete new B;
+ if (B::count[0] != 0)
+ __builtin_abort ();
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Deleting : operator delete" "cddce1"} } */
diff --git a/gcc/testsuite/g++.dg/pr94314.C b/gcc/testsuite/g++.dg/pr94314.C
new file mode 100644
index 00000000000..a06800d2219
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr94314.C
@@ -0,0 +1,85 @@
+/* PR c++/94314. */
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-cddce-details" } */
+/* { dg-additional-options "-fdelete-null-pointer-checks" } */
+
+#include <stdio.h>
+
+struct A
+{
+ __attribute__((malloc,noinline))
+ static void* operator new(unsigned long sz)
+ {
+ ++count;
+ return ::operator new(sz);
+ }
+
+ static void operator delete(void* ptr)
+ {
+ --count;
+ ::operator delete(ptr);
+ }
+
+ static int count;
+};
+
+int A::count = 0;
+
+struct B
+{
+ __attribute__((malloc,noinline))
+ static void* operator new(unsigned long sz)
+ {
+ ++count;
+ return ::operator new(sz);
+ }
+
+ __attribute__((noinline))
+ static void operator delete(void* ptr)
+ {
+ --count;
+ ::operator delete(ptr);
+ }
+
+ static int count;
+};
+
+int B::count = 0;
+
+struct C
+{
+ static void* operator new(unsigned long sz)
+ {
+ ++count;
+ return ::operator new(sz);
+ }
+
+ static void operator delete(void* ptr)
+ {
+ --count;
+ ::operator delete(ptr);
+ }
+
+ static int count;
+};
+
+int C::count = 0;
+
+int main(){
+ delete new A;
+ if (A::count != 0)
+ __builtin_abort ();
+
+ delete new B;
+ if (B::count != 0)
+ __builtin_abort ();
+
+ delete new C;
+ if (C::count != 0)
+ __builtin_abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleting : operator delete" 1 "cddce1"} } */
+/* { dg-final { scan-tree-dump-not "Deleting : B::operator delete" "cddce1"} } */
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 765ea2a9542..d84fe959acc 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1896,8 +1896,9 @@ struct GTY(()) tree_function_decl {
ENUM_BITFIELD(function_decl_type) decl_type: 2;
unsigned has_debug_args_flag : 1;
unsigned versioned_function : 1;
+ unsigned replaceable_operator : 1;
- /* 12 bits left for future expansion. */
+ /* 11 bits left for future expansion. */
};
struct GTY(()) tree_translation_unit_decl {
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index e4077b58890..fd5f24c746c 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -614,7 +614,7 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
if (callee != NULL_TREE
&& (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)
- || DECL_IS_OPERATOR_DELETE_P (callee)))
+ || DECL_IS_REPLACEABLE_OPERATOR_DELETE_P (callee)))
return false;
}
@@ -806,7 +806,7 @@ propagate_necessity (bool aggressive)
processing the argument. */
bool is_delete_operator
= (is_gimple_call (stmt)
- && gimple_call_operator_delete_p (as_a <gcall *> (stmt)));
+ && gimple_call_replaceable_operator_delete_p (as_a <gcall *> (stmt)));
if (is_delete_operator
|| gimple_call_builtin_p (stmt, BUILT_IN_FREE))
{
@@ -896,7 +896,7 @@ propagate_necessity (bool aggressive)
if (callee != NULL_TREE
&& (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)
- || DECL_IS_OPERATOR_DELETE_P (callee)))
+ || DECL_IS_REPLACEABLE_OPERATOR_DELETE_P (callee)))
continue;
/* Calls implicitly load from memory, their arguments
@@ -1321,7 +1321,7 @@ eliminate_unnecessary_stmts (void)
if (gimple_plf (stmt, STMT_NECESSARY)
&& (gimple_call_builtin_p (stmt, BUILT_IN_FREE)
|| (is_gimple_call (stmt)
- && gimple_call_operator_delete_p (as_a <gcall *> (stmt)))))
+ && gimple_call_replaceable_operator_delete_p (as_a <gcall *> (stmt)))))
{
tree ptr = gimple_call_arg (stmt, 0);
if (TREE_CODE (ptr) == SSA_NAME)
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index 4e035e9638f..0bfc272d076 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -343,6 +343,7 @@ unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
DECL_DISREGARD_INLINE_LIMITS (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_LOOPING_CONST_OR_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ DECL_IS_REPLACEABLE_OPERATOR (expr) = (unsigned) bp_unpack_value (bp, 1);
unsigned int fcode = 0;
if (cl != NOT_BUILT_IN)
{
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index 8e5e1355196..5bbcebba87e 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -305,6 +305,7 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_value (bp, DECL_DISREGARD_INLINE_LIMITS (expr), 1);
bp_pack_value (bp, DECL_PURE_P (expr), 1);
bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
+ bp_pack_value (bp, DECL_IS_REPLACEABLE_OPERATOR (expr), 1);
if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
bp_pack_value (bp, DECL_UNCHECKED_FUNCTION_CODE (expr), 32);
}
diff --git a/gcc/tree.h b/gcc/tree.h
index 66dfa876256..1c28785d411 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3037,6 +3037,11 @@ set_function_decl_type (tree decl, function_decl_type t, bool set)
FUNCTION_DECL_DECL_TYPE (decl) = NONE;
}
+/* Nonzero in a FUNCTION_DECL means this function is a replaceable
+ function (like replaceable operators new or delete). */
+#define DECL_IS_REPLACEABLE_OPERATOR(NODE)\
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.replaceable_operator)
+
/* Nonzero in a FUNCTION_DECL means this function should be treated as
C++ operator new, meaning that it returns a pointer for which we
should not use type based aliasing. */
@@ -3044,7 +3049,7 @@ set_function_decl_type (tree decl, function_decl_type t, bool set)
(FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_NEW)
#define DECL_IS_REPLACEABLE_OPERATOR_NEW_P(NODE) \
- (DECL_IS_OPERATOR_NEW_P (NODE) && DECL_IS_MALLOC (NODE))
+ (DECL_IS_OPERATOR_NEW_P (NODE) && DECL_IS_REPLACEABLE_OPERATOR (NODE))
#define DECL_SET_IS_OPERATOR_NEW(NODE, VAL) \
set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_NEW, VAL)
@@ -3054,6 +3059,9 @@ set_function_decl_type (tree decl, function_decl_type t, bool set)
#define DECL_IS_OPERATOR_DELETE_P(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_DELETE)
+#define DECL_IS_REPLACEABLE_OPERATOR_DELETE_P(NODE) \
+ (DECL_IS_OPERATOR_DELETE_P (NODE) && DECL_IS_REPLACEABLE_OPERATOR (NODE))
+
#define DECL_SET_IS_OPERATOR_DELETE(NODE, VAL) \
set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_DELETE, VAL)
--
2.26.0
next prev parent reply other threads:[~2020-04-08 15:16 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-30 8:40 [PATCH] Check DECL_CONTEXT of new/delete operators Martin Liška
2020-03-30 8:53 ` Richard Biener
2020-03-31 12:29 ` Jan Hubicka
2020-03-31 12:38 ` Martin Liška
2020-04-03 15:26 ` Jan Hubicka
2020-04-03 15:42 ` Jan Hubicka
2020-04-04 11:53 ` Jan Hubicka
2020-04-06 9:27 ` Richard Biener
2020-04-06 15:10 ` Jason Merrill
2020-04-06 8:34 ` Martin Liška
2020-04-06 12:45 ` Nathan Sidwell
2020-04-07 8:26 ` Jonathan Wakely
2020-04-07 9:29 ` Richard Biener
2020-04-07 9:49 ` Jan Hubicka
2020-04-07 10:22 ` Richard Biener
2020-04-07 10:42 ` Martin Liška
2020-04-07 11:41 ` Jonathan Wakely
2020-04-07 10:46 ` Martin Liška
2020-04-07 11:29 ` Jonathan Wakely
2020-04-07 11:40 ` Richard Biener
2020-04-07 11:46 ` Jonathan Wakely
2020-04-07 11:57 ` Richard Biener
2020-04-07 15:00 ` [PATCH] Allow new/delete operator deletion only for replaceable Martin Liška
2020-04-08 8:47 ` Richard Biener
2020-04-08 13:20 ` Jason Merrill
2020-04-08 13:32 ` Jakub Jelinek
2020-04-08 13:34 ` Jason Merrill
2020-04-08 15:16 ` Martin Liška [this message]
2020-04-08 15:46 ` Jan Hubicka
2020-04-08 16:06 ` Jakub Jelinek
2020-04-09 5:05 ` Martin Liška
2020-04-09 6:45 ` Richard Biener
2020-04-09 6:59 ` Martin Liška
2020-04-09 7:21 ` Richard Biener
2020-04-09 7:55 ` Jakub Jelinek
2020-04-09 8:04 ` Marc Glisse
2020-04-09 8:13 ` Jonathan Wakely
2020-04-10 8:08 ` Martin Liška
2020-04-10 8:18 ` Jonathan Wakely
2020-04-10 8:29 ` Martin Liška
2020-04-10 9:17 ` Jakub Jelinek
2020-04-14 7:09 ` Martin Liška
2020-04-14 7:11 ` Martin Liška
2020-04-14 8:37 ` Jakub Jelinek
2020-04-14 10:54 ` Martin Liška
2020-04-17 7:05 ` Jakub Jelinek
2020-04-17 8:12 ` Jonathan Wakely
2020-04-10 8:37 ` Marc Glisse
2020-04-10 9:11 ` Iain Sandoe
2020-04-09 16:55 ` Jason Merrill
2020-04-07 15:16 ` [PATCH] Check DECL_CONTEXT of new/delete operators Jonathan Wakely
2020-04-08 7:34 ` Richard Biener
2020-04-08 8:11 ` Jonathan Wakely
2020-04-07 14:11 ` Nathan Sidwell
2020-03-30 9:29 ` Marc Glisse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e832e47e-451e-8b17-f4d0-5bfc93c9b97f@suse.cz \
--to=mliska@suse.cz \
--cc=gcc-patches@gcc.gnu.org \
--cc=hubicka@ucw.cz \
--cc=jakub@redhat.com \
--cc=jason@redhat.com \
--cc=jwakely.gcc@gmail.com \
--cc=marc.glisse@inria.fr \
--cc=nathan@acm.org \
--cc=richard.guenther@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).