[VariadicGenerics] Fix memeffect of metadata accessor.

The metadata accessor for a variadic generic type takes as arguments
packs of metadata records and witness tables, and each such pack is
passed in a buffer.  So any such accessor is not correctly annotated
`memory(none)`.

rdar://161606892
This commit is contained in:
Nate Chandler
2025-10-01 15:38:07 -07:00
parent 4183eca16c
commit 0c685d07f6
4 changed files with 19 additions and 3 deletions

View File

@@ -109,6 +109,11 @@ public:
bool isAnyWitnessTable() const { bool isAnyWitnessTable() const {
return kind == Kind::WitnessTable || kind == Kind::WitnessTablePack; return kind == Kind::WitnessTable || kind == Kind::WitnessTablePack;
} }
bool isAnyPack() const {
return kind == Kind::MetadataPack || kind == Kind::WitnessTablePack;
}
bool isValue() const { bool isValue() const {
return kind == Kind::Value; return kind == Kind::Value;
} }

View File

@@ -2993,8 +2993,9 @@ void irgen::emitLazyMetadataAccessor(IRGenModule &IGM,
if (IGM.getOptions().optimizeForSize()) if (IGM.getOptions().optimizeForSize())
accessor->addFnAttr(llvm::Attribute::NoInline); accessor->addFnAttr(llvm::Attribute::NoInline);
bool isReadNone = (genericArgs.Types.size() <= bool isReadNone =
NumDirectGenericTypeMetadataAccessFunctionArgs); !genericArgs.hasPacks && (genericArgs.Types.size() <=
NumDirectGenericTypeMetadataAccessFunctionArgs);
emitCacheAccessFunction( emitCacheAccessFunction(
IGM, accessor, /*cache*/ nullptr, /*cache type*/ nullptr, IGM, accessor, /*cache*/ nullptr, /*cache type*/ nullptr,

View File

@@ -50,8 +50,9 @@ struct GenericArguments {
/// The values to use to initialize the arguments structure. /// The values to use to initialize the arguments structure.
SmallVector<llvm::Value *, 8> Values; SmallVector<llvm::Value *, 8> Values;
SmallVector<llvm::Type *, 8> Types; SmallVector<llvm::Type *, 8> Types;
bool hasPacks = false;
void collectTypes(IRGenModule &IGM, NominalTypeDecl *nominal) { void collectTypes(IRGenModule &IGM, NominalTypeDecl *nominal) {
GenericTypeRequirements requirements(IGM, nominal); GenericTypeRequirements requirements(IGM, nominal);
collectTypes(IGM, requirements); collectTypes(IGM, requirements);
} }
@@ -59,6 +60,7 @@ struct GenericArguments {
void collectTypes(IRGenModule &IGM, void collectTypes(IRGenModule &IGM,
const GenericTypeRequirements &requirements) { const GenericTypeRequirements &requirements) {
for (auto &requirement : requirements.getRequirements()) { for (auto &requirement : requirements.getRequirements()) {
hasPacks = hasPacks || requirement.isAnyPack();
Types.push_back(requirement.getType(IGM)); Types.push_back(requirement.getType(IGM));
} }
} }

View File

@@ -0,0 +1,8 @@
// RUN: %target-swift-frontend %s -target %target-swift-5.9-abi-triple -emit-irgen | %IRGenFileCheck %s
// CHECK: Attrs: noinline nounwind{{$}}
// CHECK-NEXT: define {{.*}}@"$s13rdar1616068921PVMa"
public struct P<each T> {
public var teas: (repeat each T)
}