Skip to content

Commit 200c51c

Browse files
authored
Merge pull request #38288 from nkcsgexi/cherry-pick-79746530
[5.5] ModuleInterface: sanitize arch when interface file name and encoded flags disagree
2 parents 336681e + cb3713e commit 200c51c

File tree

5 files changed

+55
-7
lines changed

5 files changed

+55
-7
lines changed

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,10 @@ class SerializedASTFile final : public LoadedFile {
458458
}
459459
};
460460

461+
/// Extract compiler arguments from an interface file buffer.
462+
bool extractCompilerFlagsFromInterface(StringRef interfacePath,
463+
StringRef buffer, llvm::StringSaver &ArgSaver,
464+
SmallVectorImpl<const char *> &SubArgs);
461465

462466
} // end namespace swift
463467

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,23 +1192,21 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
11921192
auto VersRe = getSwiftInterfaceFormatVersionRegex();
11931193
auto CompRe = getSwiftInterfaceCompilerVersionRegex();
11941194
auto FlagRe = getSwiftInterfaceModuleFlagsRegex();
1195-
SmallVector<StringRef, 1> VersMatches, FlagMatches, CompMatches;
1195+
SmallVector<StringRef, 1> VersMatches, CompMatches;
11961196

11971197
if (!VersRe.match(SB, &VersMatches)) {
11981198
diagnose(interfacePath, diagnosticLoc,
11991199
diag::error_extracting_version_from_module_interface);
12001200
return true;
12011201
}
1202-
if (!FlagRe.match(SB, &FlagMatches)) {
1202+
if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver, SubArgs)) {
12031203
diagnose(interfacePath, diagnosticLoc,
12041204
diag::error_extracting_version_from_module_interface);
12051205
return true;
12061206
}
12071207
assert(VersMatches.size() == 2);
1208-
assert(FlagMatches.size() == 2);
12091208
// FIXME We should diagnose this at a location that makes sense:
12101209
auto Vers = swift::version::Version(VersMatches[1], SourceLoc(), &Diags);
1211-
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], ArgSaver, SubArgs);
12121210

12131211
if (CompRe.match(SB, &CompMatches)) {
12141212
assert(CompMatches.size() == 2);

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323
#include "swift/Basic/SourceManager.h"
2424
#include "swift/Basic/Version.h"
2525

26+
#include "llvm/Option/ArgList.h"
2627
#include "llvm/ADT/SmallString.h"
2728
#include "llvm/ADT/StringSet.h"
2829
#include "llvm/Support/Debug.h"
2930
#include "llvm/Support/FileSystem.h"
3031
#include "llvm/Support/Host.h"
3132
#include "llvm/Support/MemoryBuffer.h"
3233
#include "llvm/Support/Path.h"
34+
#include "llvm/Support/CommandLine.h"
3335
#include <system_error>
3436

3537
using namespace swift;
@@ -959,6 +961,42 @@ void swift::serialization::diagnoseSerializedASTLoadFailure(
959961
}
960962
}
961963

964+
bool swift::extractCompilerFlagsFromInterface(StringRef interfacePath,
965+
StringRef buffer,
966+
llvm::StringSaver &ArgSaver,
967+
SmallVectorImpl<const char *> &SubArgs) {
968+
SmallVector<StringRef, 1> FlagMatches;
969+
auto FlagRe = llvm::Regex("^// swift-module-flags:(.*)$", llvm::Regex::Newline);
970+
if (!FlagRe.match(buffer, &FlagMatches))
971+
return true;
972+
assert(FlagMatches.size() == 2);
973+
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], ArgSaver, SubArgs);
974+
975+
auto intFileName = llvm::sys::path::filename(interfacePath);
976+
977+
// Sanitize arch if the file name and the encoded flags disagree.
978+
// It's a known issue that we are using arm64e interfaces contents for the arm64 target,
979+
// meaning the encoded module flags are using -target arm64e-x-x. Fortunately,
980+
// we can tell the target arch from the interface file name, so we could sanitize
981+
// the target to use by inferring target from the file name.
982+
StringRef arm64 = "arm64";
983+
StringRef arm64e = "arm64e";
984+
if (intFileName.contains(arm64) && !intFileName.contains(arm64e)) {
985+
for (unsigned I = 1; I < SubArgs.size(); ++I) {
986+
if (strcmp(SubArgs[I - 1], "-target") != 0) {
987+
continue;
988+
}
989+
StringRef triple(SubArgs[I]);
990+
if (triple.startswith(arm64e)) {
991+
SubArgs[I] = ArgSaver.save((llvm::Twine(arm64) +
992+
triple.substr(arm64e.size())).str()).data();
993+
}
994+
}
995+
}
996+
997+
return false;
998+
}
999+
9621000
bool SerializedModuleLoaderBase::canImportModule(
9631001
ImportPath::Element mID) {
9641002
// Look on disk.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/Bar.swiftmodule)
3+
// RUN: echo "// swift-interface-format-version: 1.0" > %t/arm64.swiftinterface
4+
// RUN: echo "// swift-module-flags: -module-name arm64 -target arm64e-apple-macos11.0" >> %t/arm64.swiftinterface
5+
6+
import arm64
7+
8+
// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -target arm64-apple-macos11.0
9+
// RUN: %FileCheck %s < %t/deps.json
10+
11+
// CHECK-NOT: arm64e-apple-macos11.0

test/stdlib/Reflection_objc.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
// REQUIRES: executable_test
1010
// REQUIRES: objc_interop
1111

12-
// rdar://problem/75006694
13-
// XFAIL: OS=macosx && CPU=arm64
14-
1512
//
1613
// DO NOT add more tests to this file. Add them to test/1_stdlib/Runtime.swift.
1714
//

0 commit comments

Comments
 (0)