https://gcc.gnu.org/g:80e5be0c7f388cf8b8b321dca436ff529ac76867

commit r15-5048-g80e5be0c7f388cf8b8b321dca436ff529ac76867
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Nov 8 22:07:33 2024 +0100

    ibstdc++: Add some further attributes to ::operator new in <new>
    
    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.
    
    2024-11-08  Jakub Jelinek  <ja...@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.

Diff:
---
 libstdc++-v3/libsupc++/new | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new
index 4345030071bb..8f8eaf9c3903 100644
--- a/libstdc++-v3/libsupc++/new
+++ b/libstdc++-v3/libsupc++/new
@@ -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(std::size_t, 
std::align_val_t)
   _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[](std::size_t, 
std::align_val_t)
   _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&)

Reply via email to