Skip to content

Commit 8dd9a12

Browse files
committed
Error on duplicate module names in Swift module maps
Duplicate module names on search paths produces an error, but providing duplicate module names in a Swift explicit module map file does not, instead the first entry will be chosen. Modify the module map parser to error on duplicated module names as well.
1 parent 6a6cc48 commit 8dd9a12

File tree

2 files changed

+82
-4
lines changed

2 files changed

+82
-4
lines changed

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ class ExplicitModuleMapParser {
414414
if (moduleName.empty())
415415
return true;
416416

417+
bool didInsert;
417418
if (swiftModulePath.has_value()) {
418419
assert((clangModuleMapPath.empty() &&
419420
clangModulePath.empty()) &&
@@ -425,7 +426,7 @@ class ExplicitModuleMapParser {
425426
isFramework,
426427
isSystem,
427428
swiftModuleCacheKey);
428-
swiftModuleMap.try_emplace(moduleName, std::move(entry));
429+
didInsert = swiftModuleMap.try_emplace(moduleName, std::move(entry)).second;
429430
} else {
430431
assert((!clangModuleMapPath.empty() ||
431432
!clangModulePath.empty()) &&
@@ -436,10 +437,10 @@ class ExplicitModuleMapParser {
436437
isSystem,
437438
isBridgingHeaderDependency,
438439
clangModuleCacheKey);
439-
clangModuleMap.try_emplace(moduleName, std::move(entry));
440+
didInsert = clangModuleMap.try_emplace(moduleName, std::move(entry)).second;
440441
}
441-
442-
return false;
442+
// Prevent duplicate module names.
443+
return !didInsert;
443444
}
444445

445446
llvm::StringSaver Saver;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// UNSUPPORTED: OS=windows-msvc
2+
// RUN: %empty-directory(%t)
3+
// RUN: mkdir -p %t/clang-module-cache
4+
// RUN: mkdir -p %t/inputs
5+
// RUN: split-file %s %t
6+
// RUN: sed -e "s|INPUTDIR|%t|g" -e "s|SWIFTLIBDIR|%swift-lib-dir|g" %t/inputs/valid_map.json.template > %t/inputs/valid_map.json
7+
// RUN: sed -e "s|INPUTDIR|%t|g" -e "s|SWIFTLIBDIR|%swift-lib-dir|g" %t/inputs/map_with_duped_swift_module.json.template > %t/inputs/map_with_duped_swift_module.json
8+
// RUN: sed -e "s|INPUTDIR|%t|g" -e "s|SWIFTLIBDIR|%swift-lib-dir|g" %t/inputs/map_with_duped_clang_module.json.template > %t/inputs/map_with_duped_clang_module.json
9+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/inputs/Foo.swiftmodule -emit-module-doc-path %t/inputs/Foo.swiftdoc -emit-module-source-info -emit-module-source-info-path %t/inputs/Foo.swiftsourceinfo -module-cache-path %t.module-cache %t/foo.swift -module-name Foo
10+
// RUN: %target-swift-emit-pcm -module-name SwiftShims %swift-lib-dir/swift/shims/module.modulemap -o %t/inputs/SwiftShims.pcm
11+
// RUN: %target-swift-emit-pcm -module-name _SwiftConcurrencyShims %swift-lib-dir/swift/shims/module.modulemap -o %t/inputs/_SwiftConcurrencyShims.pcm
12+
13+
// RUN: %target-swift-frontend -typecheck %t/foo.swift -explicit-swift-module-map-file %t/inputs/valid_map.json
14+
// RUN: not %target-swift-frontend -typecheck %t/foo.swift -explicit-swift-module-map-file %t/inputs/map_with_duped_swift_module.json
15+
// RUN: not %target-swift-frontend -typecheck %t/foo.swift -explicit-swift-module-map-file %t/inputs/map_with_duped_clang_module.json
16+
17+
//--- foo.swift
18+
public func foo() {}
19+
20+
//--- inputs/valid_map.json.template
21+
[{
22+
"moduleName": "Foo",
23+
"modulePath": "INPUTDIR/inputs/Foo.swiftmodule",
24+
"docPath": "INPUTDIR/inputs/Foo.swiftdoc",
25+
"sourceInfoPath": "INPUTDIR/inputs/Foo.swiftsourceinfo",
26+
"isFramework": false
27+
},
28+
{
29+
"moduleName": "SwiftShims",
30+
"isFramework": false,
31+
"clangModuleMapPath": "SWIFTLIBDIR/swift/shims/module.modulemap",
32+
"clangModulePath": "INPUTDIR/inputs/SwiftShims.pcm"
33+
}]
34+
35+
//--- inputs/map_with_duped_swift_module.json.template
36+
[{
37+
"moduleName": "Foo",
38+
"modulePath": "INPUTDIR/inputs/Foo.swiftmodule",
39+
"docPath": "INPUTDIR/inputs/Foo.swiftdoc",
40+
"sourceInfoPath": "INPUTDIR/inputs/Foo.swiftsourceinfo",
41+
"isFramework": false
42+
},
43+
{
44+
45+
"moduleName": "Foo",
46+
"modulePath": "INPUTDIR/inputs/Foo.swiftmodule",
47+
"docPath": "INPUTDIR/inputs/Foo.swiftdoc",
48+
"sourceInfoPath": "INPUTDIR/inputs/Foo.swiftsourceinfo",
49+
"isFramework": false
50+
},
51+
{
52+
"moduleName": "SwiftShims",
53+
"isFramework": false,
54+
"clangModuleMapPath": "SWIFTLIBDIR/swift/shims/module.modulemap",
55+
"clangModulePath": "INPUTDIR/inputs/SwiftShims.pcm"
56+
}]
57+
58+
//--- inputs/map_with_duped_clang_module.json.template
59+
[{
60+
"moduleName": "Foo",
61+
"modulePath": "INPUTDIR/inputs/Foo.swiftmodule",
62+
"docPath": "INPUTDIR/inputs/Foo.swiftdoc",
63+
"sourceInfoPath": "INPUTDIR/inputs/Foo.swiftsourceinfo",
64+
"isFramework": false
65+
},
66+
{
67+
"moduleName": "SwiftShims",
68+
"isFramework": false,
69+
"clangModuleMapPath": "SWIFTLIBDIR/swift/shims/module.modulemap",
70+
"clangModulePath": "INPUTDIR/inputs/SwiftShims.pcm"
71+
},
72+
{
73+
"moduleName": "SwiftShims",
74+
"isFramework": false,
75+
"clangModuleMapPath": "SWIFTLIBDIR/swift/shims/module.modulemap",
76+
"clangModulePath": "INPUTDIR/inputs/SwiftShims.pcm"
77+
}]

0 commit comments

Comments
 (0)