Bug 114357 - Add a way to not call deconstructors for non-auto decls, like clang's no_destroy attribute
Summary: Add a way to not call deconstructors for non-auto decls, like clang's no_dest...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-03-15 21:48 UTC by Fangrui Song
Modified: 2024-03-23 17:46 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-03-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fangrui Song 2024-03-15 21:48:02 UTC
Clang supports [[clang::no_destroy]] (alternative form: `__attribute__((no_destroy))`) to disable exit-time destructors of variables of static or thread local storage duration.

* July 2018 discussion: https://discourse.llvm.org/t/rfc-suppress-c-static-destructor-registration/49128
* Patch: https://reviews.llvm.org/D50994 with follow-up https://reviews.llvm.org/D54344
* Current documentation: https://clang.llvm.org/docs/AttributeReference.html#no-destroy
* https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1247r0.html (seems not presented to EWG yet)
 
[[clang::always_destroy]] enables exit-time destructors for specific objects (when -fno-c++-static-destructors disables exit-time destructors globally).
Comment 1 Andrew Pinski 2024-03-15 21:59:09 UTC
This sounds like a very dangerous attribute to have. It changes behavior and even could cause memory leaks if abused.

Plus I think it is also designed to get around folks not programming well defined C++ code.
Comment 2 Andrew Pinski 2024-03-15 22:02:30 UTC
Really having this attribute to work around broken C++ code is just asking for more troubles. There was a request recently for asking to remove the store for the vtable in trivial deconstructors to work around broken C++ code and it was obvious that the developer didn't know how it was broken and just wanted to this attribute to workaround their broken code.
Comment 3 JF Bastien 2024-03-15 22:08:50 UTC
The LLVM feature was added for XNU, because the kernel never runs its own global C++ destructors (but the compiler can't know this). It saved a non-trivial amount of code generation.
Comment 4 Andrew Pinski 2024-03-15 22:09:39 UTC
(In reply to JF Bastien from comment #3)
> The LLVM feature was added for XNU, because the kernel never runs its own
> global C++ destructors (but the compiler can't know this). It saved a
> non-trivial amount of code generation.

Yes and that is broken ....
Comment 5 JF Bastien 2024-03-15 22:25:10 UTC
(In reply to Andrew Pinski from comment #4)
> (In reply to JF Bastien from comment #3)
> > The LLVM feature was added for XNU, because the kernel never runs its own
> > global C++ destructors (but the compiler can't know this). It saved a
> > non-trivial amount of code generation.
> 
> Yes and that is broken ....

Please substantiate your assertion with evidence. What, specifically, is broken and why?

It's totally normal for kernels to not run destructors. It's totally normal for classes to have destructors and do work in them. It's totally normal to use these classes as globals and not need the destructor behavior in these global circumstances (yet need it when used on the stack or heap). It's totally normal for the compiler to not know this unless told.

Look you can do what you want with a non-standard feature in GCC. You're just not being constructive (being destructive?) in this request. People have used this for good reasons in my opinion, and more people would want this standardized so I'll revive that standardization effort. If you have actual good reasons to be against I'd like to hear them. I haven't heard those reasons from you. But again, do what you want and feel free to ignore, I'm not going to engage further if you want to just close the bug as "won't fix".
Comment 6 Andrew Pinski 2024-03-15 22:26:24 UTC
There are better ways of optimizing out atexit calls. PR 19661 has existed for years but nobody has decided to fix it since it has been a low hanging fruit and such.
Comment 7 Jonathan Wakely 2024-03-15 23:46:56 UTC
Libstdc++ has to use some sneaky hacks to avoid destroying globals, we would definitely use no_destroy if we had it.
Comment 8 Jonathan Wakely 2024-03-16 10:35:53 UTC
e.g. PR 107500 where a bare metal system wastes space for a no-op destructor. It would be a lot simpler if we could just mark immortal objects as [[no_destroy]] and not have to dance around what the standard allows (or not) about lifetimes and triviality for objects with static storage duration. It would also be better to not rely on DCE being able to figure out what we're trying to do with unions and empty destructors.

There are valid use cases in a kernel or language runtime for ensuring that some objects do not end their lifetime while other code is still running.