[Driver] Check that the iOS deployment target is iOS 10 or earlier if
the target is 32-bit.

The following changes are made to the driver since 32-bit apps do not
run on iOS 11 or later:

- If the deployment target is set explicitly, either with a command-line
  option or an environment variable, the driver should report an error
  if the version is greater than iOS 10.

- In the case where the deployment target is not set explicitly and the
  default is inferred from the target triple or SDK version, it should
  use a maximum default of iOS 10.99.99.

rdar://problem/32230613

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306922 91177308-0d34-0410-b5e6-96231b3b80d8
(cherry picked from commit 2fa920a582d0d13b17f0f9855d221e5f4a78f4c0)

Conflicts:
lib/Driver/ToolChains/Darwin.cpp
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index a99bcc8..d734f47 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -135,6 +135,9 @@
     "unable to open CC_PRINT_OPTIONS file: %0">;
 def err_drv_preamble_format : Error<
     "incorrect format for -preamble-bytes=N,END">;
+def err_invalid_ios_deployment_target : Error<
+  "invalid iOS deployment version '%0', iOS 10 is the maximum deployment "
+  "target for 32-bit targets">;
 def err_drv_conflicting_deployment_targets : Error<
   "conflicting deployment targets, both '%0' and '%1' are present in environment">;
 def err_arc_unsupported_on_runtime : Error<
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 68d134c..1e49d19 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -593,6 +593,17 @@
       Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
                       options::OPT_mwatchos_simulator_version_min_EQ);
 
+  unsigned Major, Minor, Micro;
+  bool HadExtra;
+
+  // iOS 10 is the maximum deployment target for 32-bit targets.
+  if (iOSVersion && getTriple().isArch32Bit() &&
+      Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
+                                HadExtra) &&
+      Major > 10)
+    getDriver().Diag(diag::err_invalid_ios_deployment_target)
+        << iOSVersion->getAsString(Args);
+
   // Add a macro to differentiate between m(iphone|tv|watch)os-version-min=X.Y and
   // -m(iphone|tv|watch)simulator-version-min=X.Y.
   if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ) ||
@@ -634,6 +645,14 @@
     if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
       WatchOSTarget = env;
 
+    // iOS 10 is the maximum deployment target for 32-bit targets.
+    if (!iOSTarget.empty() && getTriple().isArch32Bit() &&
+        Driver::GetReleaseVersion(iOSTarget.c_str(), Major, Minor, Micro,
+                                  HadExtra) &&
+        Major > 10)
+      getDriver().Diag(diag::err_invalid_ios_deployment_target)
+          << std::string("IPHONEOS_DEPLOYMENT_TARGET=") + iOSTarget;
+
     // If there is no command-line argument to specify the Target version and
     // no environment variable defined, see if we can set the default based
     // on -isysroot.
@@ -751,8 +770,6 @@
     llvm_unreachable("Unable to infer Darwin variant");
 
   // Set the tool chain target information.
-  unsigned Major, Minor, Micro;
-  bool HadExtra;
   if (Platform == MacOS) {
     assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
            "Unknown target platform!");
@@ -768,6 +785,13 @@
         HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
       getDriver().Diag(diag::err_drv_invalid_version_number)
           << iOSVersion->getAsString(Args);
+    // iOS 10 is the maximum deployment target for 32-bit targets. If the
+    // inferred deployment target is iOS 11 or later, set it to 10.99.
+    if (getTriple().isArch32Bit() && Major >= 11) {
+      Major = 10;
+      Minor = 99;
+      Micro = 99;
+    }
   } else if (Platform == TvOS) {
     if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
                                    Micro, HadExtra) || HadExtra ||
diff --git a/test/Driver/darwin-version.c b/test/Driver/darwin-version.c
index 8f08bb9..c11a2df 100644
--- a/test/Driver/darwin-version.c
+++ b/test/Driver/darwin-version.c
@@ -10,6 +10,41 @@
 // RUN: %clang -target armv6-apple-darwin9 -miphoneos-version-min=3.0 -c %s -### 2>&1 | \
 // RUN:   FileCheck --check-prefix=CHECK-VERSION-IOS3 %s
 // CHECK-VERSION-IOS3: "armv6k-apple-ios3.0.0"
+
+// RUN: env IPHONEOS_DEPLOYMENT_TARGET=11.0 \
+// RUN:   %clang -target armv7-apple-ios9.0 -c -### %s 2> %t.err
+// RUN:   FileCheck --input-file=%t.err --check-prefix=CHECK-VERSION-IOS4 %s
+// CHECK-VERSION-IOS4: invalid iOS deployment version 'IPHONEOS_DEPLOYMENT_TARGET=11.0'
+
+// RUN: %clang -target armv7-apple-ios9.0 -miphoneos-version-min=11.0 -c -### %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err --check-prefix=CHECK-VERSION-IOS5 %s
+// CHECK-VERSION-IOS5: invalid iOS deployment version '-miphoneos-version-min=11.0'
+
+// RUN: %clang -target i386-apple-darwin -mios-simulator-version-min=11.0 -c -### %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err --check-prefix=CHECK-VERSION-IOS6 %s
+// CHECK-VERSION-IOS6: invalid iOS deployment version '-mios-simulator-version-min=11.0'
+
+// RUN: %clang -target armv7-apple-ios11.1 -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-VERSION-IOS7 %s
+// CHECK-VERSION-IOS7: thumbv7-apple-ios10.99.99
+
+// RUN: env IPHONEOS_DEPLOYMENT_TARGET=11.0 \
+// RUN:   %clang -target arm64-apple-ios11.0 -c -### %s 2>&1 | \
+// RUN:   FileCheck --check-prefix=CHECK-VERSION-IOS8 %s
+// CHECK-VERSION-IOS8: arm64-apple-ios11.0.0
+
+// RUN: %clang -target arm64-apple-ios11.0 -miphoneos-version-min=11.0 -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-VERSION-IOS9 %s
+// CHECK-VERSION-IOS9: arm64-apple-ios11.0.0
+
+// RUN: %clang -target x86_64-apple-darwin -mios-simulator-version-min=11.0 -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-VERSION-IOS10 %s
+// CHECK-VERSION-IOS10: x86_64-apple-ios11.0.0
+
+// RUN: %clang -target arm64-apple-ios11.1 -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-VERSION-IOS11 %s
+// CHECK-VERSION-IOS11: arm64-apple-ios11.1.0
+
 // RUN: %clang -target i686-apple-darwin8 -c %s -### 2>&1 | \
 // RUN:   FileCheck --check-prefix=CHECK-VERSION-OSX4 %s
 // RUN: %clang -target i686-apple-darwin9 -mmacosx-version-min=10.4 -c %s -### 2>&1 | \