Skip to content

Commit 9bf1d28

Browse files
authored
Merge pull request #82105 from swiftlang/gaborh/disable-non-aliased-instantiations-on-6.2
[6.2][cxx-interop] Only swiftify template instantiations behind typealiases
2 parents 1507bcd + 4590d55 commit 9bf1d28

File tree

3 files changed

+47
-10
lines changed

3 files changed

+47
-10
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@
6262
#include "clang/AST/DeclObjCCommon.h"
6363
#include "clang/AST/Expr.h"
6464
#include "clang/AST/PrettyPrinter.h"
65-
#include "clang/AST/StmtVisitor.h"
6665
#include "clang/AST/RecordLayout.h"
66+
#include "clang/AST/RecursiveASTVisitor.h"
67+
#include "clang/AST/StmtVisitor.h"
6768
#include "clang/AST/Type.h"
6869
#include "clang/Basic/Specifiers.h"
6970
#include "clang/Basic/TargetInfo.h"
@@ -9119,6 +9120,24 @@ namespace {
91199120
};
91209121
} // namespace
91219122

9123+
namespace {
9124+
// Searches for template instantiations that are not behind type aliases.
9125+
// FIXME: make sure the generated code compiles for template
9126+
// instantiations that are not behind type aliases.
9127+
struct UnaliasedInstantiationVisitor
9128+
: clang::RecursiveASTVisitor<UnaliasedInstantiationVisitor> {
9129+
bool hasUnaliasedInstantiation = false;
9130+
9131+
bool TraverseTypedefType(const clang::TypedefType *) { return true; }
9132+
9133+
bool
9134+
VisitTemplateSpecializationType(const clang::TemplateSpecializationType *) {
9135+
hasUnaliasedInstantiation = true;
9136+
return false;
9137+
}
9138+
};
9139+
} // namespace
9140+
91229141
// Don't try to transform any Swift types that _SwiftifyImport doesn't know how
91239142
// to handle.
91249143
static bool SwiftifiableCountedByPointerType(Type swiftType) {
@@ -9173,6 +9192,13 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) {
91739192
if (ClangDecl->getNumParams() != MappedDecl->getParameters()->size())
91749193
return;
91759194

9195+
{
9196+
UnaliasedInstantiationVisitor visitor;
9197+
visitor.TraverseType(ClangDecl->getType());
9198+
if (visitor.hasUnaliasedInstantiation)
9199+
return;
9200+
}
9201+
91769202
llvm::SmallString<128> MacroString;
91779203
// We only attach the macro if it will produce an overload. Any __counted_by
91789204
// will produce an overload, since UnsafeBufferPointer is still an improvement

test/Interop/Cxx/stdlib/Inputs/std-span.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,20 @@ inline SpanOfInt MixedFuncWithMutableSafeWrapper7(int * __counted_by(len) p, int
165165
return SpanOfInt(p, len);
166166
}
167167

168+
template <typename X>
169+
struct S {};
170+
168171
struct SpanWithoutTypeAlias {
169172
std::span<const int> bar() [[clang::lifetimebound]];
170173
void foo(std::span<const int> s [[clang::noescape]]);
174+
void otherTemplatedType(ConstSpanOfInt copy [[clang::noescape]], S<int>);
175+
void otherTemplatedType2(ConstSpanOfInt copy [[clang::noescape]], S<int> *);
171176
};
172177

173178
inline void func(ConstSpanOfInt copy [[clang::noescape]]) {}
174179
inline void mutableKeyword(SpanOfInt copy [[clang::noescape]]) {}
175180

181+
inline void spanWithoutTypeAlias(std::span<const int> s [[clang::noescape]]) {}
182+
inline void mutableSpanWithoutTypeAlias(std::span<int> s [[clang::noescape]]) {}
183+
176184
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_STD_SPAN_H

test/Interop/Cxx/stdlib/std-span-interface.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RUN: %FileCheck %s < %t/interface.swift
44

55
// Make sure we trigger typechecking and SIL diagnostics
6-
// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -I %S/Inputs -enable-experimental-feature SafeInteropWrappers -enable-experimental-feature Lifetimes -cxx-interoperability-mode=default -strict-memory-safety -warnings-as-errors -Xcc -std=c++20 %s
6+
// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -I %S/Inputs -enable-experimental-feature SafeInteropWrappers -enable-experimental-feature Lifetimes -cxx-interoperability-mode=default -strict-memory-safety -warnings-as-errors -verify -Xcc -std=c++20 %s
77

88
// REQUIRES: swift_feature_SafeInteropWrappers
99
// REQUIRES: swift_feature_Lifetimes
@@ -34,15 +34,10 @@ import CxxStdlib
3434
// CHECK-NEXT: }
3535
// CHECK: struct SpanWithoutTypeAlias {
3636
// CHECK-NEXT: init()
37-
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
38-
// CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
39-
// CHECK-NEXT: @_lifetime(borrow self)
40-
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func bar() -> Span<CInt>
4137
// CHECK-NEXT: mutating func bar() -> std.{{.*}}span<__cxxConst<CInt>, _C{{.*}}_{{.*}}>
42-
// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop
43-
// CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
44-
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func foo(_ s: Span<CInt>)
4538
// CHECK-NEXT: mutating func foo(_ s: std.{{.*}}span<__cxxConst<CInt>, _C{{.*}}_{{.*}}>)
39+
// CHECK-NEXT: mutating func otherTemplatedType(_ copy: ConstSpanOfInt, _: S<CInt>)
40+
// CHECK-NEXT: mutating func otherTemplatedType2(_ copy: ConstSpanOfInt, _: UnsafeMutablePointer<S<CInt>>!)
4641
// CHECK-NEXT: }
4742

4843
// CHECK: /// This is an auto-generated wrapper for safer interop
@@ -150,7 +145,7 @@ func callMethodWithSafeWrapper(_ x: inout X, s: Span<CInt>) {
150145
}
151146

152147
func callFooBar(_ x: inout SpanWithoutTypeAlias, _ s: ConstSpanOfInt) {
153-
let _: Span<CInt> = x.bar()
148+
let _: Span<CInt> = x.bar() // expected-error {{cannot convert value of type}}
154149
unsafe x.foo(s)
155150
}
156151

@@ -242,3 +237,11 @@ func callMixedFuncWithSafeWrapper7(_ p: UnsafeBufferPointer<CInt>) {
242237
func callMutableKeyword(_ span: inout MutableSpan<CInt>) {
243238
mutableKeyword(&span)
244239
}
240+
241+
func callSpanWithoutTypeAlias(_ span: Span<CInt>) {
242+
spanWithoutTypeAlias(span) // expected-error {{cannot convert value of type}}
243+
}
244+
245+
func callMutableSpanWithoutTypeAlias(_ span: consuming MutableSpan<CInt>) {
246+
mutableSpanWithoutTypeAlias(&span) // expected-error {{cannot convert value of type}}
247+
}

0 commit comments

Comments
 (0)