diff options
author | Simon Martin <simon@nasilyan.com> | 2024-11-11 20:22:32 +0100 |
---|---|---|
committer | Simon Martin <simon@nasilyan.com> | 2024-11-11 20:22:32 +0100 |
commit | f32e7339871beec0e4d49698f7e34d77ee882088 (patch) | |
tree | 352ceda31244d2203b81b58ed6a324741592fb9a /gcc/cp | |
parent | 417b4cc9bf218083838aeab458bbb7510e36375a (diff) | |
download | gcc-f32e7339871beec0e4d49698f7e34d77ee882088.zip gcc-f32e7339871beec0e4d49698f7e34d77ee882088.tar.gz gcc-f32e7339871beec0e4d49698f7e34d77ee882088.tar.bz2 |
c++: Fix another crash with invalid new operators [PR117463]
Even though this PR is very close to PR117101, it's not addressed by the
fix I made through r15-4958-g5821f5c8c89a05 because cxx_placement_new_fn
has the very same issue as std_placement_new_fn_p used to have.
As suggested by Jason, this patch changes both functions so that
cxx_placement_new_fn leverages std_placement_new_fn_p which reduces code
duplication and fixes the PR.
PR c++/117463
gcc/cp/ChangeLog:
* constexpr.cc (cxx_placement_new_fn): Implement in terms of
std_placement_new_fn_p.
* cp-tree.h (std_placement_new_fn_p): Declare.
* init.cc (std_placement_new_fn_p): Add missing checks to ensure
that fndecl is a non-replaceable ::operator new.
gcc/testsuite/ChangeLog:
* g++.dg/init/new54.C: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/constexpr.cc | 13 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/init.cc | 6 |
3 files changed, 6 insertions, 14 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 71e6dc4..c097860 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -2327,18 +2327,7 @@ cxx_replaceable_global_alloc_fn (tree fndecl) static inline bool cxx_placement_new_fn (tree fndecl) { - if (cxx_dialect >= cxx20 - && IDENTIFIER_NEW_OP_P (DECL_NAME (fndecl)) - && CP_DECL_CONTEXT (fndecl) == global_namespace - && !DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl) - && TREE_CODE (TREE_TYPE (fndecl)) == FUNCTION_TYPE) - { - tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); - if (TREE_VALUE (first_arg) == ptr_type_node - && TREE_CHAIN (first_arg) == void_list_node) - return true; - } - return false; + return (cxx_dialect >= cxx20 && std_placement_new_fn_p (fndecl)); } /* Return true if FNDECL is std::construct_at. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1a0d534..b3c909b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7281,6 +7281,7 @@ extern tree build_offset_ref (tree, tree, bool, extern tree throw_bad_array_new_length (void); extern bool type_has_new_extended_alignment (tree); extern unsigned malloc_alignment (void); +extern bool std_placement_new_fn_p (tree); extern tree build_new_constexpr_heap_type (tree, tree, tree); extern tree build_new (location_t, vec<tree, va_gc> **, tree, diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 62b3d6f..a117010 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -2976,10 +2976,12 @@ malloc_alignment () /* Determine whether an allocation function is a namespace-scope non-replaceable placement new function. See DR 1748. */ -static bool +bool std_placement_new_fn_p (tree alloc_fn) { - if (DECL_NAMESPACE_SCOPE_P (alloc_fn)) + if (DECL_NAMESPACE_SCOPE_P (alloc_fn) + && IDENTIFIER_NEW_OP_P (DECL_NAME (alloc_fn)) + && !DECL_IS_REPLACEABLE_OPERATOR_NEW_P (alloc_fn)) { tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn))); if (first_arg |