[driver][macOS] Pick the system version for the deployment target
if the SDK is newer than the system

This commit improves the driver by making sure that it picks the system version
for the deployment target when the version of the macOS SDK is newer than the
system version.

rdar://29449467

Differential Revision: https://reviews.llvm.org/D34175

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@305678 91177308-0d34-0410-b5e6-96231b3b80d8
(cherry picked from commit cf092e8c65bbd3abcf4f254e2ad54db83d9eaeb7)
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index d01e31f..c42b08c 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -510,6 +510,27 @@
   }
 }
 
+/// Returns the most appropriate macOS target version for the current process.
+///
+/// If the macOS SDK version is the same or earlier than the system version,
+/// then the SDK version is returned. Otherwise the system version is returned.
+static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
+  unsigned Major, Minor, Micro;
+  llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
+  if (!SystemTriple.isMacOSX())
+    return MacOSSDKVersion;
+  SystemTriple.getMacOSXVersion(Major, Minor, Micro);
+  VersionTuple SystemVersion(Major, Minor, Micro);
+  bool HadExtra;
+  if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro,
+                                 HadExtra))
+    return MacOSSDKVersion;
+  VersionTuple SDKVersion(Major, Minor, Micro);
+  if (SDKVersion > SystemVersion)
+    return SystemVersion.getAsString();
+  return MacOSSDKVersion;
+}
+
 void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
   const OptTable &Opts = getDriver().getOpts();
 
@@ -602,7 +623,7 @@
                 SDK.startswith("iPhoneSimulator"))
               iOSTarget = Version;
             else if (SDK.startswith("MacOSX"))
-              OSXTarget = Version;
+              OSXTarget = getSystemOrSDKMacOSVersion(Version);
             else if (SDK.startswith("WatchOS") ||
                      SDK.startswith("WatchSimulator"))
               WatchOSTarget = Version;
diff --git a/test/Driver/darwin-sdk-vs-os-version.c b/test/Driver/darwin-sdk-vs-os-version.c
new file mode 100644
index 0000000..391f4d5
--- /dev/null
+++ b/test/Driver/darwin-sdk-vs-os-version.c
@@ -0,0 +1,10 @@
+// REQUIRES: system-darwin
+
+// Ensure that we never pick a version that's based on the SDK that's newer than
+// the system version:
+// RUN: rm -rf %t/SDKs/MacOSX10.99.99.sdk
+// RUN: mkdir -p %t/SDKs/MacOSX10.99.99.sdk
+// RUN: %clang -target x86_64-apple-darwin -isysroot %t/SDKs/MacOSX10.99.99.sdk %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MACOSX-SYSTEM-VERSION %s
+
+// CHECK-MACOSX-SYSTEM-VERSION-NOT: 10.99.99"