Skip to content

Commit c66de29

Browse files
authored
Merge pull request #84896 from hnrklssn/inherit-skip-unfulfilled-require
[MacrosOnImports] Don't inherit imports with unfulfilled `required` clauses
2 parents dc4ff24 + 8542903 commit c66de29

File tree

3 files changed

+242
-1
lines changed

3 files changed

+242
-1
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2848,10 +2848,22 @@ ClangModuleUnit *ClangImporter::Implementation::getWrapperForModule(
28482848
for (auto UI : implicitImportInfo.AdditionalUnloadedImports)
28492849
Imported.insert(UI.module.getImportPath());
28502850
assert(implicitImportInfo.AdditionalImports.empty());
2851+
const bool cxx = SwiftContext.LangOpts.EnableCXXInterop;
28512852

2852-
auto addImplicitImport = [&implicitImportInfo, &Imported,
2853+
auto addImplicitImport = [&implicitImportInfo, &Imported, cxx,
28532854
this](const clang::Module *M,
28542855
bool guaranteedUnique) {
2856+
const bool cannotBeImported =
2857+
llvm::any_of(M->Requirements, [cxx](auto &Req) {
2858+
if (Req.FeatureName == "swift")
2859+
return !Req.RequiredState;
2860+
if (Req.FeatureName == "cplusplus")
2861+
return Req.RequiredState != cxx;
2862+
return false;
2863+
});
2864+
if (cannotBeImported) {
2865+
return;
2866+
}
28552867
ImportPath::Builder builder = getSwiftModulePath(M);
28562868
if (!guaranteedUnique && Imported.count(builder.get()))
28572869
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+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// REQUIRES: swift_feature_SafeInteropWrappers
2+
3+
// Tests that we don't try to import modules that don't work well with C++ interop (when enabled)
4+
5+
// RUN: %empty-directory(%t)
6+
// RUN: split-file --leading-lines %s %t
7+
8+
// Case 1: a.swift calls A1.B1.foo with C++ interop
9+
// RUN: not %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -cxx-interoperability-mode=default -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/a.swift -dump-source-file-imports 2>&1 | %FileCheck --check-prefixes CHECK-A,CHECK-A-CXX %s
10+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -cxx-interoperability-mode=default -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/a.swift -verify -verify-additional-prefix cxx- -verify-additional-file %t%{fs-sep}Inputs%{fs-sep}B1.h -verify-ignore-macro-note
11+
12+
// Case 2: a.swift calls A1.B1.foo without C++ interop
13+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/a.swift -dump-source-file-imports 2>&1 | %FileCheck --check-prefixes CHECK-A,CHECK-A-C %s
14+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/a.swift -verify
15+
16+
// Case 3: b.swift calls A2.B2.foo with C++ interop
17+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -cxx-interoperability-mode=default -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/b.swift -dump-source-file-imports 2>&1 | %FileCheck --check-prefixes CHECK-B,CHECK-B-CXX %s
18+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -cxx-interoperability-mode=default -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/b.swift -verify
19+
20+
// Case 4: b.swift calls A2.B2.foo without C++ interop
21+
// RUN: not %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/b.swift -dump-source-file-imports 2>&1 | %FileCheck --check-prefix CHECK-B %s
22+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -I %t%{fs-sep}Inputs -enable-experimental-feature SafeInteropWrappers %t/b.swift -verify -verify-additional-prefix c- -verify-additional-file %t%{fs-sep}Inputs%{fs-sep}B2.h -verify-ignore-macro-note
23+
24+
// CHECK-A: imports for {{.*}}a.swift:
25+
// CHECK-A-NEXT: Swift
26+
// CHECK-A-CXX-NEXT: CxxShim
27+
// CHECK-A-CXX-NEXT: Cxx
28+
// CHECK-A-NEXT: _StringProcessing
29+
// CHECK-A-NEXT: _SwiftConcurrencyShims
30+
// CHECK-A-NEXT: _Concurrency
31+
// CHECK-A-NEXT: B1
32+
// CHECK-A-NEXT: A1
33+
// CHECK-A-NEXT: imports for A1.foo:
34+
35+
// CHECK-A-NEXT: imports for @__swiftmacro{{.*}}foo{{.*}}_SwiftifyImport{{.*}}.swift:
36+
// CHECK-A-NEXT: Swift
37+
// CHECK-A-C-NEXT: C1
38+
// CHECK-A-NEXT: B1
39+
// CHECK-A-CXX-NEXT: CxxShim
40+
// CHECK-A-CXX-NEXT: Cxx
41+
// CHECK-A-NEXT: _StringProcessing
42+
// CHECK-A-NEXT: _SwiftConcurrencyShims
43+
// CHECK-A-NEXT: _Concurrency
44+
45+
// CHECK-B: imports for {{.*}}b.swift:
46+
// CHECK-B-NEXT: Swift
47+
// CHECK-B-CXX-NEXT: CxxShim
48+
// CHECK-B-CXX-NEXT: Cxx
49+
// CHECK-B-NEXT: _StringProcessing
50+
// CHECK-B-NEXT: _SwiftConcurrencyShims
51+
// CHECK-B-NEXT: _Concurrency
52+
// CHECK-B-NEXT: B2
53+
// CHECK-B-NEXT: A2
54+
// CHECK-B-NEXT: imports for A2.bar:
55+
56+
// CHECK-B-NEXT: imports for @__swiftmacro{{.*}}bar{{.*}}_SwiftifyImport{{.*}}.swift:
57+
// CHECK-B-NEXT: Swift
58+
// CHECK-B-CXX-NEXT: C2
59+
// CHECK-B-NEXT: B2
60+
// CHECK-B-CXX-NEXT: CxxShim
61+
// CHECK-B-CXX-NEXT: Cxx
62+
// CHECK-B-NEXT: _StringProcessing
63+
// CHECK-B-NEXT: _SwiftConcurrencyShims
64+
// CHECK-B-NEXT: _Concurrency
65+
66+
67+
//--- Inputs/module.modulemap
68+
module A1 {
69+
explicit module B1 {
70+
header "B1.h"
71+
explicit module C1 {
72+
header "C1.h"
73+
requires !cplusplus
74+
}
75+
}
76+
}
77+
module A2 {
78+
explicit module B2 {
79+
header "B2.h"
80+
explicit module C2 {
81+
header "C2.h"
82+
requires cplusplus
83+
}
84+
}
85+
}
86+
87+
//--- Inputs/B1.h
88+
#pragma once
89+
90+
#include "C1.h"
91+
#define __sized_by(s) __attribute__((__sized_by__(s)))
92+
93+
// foo causes an error with cxx-interop
94+
c1_t foo(void * _Nonnull __sized_by(size), int size);
95+
/*
96+
expected-cxx-note@-2{{'foo' declared here}}
97+
expected-cxx-expansion@-3:54{{
98+
expected-cxx-error@2:110{{cannot find type 'c1_t' in scope}}
99+
}}
100+
*/
101+
102+
//--- Inputs/B2.h
103+
#pragma once
104+
105+
#include "C2.h"
106+
#define __sized_by(s) __attribute__((__sized_by__(s)))
107+
108+
// bar causes an error without cxx-interop
109+
c2_t bar(void * _Nonnull __sized_by(size), int size);
110+
/*
111+
expected-c-note@-2{{'bar' declared here}}
112+
expected-c-expansion@-3:54{{
113+
expected-c-error@2:110{{cannot find type 'c2_t' in scope}}
114+
}}
115+
*/
116+
117+
//--- Inputs/C1.h
118+
#pragma once
119+
120+
typedef int c1_t;
121+
122+
//--- Inputs/C2.h
123+
#pragma once
124+
125+
typedef int c2_t;
126+
127+
//--- a.swift
128+
import A1.B1
129+
130+
public func callUnsafe(_ p: UnsafeMutableRawPointer) {
131+
let _ = foo(p, 13)
132+
}
133+
public func callSafe(_ p: UnsafeMutableRawBufferPointer) {
134+
let _ = foo(p) // expected-cxx-error{{cannot convert value of type 'UnsafeMutableRawBufferPointer' to expected argument type 'UnsafeMutableRawPointer'}}
135+
// expected-cxx-error@-1{{missing argument}}
136+
}
137+
138+
//--- b.swift
139+
import A2.B2
140+
141+
public func callUnsafe(_ p: UnsafeMutableRawPointer) {
142+
let _ = bar(p, 13)
143+
}
144+
public func callSafe(_ p: UnsafeMutableRawBufferPointer) {
145+
let _ = bar(p) // expected-c-error{{cannot convert value of type 'UnsafeMutableRawBufferPointer' to expected argument type 'UnsafeMutableRawPointer'}}
146+
// expected-c-error@-1{{missing argument}}
147+
148+
}

0 commit comments

Comments
 (0)