================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits