libstdc++: Add some further attributes to ::operator new in <new>

Message ID ZySweBOoH0RtnDDl@tucnak
State New
Headers
Series libstdc++: Add some further attributes to ::operator new in <new> |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed

Commit Message

Jakub Jelinek Nov. 1, 2024, 10:42 a.m. UTC
  Hi!

I've noticed alloc_align attribute is missing on the non-vector
::operator new with std::align_val_t and const std::nothrow_t&
arguments, this patch adds it.  The last hunk is just
an attempt to make the line shorter.
The first hunk originally added also __alloc_size__ (1) attribute,
but seems that regresses
FAIL: g++.dg/tm/pr46270.C  -std=gnu++98 (test for excess errors)
with
Excess errors:
.../libstdc++-v3/libsupc++/new:137:26: warning: new declaration 'void* operator new(std::size_t)' ambiguates built-in declaration 'void* operator new(long unsigned int) transaction_safe' [-Wbuiltin-declaration-mismatch]
.../libstdc++-v3/libsupc++/new:140:26: warning: new declaration 'void* operator new [](std::size_t)' ambiguates built-in declaration 'void* operator new [](long unsigned int) transaction_safe' [-Wbuiltin-declaration-mismatch]
I must say I have no clue why that happens only in C++98 (C++11 and
above are quiet) and why only with -fgnu-tm, tried to debug that but
am lost.  It is some conflict with the predeclared ::operator new, but
those clearly do have the externally_visible attribute, and alloc_size (1)
attributes:
    extvisattr = build_tree_list (get_identifier ("externally_visible"),
                                  NULL_TREE);
    newattrs = tree_cons (get_identifier ("alloc_size"),
                          build_tree_list (NULL_TREE, integer_one_node),
                          extvisattr);
    newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
    newtype = build_exception_variant (newtype, new_eh_spec);
...
    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;
and at C++98 I think libstdc++ doesn't add transaction_safe attribute:
// Conditionally enable annotations for the Transactional Memory TS on C++11.
// Most of the following conditions are due to limitations in the current
// implementation.
#if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI                    \
  && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201500L     \
  &&  !_GLIBCXX_FULLY_DYNAMIC_STRING && _GLIBCXX_USE_WEAK_REF           \
  && _GLIBCXX_USE_ALLOCATOR_NEW
#define _GLIBCXX_TXN_SAFE transaction_safe
#define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic
#else
#define _GLIBCXX_TXN_SAFE
#define _GLIBCXX_TXN_SAFE_DYN
#endif
push_cp_library_fn adds transaction_safe attribute whenever -fgnu-tm
is used, regardless of the other conditionals:
  if (flag_tm)
    apply_tm_attr (fn, get_identifier ("transaction_safe"));

Anyway, omitting alloc_size (1) fixes that test and given that the
predeclared operator new already has alloc_size (1) attribute, I think it
can be safely left out.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2024-11-01  Jakub Jelinek  <jakub@redhat.com>

	* libsupc++/new (::operator new, ::operator new[]): Add malloc
	attribute where missing.  Add alloc_align attribute when
	std::align_val_t is present and where it was missing.  Formatting fix.


	Jakub
  

Comments

Jakub Jelinek Nov. 8, 2024, 12:43 p.m. UTC | #1
Hi!

On Fri, Nov 01, 2024 at 11:42:00AM +0100, Jakub Jelinek wrote:
> I've noticed alloc_align attribute is missing on the non-vector
> ::operator new with std::align_val_t and const std::nothrow_t&
> arguments, this patch adds it.  The last hunk is just
> an attempt to make the line shorter.

I'd like to ping the
https://gcc.gnu.org/pipermail/libstdc++/2024-November/059889.html
patch.

Thanks.

> 2024-11-01  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* libsupc++/new (::operator new, ::operator new[]): Add malloc
> 	attribute where missing.  Add alloc_align attribute when
> 	std::align_val_t is present and where it was missing.  Formatting fix.

	Jakub
  
Jonathan Wakely Nov. 8, 2024, 2:56 p.m. UTC | #2
On Fri, 1 Nov 2024 at 10:42, Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> I've noticed alloc_align attribute is missing on the non-vector
> ::operator new with std::align_val_t and const std::nothrow_t&
> arguments, this patch adds it.  The last hunk is just
> an attempt to make the line shorter.
> The first hunk originally added also __alloc_size__ (1) attribute,
> but seems that regresses
> FAIL: g++.dg/tm/pr46270.C  -std=gnu++98 (test for excess errors)
> with
> Excess errors:
> .../libstdc++-v3/libsupc++/new:137:26: warning: new declaration 'void* operator new(std::size_t)' ambiguates built-in declaration 'void* operator new(long unsigned int) transaction_safe' [-Wbuiltin-declaration-mismatch]
> .../libstdc++-v3/libsupc++/new:140:26: warning: new declaration 'void* operator new [](std::size_t)' ambiguates built-in declaration 'void* operator new [](long unsigned int) transaction_safe' [-Wbuiltin-declaration-mismatch]
> I must say I have no clue why that happens only in C++98 (C++11 and
> above are quiet) and why only with -fgnu-tm, tried to debug that but
> am lost.  It is some conflict with the predeclared ::operator new, but
> those clearly do have the externally_visible attribute, and alloc_size (1)
> attributes:
>     extvisattr = build_tree_list (get_identifier ("externally_visible"),
>                                   NULL_TREE);
>     newattrs = tree_cons (get_identifier ("alloc_size"),
>                           build_tree_list (NULL_TREE, integer_one_node),
>                           extvisattr);
>     newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
>     newtype = build_exception_variant (newtype, new_eh_spec);
> ...
>     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;
> and at C++98 I think libstdc++ doesn't add transaction_safe attribute:
> // Conditionally enable annotations for the Transactional Memory TS on C++11.
> // Most of the following conditions are due to limitations in the current
> // implementation.
> #if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI                    \
>   && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201500L     \
>   &&  !_GLIBCXX_FULLY_DYNAMIC_STRING && _GLIBCXX_USE_WEAK_REF           \
>   && _GLIBCXX_USE_ALLOCATOR_NEW
> #define _GLIBCXX_TXN_SAFE transaction_safe
> #define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic
> #else
> #define _GLIBCXX_TXN_SAFE
> #define _GLIBCXX_TXN_SAFE_DYN
> #endif
> push_cp_library_fn adds transaction_safe attribute whenever -fgnu-tm
> is used, regardless of the other conditionals:
>   if (flag_tm)
>     apply_tm_attr (fn, get_identifier ("transaction_safe"));
>
> Anyway, omitting alloc_size (1) fixes that test and given that the
> predeclared operator new already has alloc_size (1) attribute, I think it
> can be safely left out.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK, thanks.


>
> 2024-11-01  Jakub Jelinek  <jakub@redhat.com>
>
>         * libsupc++/new (::operator new, ::operator new[]): Add malloc
>         attribute where missing.  Add alloc_align attribute when
>         std::align_val_t is present and where it was missing.  Formatting fix.
>
> --- libstdc++-v3/libsupc++/new.jj       2024-10-31 11:41:47.894615923 +0100
> +++ libstdc++-v3/libsupc++/new  2024-10-31 16:16:56.545859474 +0100
> @@ -136,10 +136,10 @@ namespace std
>  */
>  _GLIBCXX_NODISCARD void* operator new(std::size_t)
>    _GLIBCXX_TXN_SAFE _GLIBCXX_THROW (std::bad_alloc)
> -  __attribute__((__externally_visible__));
> +  __attribute__((__externally_visible__, __malloc__));
>  _GLIBCXX_NODISCARD void* operator new[](std::size_t)
>    _GLIBCXX_TXN_SAFE _GLIBCXX_THROW (std::bad_alloc)
> -  __attribute__((__externally_visible__));
> +  __attribute__((__externally_visible__, __malloc__));
>  void operator delete(void*) _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
>    __attribute__((__externally_visible__));
>  void operator delete[](void*) _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
> @@ -169,8 +169,8 @@ _GLIBCXX_NODISCARD void* operator new(st
>    _GLIBCXX_TXN_SAFE
>    __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2),  __malloc__));
>  _GLIBCXX_NODISCARD void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&)
> -   _GLIBCXX_TXN_SAFE
> -  _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __alloc_size__ (1), __malloc__));
> +  _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
> +  __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2), __malloc__));
>  void operator delete(void*, std::align_val_t) _GLIBCXX_TXN_SAFE
>    _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
>  void operator delete(void*, std::align_val_t, const std::nothrow_t&)
> @@ -180,8 +180,8 @@ _GLIBCXX_NODISCARD void* operator new[](
>    _GLIBCXX_TXN_SAFE
>    __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2), __malloc__));
>  _GLIBCXX_NODISCARD void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&)
> -  _GLIBCXX_TXN_SAFE
> -  _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2), __malloc__));
> +  _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
> +  __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2), __malloc__));
>  void operator delete[](void*, std::align_val_t) _GLIBCXX_TXN_SAFE
>    _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
>  void operator delete[](void*, std::align_val_t, const std::nothrow_t&)
>
>         Jakub
>
  

Patch

--- libstdc++-v3/libsupc++/new.jj	2024-10-31 11:41:47.894615923 +0100
+++ libstdc++-v3/libsupc++/new	2024-10-31 16:16:56.545859474 +0100
@@ -136,10 +136,10 @@  namespace std
 */
 _GLIBCXX_NODISCARD void* operator new(std::size_t)
   _GLIBCXX_TXN_SAFE _GLIBCXX_THROW (std::bad_alloc)
-  __attribute__((__externally_visible__));
+  __attribute__((__externally_visible__, __malloc__));
 _GLIBCXX_NODISCARD void* operator new[](std::size_t)
   _GLIBCXX_TXN_SAFE _GLIBCXX_THROW (std::bad_alloc)
-  __attribute__((__externally_visible__));
+  __attribute__((__externally_visible__, __malloc__));
 void operator delete(void*) _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
   __attribute__((__externally_visible__));
 void operator delete[](void*) _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
@@ -169,8 +169,8 @@  _GLIBCXX_NODISCARD void* operator new(st
   _GLIBCXX_TXN_SAFE
   __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2),  __malloc__));
 _GLIBCXX_NODISCARD void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&)
-   _GLIBCXX_TXN_SAFE
-  _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __alloc_size__ (1), __malloc__));
+  _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
+  __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2), __malloc__));
 void operator delete(void*, std::align_val_t) _GLIBCXX_TXN_SAFE
   _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
 void operator delete(void*, std::align_val_t, const std::nothrow_t&)
@@ -180,8 +180,8 @@  _GLIBCXX_NODISCARD void* operator new[](
   _GLIBCXX_TXN_SAFE
   __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2), __malloc__));
 _GLIBCXX_NODISCARD void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&)
-  _GLIBCXX_TXN_SAFE
-  _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2), __malloc__));
+  _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
+  __attribute__((__externally_visible__, __alloc_size__ (1), __alloc_align__ (2), __malloc__));
 void operator delete[](void*, std::align_val_t) _GLIBCXX_TXN_SAFE
   _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
 void operator delete[](void*, std::align_val_t, const std::nothrow_t&)