https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2022-11-02
     Ever confirmed|0                           |1

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to R. Diez from comment #0)
> The check above fails with GCC 12.2. Apparently, a destructor called
> constant_init::~constant_init() gets added to the atexit table on start-up.

This was done to make the global object in that file immortal. The
constant_init wrapper gets destroyed, but its subobject doesn't, so code that
refers to it later is ... slightly less undefined.

> Because of the way that Newlib works, that wastes 400 bytes of SRAM, which
> corresponds to sizeof( _global_atexit0 ). The structure has room for 32
> atexit calls (because of some ANSI conformance), but we are only using 1
> entry.
> 
> The interesting thing is that the destructor is supposed to be empty, see:
> 
> https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/
> eh_globals.cc
> 
> ~constant_init() { /* do nothing, union member is not destroyed */ }
> 
> GCC generates the following code for that empty destructor:
> 
> 0008da68 <(anonymous namespace)::constant_init::~constant_init()>:
>   8da68:  b580  push  {r7, lr}
>   8da6a:  af00  add   r7, sp, #0
>   8da6c:  bd80  pop   {r7, pc}
> 
> That does not make any sense. Is there a way to prevent GCC from registering
> such an empty atexit function? Failing that, is there a way to prevent GCC
> from registering a particular atexit function, even if it is not empty?

If we had clang's no_destroy attribute then we could use that on those
constant_init wrappers:
https://clang.llvm.org/docs/AttributeReference.html#no-destroy


> I find surprising that GCC emits such code. My project is building its own
> GCC/Newlib toolchain with optimisation level "-Os", so I would expect at
> least the "add r7, sp, #0" to be optimised away.

Agreed, I don't think we should be emitting cleanup if it's a no-op. But I
don't know if the compiler is able to tell it's a no-op at the point where it
emits that code. The attribute would tell the compiler it's OK to do that.

Reply via email to