[clang] [clang][CodeGen] Set `dead_on_return` on indirect pointer arguments (PR #148159)
John McCall via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 14 09:24:46 PDT 2025
================
@@ -2852,8 +2852,17 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
if (AI.getInReg())
Attrs.addAttribute(llvm::Attribute::InReg);
- if (AI.getIndirectByVal())
+ // Depending on the ABI, this may be either a byval or a dead_on_return
+ // argument.
+ if (AI.getIndirectByVal()) {
Attrs.addByValAttr(getTypes().ConvertTypeForMem(ParamType));
+ } else {
+ // If the argument type has a non-trivial destructor that the caller has
+ // to invoke, this cannot be a dead_on_return argument.
+ const auto *RD = ParamType->getAsCXXRecordDecl();
+ if (!RD || (RD && RD->hasTrivialDestructor()))
+ Attrs.addAttribute(llvm::Attribute::DeadOnReturn);
+ }
----------------
rjmccall wrote:
Please use:
```
if (!ParamType.isDestructedType() || !ParamType->isRecordType() ||
ParamType->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee())
```
We do destroy parameters in the callee in several situations. The most important example is the MSVC C++ ABI, but I believe that coincidentally never uses indirect argument passing, so it wouldn't be testable. The testable example would be something like this in Objective-C++:
```
struct HasWeakReference {
__weak id ref;
};
void test(HasWeakReference) {} // should still be dead_on_return because the caller is not responsible to destroy it
```
`__weak` helpfully forces the struct to be passed indirectly, but you could also just use a `__strong id ref;` in a struct that's big enough to be passed indirectly on the target.
https://github.com/llvm/llvm-project/pull/148159
More information about the cfe-commits
mailing list