Skip to content

Commit c090816

Browse files
author
Harlan Haskins
committed
[ModuleInterfaces] Combine the normalized target triple into the cache hash
Previously, we'd combine just the target architecture, and rely on the fact that the .swiftinterface is in a reasonably-target-specific subdirectory to include enough entropy to avoid hash collisions. But in the presence of a VFS or if two targets are sharing the same .swiftinterface file (which can sometimes happen in tests), they will collide since the hash only includes architecture. Instead, use the same normalization that the serialized module loader uses, and serialize the normalized target triple instead. Fixes rdar://55881335
1 parent 1a1f731 commit c090816

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,12 +391,15 @@ class ModuleInterfaceLoaderImpl {
391391
// anyways.
392392
H = hash_combine(H, interfacePath);
393393

394-
// Include the target CPU architecture. In practice, .swiftinterface files
395-
// will be in architecture-specific subdirectories and would have
396-
// architecture-specific pieces #if'd out. However, it doesn't hurt to
394+
// Include the normalized target triple. In practice, .swiftinterface files
395+
// will be in target-specific subdirectories and would have
396+
// target-specific pieces #if'd out. However, it doesn't hurt to
397397
// include it, and it guards against mistakenly reusing cached modules
398-
// across architectures.
399-
H = hash_combine(H, SubInvocation.getLangOptions().Target.getArchName());
398+
// across targets. Note that this normalization explicitly doesn't
399+
// include the minimum deployment target (e.g. the '12.0' in 'ios12.0').
400+
auto normalizedTargetTriple =
401+
getTargetSpecificModuleTriple(SubInvocation.getLangOptions().Target);
402+
H = hash_combine(H, normalizedTargetTriple.str());
400403

401404
// The SDK path is going to affect how this module is imported, so include
402405
// it.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/MCP)
3+
4+
// This test makes sure that the module cache hash properly distinguishes
5+
// between different targets, even when the path to the module interface is
6+
// the same for multiple targets.
7+
8+
// 1. Build a .swiftinterface for a dummy module.
9+
10+
// RUN: %target-swift-frontend -typecheck -target x86_64-apple-macosx10.9 -emit-module-interface-path %t/SwiftModule.swiftinterface.tmp -parse-stdlib %s -module-name SwiftModule
11+
12+
// 2. Remove the -target line from the .swiftinterface. Clients will build using their target.
13+
14+
// RUN: sed -E 's/-target [^ ]+//g' %t/SwiftModule.swiftinterface.tmp > %t/SwiftModule.swiftinterface
15+
16+
// 3. Build for a bunch of different x86_64 targets, and ensure they all succeed by putting something else in the module cache.
17+
18+
// RUN: echo 'import SwiftModule' > %t/test.swift
19+
20+
// RUN: %target-swift-frontend -typecheck -sdk '' -target x86_64-apple-macosx10.9 -module-cache-path %t/MCP -parse-stdlib -I %t %t/test.swift
21+
// RUN: %target-swift-frontend -typecheck -sdk '' -target x86_64-apple-tvos13.0 -module-cache-path %t/MCP -parse-stdlib -I %t %t/test.swift
22+
// RUN: %target-swift-frontend -typecheck -sdk '' -target x86_64-apple-ios10.0 -module-cache-path %t/MCP -parse-stdlib -I %t %t/test.swift
23+
24+
// 4. Test iOS again, but with a newer minimum deployment target
25+
// RUN: %target-swift-frontend -typecheck -sdk '' -target x86_64-apple-ios13.0 -module-cache-path %t/MCP -parse-stdlib -I %t %t/test.swift
26+
27+
// 5. Make sure there are only 3 .swiftmodules in the cache path (because iOS was reused)
28+
// RUN: ls %t/MCP/*.swiftmodule | count 3

0 commit comments

Comments
 (0)