On 11/1/24 3:17 PM, Jakub Jelinek wrote:
On Fri, Nov 01, 2024 at 12:28:52PM -0400, Jason Merrill wrote:
Can this block be
if (aligned_allocation_fn_p (decl))
args = TREE_CHAIN (args);
?
Yes.
+ && TREE_CODE (t) == RECORD_TYPE
+ && DECL_NAMESPACE_STD_P (CP_TYPE_CONTEXT (t))
+ && TYPE_NAME (t)
+ && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
+ && DECL_NAME (TYPE_NAME (t))
+ && id_equal (DECL_NAME (TYPE_NAME (t)), "nothrow_t"))
Let's factor is_std_allocator into a function taking a const char * and use
that here as well.
So like this?
I've verified on #include <new> with -std=c++23 it marks exactly 8 operators
which is the expected count.
OK.
2024-11-01 Jakub Jelinek <ja...@redhat.com>
PR c++/117370
* cp-tree.h (is_std_class): Declare.
* constexpr.cc (is_std_class): New function.
(is_std_allocator): Use it.
* decl.cc (grok_op_properties): Mark global replaceable
operator new/delete operators with const std::nothrow_t & last
argument with DECL_IS_REPLACEABLE_OPERATOR.
--- gcc/cp/cp-tree.h.jj 2024-11-01 19:32:12.961053085 +0100
+++ gcc/cp/cp-tree.h 2024-11-01 20:10:18.246350835 +0100
@@ -8706,6 +8706,7 @@ extern bool is_rvalue_constant_expressio
extern bool is_nondependent_constant_expression (tree);
extern bool is_nondependent_static_init_expression (tree);
extern bool is_static_init_expression (tree);
+extern bool is_std_class (tree, const char *);
extern bool is_std_allocator (tree);
extern bool potential_rvalue_constant_expression (tree);
extern bool require_potential_constant_expression (tree);
--- gcc/cp/constexpr.cc.jj 2024-10-25 10:00:29.407768730 +0200
+++ gcc/cp/constexpr.cc 2024-11-01 20:12:04.835825528 +0100
@@ -2363,22 +2363,30 @@ is_std_construct_at (const constexpr_cal
&& is_std_construct_at (call->fundef->decl));
}
-/* True if CTX is an instance of std::allocator. */
+/* True if CTX is an instance of std::NAME class. */
bool
-is_std_allocator (tree ctx)
+is_std_class (tree ctx, const char *name)
{
if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
return false;
tree decl = TYPE_MAIN_DECL (ctx);
- tree name = DECL_NAME (decl);
- if (name == NULL_TREE || !id_equal (name, "allocator"))
+ tree dname = DECL_NAME (decl);
+ if (dname == NULL_TREE || !id_equal (dname, name))
return false;
return decl_in_std_namespace_p (decl);
}
+/* True if CTX is an instance of std::allocator. */
+
+bool
+is_std_allocator (tree ctx)
+{
+ return is_std_class (ctx, "allocator");
+}
+
/* Return true if FNDECL is std::allocator<T>::{,de}allocate. */
static inline bool
--- gcc/cp/decl.cc.jj 2024-10-31 21:17:07.059018373 +0100
+++ gcc/cp/decl.cc 2024-11-01 20:12:48.506200598 +0100
@@ -16191,6 +16191,36 @@ grok_op_properties (tree decl, bool comp
}
}
+ /* Check for replaceable global new/delete operators with
+ const std::nothrow_t & last argument, other replaceable global
+ new/delete operators are marked in cxx_init_decl_processing. */
+ if (CP_DECL_CONTEXT (decl) == global_namespace)
+ {
+ tree args = argtypes;
+ if (args
+ && args != void_list_node
+ && same_type_p (TREE_VALUE (args),
+ (op_flags & OVL_OP_FLAG_DELETE)
+ ? ptr_type_node : size_type_node))
+ {
+ args = TREE_CHAIN (args);
+ if (aligned_allocation_fn_p (decl))
+ args = TREE_CHAIN (args);
+ if (args
+ && args != void_list_node
+ && TREE_CHAIN (args) == void_list_node)
+ {
+ tree t = TREE_VALUE (args);
+ if (TYPE_REF_P (t)
+ && !TYPE_REF_IS_RVALUE (t)
+ && (t = TREE_TYPE (t))
+ && TYPE_QUALS (t) == TYPE_QUAL_CONST
+ && is_std_class (t, "nothrow_t"))
+ DECL_IS_REPLACEABLE_OPERATOR (decl) = 1;
+ }
+ }
+ }
+
if (op_flags & OVL_OP_FLAG_DELETE)
{
DECL_SET_IS_OPERATOR_DELETE (decl, true);
Jakub