Skip to content

Commit cfbfb58

Browse files
committed
AST: Only apply MemberImportVisibility to lookups from the main module.
MemberImportVisibility rules should only apply to source code in the main module. The rules were being applied when resolving witnesses for synthesized Hashable conformances on CF types imported by ClangImporter, which caused the lookups to fail and bad conformances to be generated. Resolves #78870 and rdar://142433039.
1 parent cfb9eda commit cfbfb58

File tree

3 files changed

+50
-13
lines changed

3 files changed

+50
-13
lines changed

lib/AST/NameLookup.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2330,22 +2330,27 @@ ObjCCategoryNameMap ClassDecl::getObjCCategoryNameMap() {
23302330
ObjCCategoryNameMap());
23312331
}
23322332

2333-
static bool missingImportForMemberDecl(const DeclContext *dc, ValueDecl *decl) {
2334-
// Only require explicit imports for members when MemberImportVisibility is
2335-
// enabled.
2336-
auto &ctx = dc->getASTContext();
2333+
/// Determines whether MemberImportVisiblity should be enforced for lookups in
2334+
/// the given context.
2335+
static bool shouldRequireImportsInContext(const DeclContext *lookupContext) {
2336+
auto &ctx = lookupContext->getASTContext();
23372337
if (!ctx.LangOpts.hasFeature(Feature::MemberImportVisibility))
23382338
return false;
23392339

2340-
return !dc->isDeclImported(decl);
2340+
// Code outside of the main module (which is often synthesized) isn't subject
2341+
// to MemberImportVisibility rules.
2342+
if (lookupContext->getParentModule() != ctx.MainModule)
2343+
return false;
2344+
2345+
return true;
23412346
}
23422347

23432348
/// Determine whether the given declaration is an acceptable lookup
23442349
/// result when searching from the given DeclContext.
2345-
static bool isAcceptableLookupResult(const DeclContext *dc,
2346-
NLOptions options,
2350+
static bool isAcceptableLookupResult(const DeclContext *dc, NLOptions options,
23472351
ValueDecl *decl,
2348-
bool onlyCompleteObjectInits) {
2352+
bool onlyCompleteObjectInits,
2353+
bool requireImport) {
23492354
// Filter out designated initializers, if requested.
23502355
if (onlyCompleteObjectInits) {
23512356
if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
@@ -2373,10 +2378,9 @@ static bool isAcceptableLookupResult(const DeclContext *dc,
23732378

23742379
// Check that there is some import in the originating context that makes this
23752380
// decl visible.
2376-
if (!(options & NL_IgnoreMissingImports)) {
2377-
if (missingImportForMemberDecl(dc, decl))
2381+
if (requireImport && !(options & NL_IgnoreMissingImports))
2382+
if (!dc->isDeclImported(decl))
23782383
return false;
2379-
}
23802384

23812385
return true;
23822386
}
@@ -2567,6 +2571,7 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
25672571
DeclNameRef member, NLOptions options) const {
25682572
using namespace namelookup;
25692573
QualifiedLookupResult decls;
2574+
auto &ctx = DC->getASTContext();
25702575

25712576
// Tracking for the nominal types we'll visit.
25722577
SmallVector<NominalTypeDecl *, 4> stack;
@@ -2593,6 +2598,9 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
25932598
// Whether we only want to return complete object initializers.
25942599
bool onlyCompleteObjectInits = false;
25952600

2601+
// Whether to enforce MemberImportVisibility import restrictions.
2602+
bool requireImport = shouldRequireImportsInContext(DC);
2603+
25962604
// Visit all of the nominal types we know about, discovering any others
25972605
// we need along the way.
25982606
bool wantProtocolMembers = (options & NL_ProtocolMembers);
@@ -2625,7 +2633,8 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
26252633
if ((options & NL_OnlyMacros) && !isa<MacroDecl>(decl))
26262634
continue;
26272635

2628-
if (isAcceptableLookupResult(DC, options, decl, onlyCompleteObjectInits))
2636+
if (isAcceptableLookupResult(DC, options, decl, onlyCompleteObjectInits,
2637+
requireImport))
26292638
decls.push_back(decl);
26302639
}
26312640

@@ -2762,6 +2771,9 @@ AnyObjectLookupRequest::evaluate(Evaluator &evaluator, const DeclContext *dc,
27622771
member.getFullName(), allDecls);
27632772
}
27642773

2774+
/// Whether to enforce MemberImportVisibility import restrictions.
2775+
bool requireImport = shouldRequireImportsInContext(dc);
2776+
27652777
// For each declaration whose context is not something we've
27662778
// already visited above, add it to the list of declarations.
27672779
llvm::SmallPtrSet<ValueDecl *, 4> knownDecls;
@@ -2794,7 +2806,8 @@ AnyObjectLookupRequest::evaluate(Evaluator &evaluator, const DeclContext *dc,
27942806
// result, add it to the list.
27952807
if (knownDecls.insert(decl).second &&
27962808
isAcceptableLookupResult(dc, options, decl,
2797-
/*onlyCompleteObjectInits=*/false))
2809+
/*onlyCompleteObjectInits=*/false,
2810+
requireImport))
27982811
decls.push_back(decl);
27992812
}
28002813

test/ClangImporter/Security_test.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify
2+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -enable-upcoming-feature MemberImportVisibility -verify
23

34
// REQUIRES: objc_interop
45

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-frontend -emit-sil %s -verify
2+
// RUN: %target-swift-frontend -emit-sil %s -enable-upcoming-feature MemberImportVisibility -verify
3+
4+
// REQUIRES: VENDOR=apple
5+
// REQUIRES: swift_feature_MemberImportVisibility
6+
7+
import CoreFoundation
8+
9+
public func takesHashable<T: Hashable>(_ t: T) {}
10+
11+
public func takesCFObjects(
12+
_ string: CFString,
13+
_ number: CFNumber,
14+
_ date: CFDate,
15+
_ data: CFData,
16+
_ set: CFSet,
17+
) {
18+
takesHashable(string)
19+
takesHashable(number)
20+
takesHashable(date)
21+
takesHashable(data)
22+
takesHashable(set)
23+
}

0 commit comments

Comments
 (0)