From 8332b7c03fe0ec3c4b0ed51ae46268e9c637b92f Mon Sep 17 00:00:00 2001 From: Nate Chandler Date: Fri, 3 Oct 2025 07:53:20 -0700 Subject: [PATCH] [VariadicGenerics] Fix memeffect of metadata accessor call. Follow up to https://github.com/swiftlang/swift/pull/84635/. 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 the call to any such accessor is not correctly annotated memory(none). rdar://161606892 --- lib/IRGen/IRGenFunction.h | 5 ++- lib/IRGen/MetadataRequest.cpp | 12 +++---- validation-test/IRGen/rdar161606892_2.swift | 40 +++++++++++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 validation-test/IRGen/rdar161606892_2.swift diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h index 832d6504985a7..43f2b3dbb6ff2 100644 --- a/lib/IRGen/IRGenFunction.h +++ b/lib/IRGen/IRGenFunction.h @@ -395,9 +395,8 @@ class IRGenFunction { // Emit a call to the given generic type metadata access function. MetadataResponse emitGenericTypeMetadataAccessFunctionCall( - llvm::Function *accessFunction, - ArrayRef args, - DynamicMetadataRequest request); + llvm::Function *accessFunction, ArrayRef args, + DynamicMetadataRequest request, bool hasPacks = false); // Emit a reference to the canonical type metadata record for the given AST // type. This can be used to identify the type at runtime. For types with diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 9a325e8e6e85e..970eac1fe4cdf 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -750,7 +750,7 @@ static MetadataResponse emitNominalMetadataRef(IRGenFunction &IGF, theDecl, genericArgs.Types, NotForDefinition); response = IGF.emitGenericTypeMetadataAccessFunctionCall( - accessor, genericArgs.Values, request); + accessor, genericArgs.Values, request, genericArgs.hasPacks); } IGF.setScopedLocalTypeMetadata(theType, response); @@ -2462,11 +2462,9 @@ void irgen::emitCacheAccessFunction(IRGenModule &IGM, llvm::Function *accessor, IGF.Builder.CreateRet(ret); } -MetadataResponse -IRGenFunction::emitGenericTypeMetadataAccessFunctionCall( - llvm::Function *accessFunction, - ArrayRef args, - DynamicMetadataRequest request) { +MetadataResponse IRGenFunction::emitGenericTypeMetadataAccessFunctionCall( + llvm::Function *accessFunction, ArrayRef args, + DynamicMetadataRequest request, bool hasPacks) { SmallVector callArgs; @@ -2490,7 +2488,7 @@ IRGenFunction::emitGenericTypeMetadataAccessFunctionCall( accessFunction, callArgs); call->setDoesNotThrow(); call->setCallingConv(IGM.SwiftCC); - call->setMemoryEffects(allocatedArgsBuffer + call->setMemoryEffects(hasPacks || allocatedArgsBuffer ? llvm::MemoryEffects::inaccessibleOrArgMemOnly() : llvm::MemoryEffects::none()); diff --git a/validation-test/IRGen/rdar161606892_2.swift b/validation-test/IRGen/rdar161606892_2.swift new file mode 100644 index 0000000000000..2651d0d7ef53f --- /dev/null +++ b/validation-test/IRGen/rdar161606892_2.swift @@ -0,0 +1,40 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: %target-build-swift \ +// RUN: -emit-module \ +// RUN: -target %target-swift-5.9-abi-triple \ +// RUN: %t/Library.swift \ +// RUN: -parse-as-library \ +// RUN: -module-name Library \ +// RUN: -emit-module-path %t/Library.swiftmodule + +// RUN: %target-swift-frontend \ +// RUN: %t/Downstream.swift \ +// RUN: -emit-irgen \ +// RUN: -target %target-swift-5.9-abi-triple \ +// RUN: -module-name main \ +// RUN: -lLibrary \ +// RUN: -I %t \ +// RUN: | %FileCheck %t/Downstream.swift --check-prefixes=CHECK,CHECK-OLD + +//--- Library.swift + +public struct Pack { + public init() {} +} + +public func sink(_ t: T) {} + +//--- Downstream.swift + +import Library + +// CHECK: doit +// CHECK: @"$s7Library4PackVMa"{{.*}} [[CALL:#[^,]+]] + +// CHECK: attributes [[CALL]] = { nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) } +@_silgen_name("doit") +func doit(ts: repeat each T, us: repeat each U) { + sink(Pack()) +}