Skip to content

Commit 634084b

Browse files
committed
[MacrosOnImports] Don't import !swift modules
Inheriting a clang import marked `requires: !swift` will always result in an error. This skips such imports, which *may* result in name lookup errors instead, but also may not, depending on the module. rdar://161795145
1 parent 412fffc commit 634084b

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2852,6 +2852,12 @@ ClangModuleUnit *ClangImporter::Implementation::getWrapperForModule(
28522852
auto addImplicitImport = [&implicitImportInfo, &Imported,
28532853
this](const clang::Module *M,
28542854
bool guaranteedUnique) {
2855+
const bool cannotBeImported = llvm::any_of(M->Requirements, [](auto &Req) {
2856+
return !Req.RequiredState && Req.FeatureName == "swift";
2857+
});
2858+
if (cannotBeImported) {
2859+
return;
2860+
}
28552861
ImportPath::Builder builder = getSwiftModulePath(M);
28562862
if (!guaranteedUnique && Imported.count(builder.get()))
28572863
return;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// REQUIRES: swift_feature_SafeInteropWrappers
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: split-file --leading-lines %s %t
5+
6+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/succeed.swift
7+
// RUN: not %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/fail.swift -dump-source-file-imports 2>&1 | %FileCheck %s
8+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/fail.swift -verify -verify-additional-file %t%{fs-sep}Inputs%{fs-sep}B1.h -verify-ignore-macro-note
9+
10+
// Tests that we don't try to import modules that don't work well with Swift
11+
12+
// CHECK: imports for {{.*}}fail.swift:
13+
// CHECK-NEXT: Swift
14+
// CHECK-NEXT: _StringProcessing
15+
// CHECK-NEXT: _SwiftConcurrencyShims
16+
// CHECK-NEXT: _Concurrency
17+
// CHECK-NEXT: B1
18+
// CHECK-NEXT: A1
19+
20+
// CHECK-NEXT: imports for A1.foo:
21+
22+
// CHECK-NEXT: imports for @__swiftmacro{{.*}}foo{{.*}}_SwiftifyImport{{.*}}.swift:
23+
// CHECK-NEXT: Swift
24+
// CHECK-NEXT: B1
25+
// CHECK-NEXT: _StringProcessing
26+
// CHECK-NEXT: _SwiftConcurrencyShims
27+
// CHECK-NEXT: _Concurrency
28+
29+
//--- Inputs/module.modulemap
30+
module A1 {
31+
explicit module B1 {
32+
header "B1.h"
33+
explicit module C1 {
34+
header "C1.h"
35+
requires !swift
36+
}
37+
}
38+
}
39+
40+
//--- Inputs/B1.h
41+
#pragma once
42+
43+
#include "C1.h"
44+
#define __sized_by(s) __attribute__((__sized_by__(s)))
45+
46+
// We can use bar without C1 causing errors
47+
void bar(void * _Nonnull __sized_by(size), int size);
48+
// foo causes an error when we try to refer to c1_t from the '!swift' module C1
49+
c1_t foo(void * _Nonnull __sized_by(size), int size);
50+
/*
51+
expected-note@-2{{'foo' declared here}}
52+
expected-expansion@-3:52{{
53+
expected-error@2:110{{cannot find type 'c1_t' in scope}}
54+
}}
55+
*/
56+
57+
//--- Inputs/C1.h
58+
#pragma once
59+
60+
typedef int c1_t;
61+
62+
//--- fail.swift
63+
import A1.B1
64+
65+
public func callUnsafe(_ p: UnsafeMutableRawPointer) {
66+
let _ = foo(p, 13)
67+
}
68+
public func callSafe(_ p: UnsafeMutableRawBufferPointer) {
69+
let _ = foo(p) // expected-error{{cannot convert value of type 'UnsafeMutableRawBufferPointer' to expected argument type 'UnsafeMutableRawPointer'}}
70+
// expected-error@-1{{missing argument}}
71+
}
72+
73+
//--- succeed.swift
74+
import A1.B1
75+
76+
public func callUnsafe(_ p: UnsafeMutableRawPointer) {
77+
bar(p, 13)
78+
}
79+
public func callSafe(_ p: UnsafeMutableRawBufferPointer) {
80+
bar(p)
81+
}

0 commit comments

Comments
 (0)