[clang] 3a32d2e - [Clang][Sema] Use VersionMap from SDKSettings for remapping tvOS and watchOS availability

Egor Zhdan via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 12 09:53:29 PST 2022


Author: Egor Zhdan
Date: 2022-01-12T17:40:18Z
New Revision: 3a32d2e74e5c03d97a41ef7b0a01f206af62ad4f

URL: https://github.com/llvm/llvm-project/commit/3a32d2e74e5c03d97a41ef7b0a01f206af62ad4f
DIFF: https://github.com/llvm/llvm-project/commit/3a32d2e74e5c03d97a41ef7b0a01f206af62ad4f.diff

LOG: [Clang][Sema] Use VersionMap from SDKSettings for remapping tvOS and watchOS availability

This makes the mapping between iOS & tvOS/watchOS versions more accurate. For example, iOS 9.3 now gets correctly mapped into tvOS 9.2 and not tvOS 9.3.

Before this change, the incorrect mapping could cause excessive or missing warnings for code that specifies availability for iOS, but not for tvOS/watchOS.

rdar://81491680

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

Added: 
    clang/test/Sema/Inputs/AppleTVOS15.0.sdk/SDKSettings.json
    clang/test/Sema/Inputs/WatchOS7.0.sdk/SDKSettings.json

Modified: 
    clang/include/clang/Basic/DarwinSDKInfo.h
    clang/include/clang/Sema/Sema.h
    clang/lib/Sema/Sema.cpp
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/Sema/attr-availability-tvos.c
    clang/test/Sema/attr-availability-watchos.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DarwinSDKInfo.h b/clang/include/clang/Basic/DarwinSDKInfo.h
index b0673dc8b3cd8..df16827debfc0 100644
--- a/clang/include/clang/Basic/DarwinSDKInfo.h
+++ b/clang/include/clang/Basic/DarwinSDKInfo.h
@@ -57,6 +57,20 @@ class DarwinSDKInfo {
                        llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment);
     }
 
+    /// Returns the os-environment mapping pair that's used to represent the
+    /// iOS -> watchOS version mapping.
+    static inline constexpr OSEnvPair iOStoWatchOSPair() {
+      return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
+                       llvm::Triple::WatchOS, llvm::Triple::UnknownEnvironment);
+    }
+
+    /// Returns the os-environment mapping pair that's used to represent the
+    /// iOS -> tvOS version mapping.
+    static inline constexpr OSEnvPair iOStoTvOSPair() {
+      return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
+                       llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment);
+    }
+
   private:
     StorageType Value;
 

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b4d8d1494e705..b1ef02865328f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1565,8 +1565,11 @@ class Sema final {
   /// assignment.
   llvm::DenseMap<const VarDecl *, int> RefsMinusAssignments;
 
+private:
   Optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo;
 
+  bool WarnedDarwinSDKInfoMissing = false;
+
 public:
   Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
        TranslationUnitKind TUKind = TU_Complete,
@@ -1595,8 +1598,10 @@ class Sema final {
   ASTConsumer &getASTConsumer() const { return Consumer; }
   ASTMutationListener *getASTMutationListener() const;
   ExternalSemaSource* getExternalSource() const { return ExternalSource; }
+
   DarwinSDKInfo *getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc,
                                                          StringRef Platform);
+  DarwinSDKInfo *getDarwinSDKInfoForAvailabilityChecking();
 
   ///Registers an external source. If an external source already exists,
   /// creates a multiplex external source and appends to it.

diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 60f37c17c3f18..aaa31adf2e97a 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -60,6 +60,16 @@ ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); }
 DarwinSDKInfo *
 Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc,
                                               StringRef Platform) {
+  auto *SDKInfo = getDarwinSDKInfoForAvailabilityChecking();
+  if (!SDKInfo && !WarnedDarwinSDKInfoMissing) {
+    Diag(Loc, diag::warn_missing_sdksettings_for_availability_checking)
+        << Platform;
+    WarnedDarwinSDKInfoMissing = true;
+  }
+  return SDKInfo;
+}
+
+DarwinSDKInfo *Sema::getDarwinSDKInfoForAvailabilityChecking() {
   if (CachedDarwinSDKInfo)
     return CachedDarwinSDKInfo->get();
   auto SDKInfo = parseDarwinSDKInfo(
@@ -71,8 +81,6 @@ Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc,
   }
   if (!SDKInfo)
     llvm::consumeError(SDKInfo.takeError());
-  Diag(Loc, diag::warn_missing_sdksettings_for_availability_checking)
-      << Platform;
   CachedDarwinSDKInfo = std::unique_ptr<DarwinSDKInfo>();
   return nullptr;
 }

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 642b878e02706..955f477760429 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2625,9 +2625,25 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
       NewII = &S.Context.Idents.get("watchos_app_extension");
 
     if (NewII) {
-      auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple {
+      const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
+      const auto *IOSToWatchOSMapping =
+          SDKInfo ? SDKInfo->getVersionMapping(
+                        DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair())
+                  : nullptr;
+
+      auto adjustWatchOSVersion =
+          [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {
         if (Version.empty())
           return Version;
+        auto MinimumWatchOSVersion = VersionTuple(2, 0);
+
+        if (IOSToWatchOSMapping) {
+          if (auto MappedVersion = IOSToWatchOSMapping->map(
+                  Version, MinimumWatchOSVersion, None)) {
+            return MappedVersion.getValue();
+          }
+        }
+
         auto Major = Version.getMajor();
         auto NewMajor = Major >= 9 ? Major - 7 : 0;
         if (NewMajor >= 2) {
@@ -2641,7 +2657,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
           return VersionTuple(NewMajor);
         }
 
-        return VersionTuple(2, 0);
+        return MinimumWatchOSVersion;
       };
 
       auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
@@ -2666,10 +2682,34 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
       NewII = &S.Context.Idents.get("tvos_app_extension");
 
     if (NewII) {
+      const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
+      const auto *IOSToTvOSMapping =
+          SDKInfo ? SDKInfo->getVersionMapping(
+                        DarwinSDKInfo::OSEnvPair::iOStoTvOSPair())
+                  : nullptr;
+
+      auto AdjustTvOSVersion =
+          [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {
+        if (Version.empty())
+          return Version;
+
+        if (IOSToTvOSMapping) {
+          if (auto MappedVersion =
+                  IOSToTvOSMapping->map(Version, VersionTuple(0, 0), None)) {
+            return MappedVersion.getValue();
+          }
+        }
+        return Version;
+      };
+
+      auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
+      auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
+      auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
+
       AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
-          ND, AL, NewII, true /*Implicit*/, Introduced.Version,
-          Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, IsStrict,
-          Replacement, Sema::AMK_None,
+          ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
+          NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
+          Sema::AMK_None,
           PriorityModifier + Sema::AP_InferredFromOtherPlatform);
       if (NewAttr)
         D->addAttr(NewAttr);

diff  --git a/clang/test/Sema/Inputs/AppleTVOS15.0.sdk/SDKSettings.json b/clang/test/Sema/Inputs/AppleTVOS15.0.sdk/SDKSettings.json
new file mode 100644
index 0000000000000..dc10836f4887e
--- /dev/null
+++ b/clang/test/Sema/Inputs/AppleTVOS15.0.sdk/SDKSettings.json
@@ -0,0 +1,67 @@
+{
+  "DisplayName": "tvOS 15.0",
+  "Version": "15.0",
+  "MaximumDeploymentTarget": "15.0.99",
+  "PropertyConditionFallbackNames": [],
+  "VersionMap": {
+    "iOS_tvOS": {
+      "10.0": "10.0",
+      "10.1": "10.0",
+      "10.2": "10.1",
+      "10.3": "10.2",
+      "10.3.1": "10.2",
+      "11.0": "11.0",
+      "11.1": "11.1",
+      "11.2": "11.2",
+      "11.3": "11.3",
+      "11.4": "11.4",
+      "12.0": "12.0",
+      "12.1": "12.1",
+      "12.2": "12.2",
+      "12.4": "12.4",
+      "13.0": "13.0",
+      "13.1": "13.0",
+      "13.2": "13.2",
+      "13.4": "13.4",
+      "13.5": "13.4",
+      "13.6": "13.4",
+      "13.7": "13.4",
+      "14.0": "14.0",
+      "14.1": "14.0",
+      "14.2": "14.2",
+      "14.3": "14.3",
+      "14.4": "14.3",
+      "14.5": "14.5",
+      "15.0": "15.0",
+      "9.0": "9.0",
+      "9.1": "9.0",
+      "9.2": "9.1",
+      "9.3": "9.2"
+    },
+    "tvOS_iOS": {
+      "10.0": "10.0",
+      "10.1": "10.2",
+      "10.2": "10.3",
+      "11.0": "11.0",
+      "11.1": "11.1",
+      "11.2": "11.2",
+      "11.3": "11.3",
+      "11.4": "11.4",
+      "12.0": "12.0",
+      "12.1": "12.1",
+      "12.2": "12.2",
+      "12.4": "12.4",
+      "13.0": "13.0",
+      "13.2": "13.2",
+      "13.4": "13.4",
+      "14.0": "14.0",
+      "14.2": "14.2",
+      "14.3": "14.3",
+      "14.5": "14.5",
+      "15.0": "15.0",
+      "9.0": "9.0",
+      "9.1": "9.2",
+      "9.2": "9.3"
+    }
+  }
+}

diff  --git a/clang/test/Sema/Inputs/WatchOS7.0.sdk/SDKSettings.json b/clang/test/Sema/Inputs/WatchOS7.0.sdk/SDKSettings.json
new file mode 100644
index 0000000000000..fff3e3a80286e
--- /dev/null
+++ b/clang/test/Sema/Inputs/WatchOS7.0.sdk/SDKSettings.json
@@ -0,0 +1,57 @@
+{
+  "DisplayName": "watchOS 7.0",
+  "Version": "7.0",
+  "MaximumDeploymentTarget": "7.0.99",
+  "PropertyConditionFallbackNames": [],
+  "VersionMap": {
+    "iOS_watchOS": {
+      "10.0": "3.0",
+      "10.1": "3.1",
+      "10.2": "3.1",
+      "10.3": "3.2",
+      "10.3.1": "3.2",
+      "11.0": "4.0",
+      "11.1": "4.1",
+      "11.2": "4.2",
+      "11.3": "4.3",
+      "11.4": "4.3",
+      "12.0": "5.0",
+      "12.1": "5.1",
+      "12.2": "5.2",
+      "12.4": "5.3",
+      "13.0": "6.0",
+      "13.1": "6.0",
+      "13.2": "6.1",
+      "13.4": "6.2",
+      "13.5": "6.2",
+      "13.6": "6.2",
+      "13.7": "6.2",
+      "14.0": "7.0",
+      "14.1": "7.0",
+      "9.0": "2.0",
+      "9.1": "2.0",
+      "9.2": "2.1",
+      "9.3": "2.2"
+    },
+    "watchOS_iOS": {
+      "2.0": "9.0",
+      "2.1": "9.2",
+      "2.2": "9.3",
+      "3.0": "10.0",
+      "3.1": "10.1",
+      "3.2": "10.3",
+      "4.0": "11.0",
+      "4.1": "11.1",
+      "4.2": "11.2",
+      "4.3": "11.3",
+      "5.0": "12.0",
+      "5.1": "12.1",
+      "5.2": "12.2",
+      "5.3": "12.4",
+      "6.0": "13.0",
+      "6.1": "13.2",
+      "6.2": "13.4",
+      "7.0": "14.0"
+    }
+  }
+}

diff  --git a/clang/test/Sema/attr-availability-tvos.c b/clang/test/Sema/attr-availability-tvos.c
index b940a9ad3a998..24755e98c1c13 100644
--- a/clang/test/Sema/attr-availability-tvos.c
+++ b/clang/test/Sema/attr-availability-tvos.c
@@ -1,63 +1,80 @@
-// RUN: %clang_cc1 "-triple" "x86_64-apple-tvos3.0" -fsyntax-only -verify %s
+// RUN: %clang_cc1 "-triple" "x86_64-apple-tvos13.0" -fsyntax-only -verify %s
+// RUN: %clang_cc1 "-triple" "x86_64-apple-tvos13.0" -DUSE_VERSION_MAP -isysroot %S/Inputs/AppleTVOS15.0.sdk -fsyntax-only -verify %s
 
-void f0(int) __attribute__((availability(tvos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
-void f1(int) __attribute__((availability(tvos,introduced=2.1)));
-void f2(int) __attribute__((availability(tvos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
-void f3(int) __attribute__((availability(tvos,introduced=3.0)));
-void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
+void f0(int) __attribute__((availability(tvos,introduced=12.0,deprecated=12.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
+void f1(int) __attribute__((availability(tvos,introduced=12.1)));
+void f2(int) __attribute__((availability(tvos,introduced=12.0,deprecated=13.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
+void f3(int) __attribute__((availability(tvos,introduced=13.0)));
+void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=12.0,deprecated=12.1,obsoleted=13.0))); // expected-note{{explicitly marked unavailable}}
 
-void f5(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
-void f6(int) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
-void f6(int) __attribute__((availability(tvos,introduced=2.0)));
+void f5(int) __attribute__((availability(tvos,introduced=12.0))) __attribute__((availability(tvos,deprecated=13.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
+void f6(int) __attribute__((availability(tvos,deprecated=13.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
+void f6(int) __attribute__((availability(tvos,introduced=12.0)));
 
 void test() {
-  f0(0); // expected-warning{{'f0' is deprecated: first deprecated in tvOS 2.1}}
+  f0(0); // expected-warning{{'f0' is deprecated: first deprecated in tvOS 12.1}}
   f1(0);
-  f2(0); // expected-warning{{'f2' is deprecated: first deprecated in tvOS 3.0}}
+  f2(0); // expected-warning{{'f2' is deprecated: first deprecated in tvOS 13.0}}
   f3(0);
-  f4(0); // expected-error{{f4' is unavailable: obsoleted in tvOS 3.0}}
-  f5(0); // expected-warning{{'f5' is deprecated: first deprecated in tvOS 3.0}}
-  f6(0); // expected-warning{{'f6' is deprecated: first deprecated in tvOS 3.0}}
+  f4(0); // expected-error{{f4' is unavailable: obsoleted in tvOS 13.0}}
+  f5(0); // expected-warning{{'f5' is deprecated: first deprecated in tvOS 13.0}}
+  f6(0); // expected-warning{{'f6' is deprecated: first deprecated in tvOS 13.0}}
 }
 
-// Anything iOS later than 8 does not apply to tvOS.
-void f9(int) __attribute__((availability(ios,introduced=2.0,deprecated=9.0)));
+// Anything iOS later than 13 does not apply to tvOS.
+void f9(int) __attribute__((availability(ios,introduced=12.0,deprecated=19.0)));
 
 void test_transcribed_availability() {
   f9(0);
 }
 
-__attribute__((availability(ios,introduced=9_0,deprecated=9_0,message="" ))) // expected-warning 2{{availability does not match previous declaration}}
-__attribute__((availability(ios,introduced=7_0)))                            // expected-note 2{{previous attribute is here}}
+__attribute__((availability(ios,introduced=19_0,deprecated=19_0,message="" ))) // expected-warning 2{{availability does not match previous declaration}}
+__attribute__((availability(ios,introduced=17_0)))                             // expected-note 2{{previous attribute is here}}
 void f10(int);
 
 // Test tvOS specific attributes.
-void f0_tvos(int) __attribute__((availability(tvos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0_tvos' has been explicitly marked deprecated here}}
-void f1_tvos(int) __attribute__((availability(tvos,introduced=2.1)));
-void f2_tvos(int) __attribute__((availability(tvOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_tvos' has been explicitly marked deprecated here}}
-void f3_tvos(int) __attribute__((availability(tvos,introduced=3.0)));
-void f4_tvos(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
-void f5_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0)));
-void f5_attr_reversed_tvos(int) __attribute__((availability(ios, deprecated=3.0))) __attribute__((availability(tvos,introduced=2.0)));
-void f5b_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5b_tvos' has been explicitly marked deprecated here}}
-void f5c_tvos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_tvos' has been explicitly marked deprecated here}}
-void f6_tvos(int) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}}
-void f6_tvos(int) __attribute__((availability(tvOS,introduced=2.0)));
+void f0_tvos(int) __attribute__((availability(tvos,introduced=12.0,deprecated=12.1))); // expected-note {{'f0_tvos' has been explicitly marked deprecated here}}
+void f1_tvos(int) __attribute__((availability(tvos,introduced=12.1)));
+void f2_tvos(int) __attribute__((availability(tvOS,introduced=12.0,deprecated=13.0))); // expected-note {{'f2_tvos' has been explicitly marked deprecated here}}
+void f3_tvos(int) __attribute__((availability(tvos,introduced=13.0)));
+void f4_tvos(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=12.0,deprecated=12.1,obsoleted=13.0))); // expected-note{{explicitly marked unavailable}}
+void f5_tvos(int) __attribute__((availability(tvos,introduced=12.0))) __attribute__((availability(ios,deprecated=13.0)));
+void f5_attr_reversed_tvos(int) __attribute__((availability(ios, deprecated=13.0))) __attribute__((availability(tvos,introduced=12.0)));
+void f5b_tvos(int) __attribute__((availability(tvos,introduced=12.0))) __attribute__((availability(tvos,deprecated=13.0))); // expected-note {{'f5b_tvos' has been explicitly marked deprecated here}}
+void f5c_tvos(int) __attribute__((availability(ios,introduced=12.0))) __attribute__((availability(ios,deprecated=13.0))); // expected-note {{'f5c_tvos' has been explicitly marked deprecated here}}
+void f6_tvos(int) __attribute__((availability(tvos,deprecated=13.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}}
+void f6_tvos(int) __attribute__((availability(tvOS,introduced=12.0)));
 
 void test_tvos() {
-  f0_tvos(0); // expected-warning{{'f0_tvos' is deprecated: first deprecated in tvOS 2.1}}
+  f0_tvos(0); // expected-warning{{'f0_tvos' is deprecated: first deprecated in tvOS 12.1}}
   f1_tvos(0);
-  f2_tvos(0); // expected-warning{{'f2_tvos' is deprecated: first deprecated in tvOS 3.0}}
+  f2_tvos(0); // expected-warning{{'f2_tvos' is deprecated: first deprecated in tvOS 13.0}}
   f3_tvos(0);
-  f4_tvos(0); // expected-error{{'f4_tvos' is unavailable: obsoleted in tvOS 3.0}}
+  f4_tvos(0); // expected-error{{'f4_tvos' is unavailable: obsoleted in tvOS 13.0}}
   // We get no warning here because any explicit 'tvos' availability causes
   // the ios availability to not implicitly become 'tvos' availability.  Otherwise we'd get
   // a deprecated warning.
   f5_tvos(0); // no-warning
   f5_attr_reversed_tvos(0); // no-warning
   // We get a deprecated warning here because both attributes are explicitly 'tvos'.
-  f5b_tvos(0); // expected-warning {{'f5b_tvos' is deprecated: first deprecated in tvOS 3.0}}
+  f5b_tvos(0); // expected-warning {{'f5b_tvos' is deprecated: first deprecated in tvOS 13.0}}
   // We get a deprecated warning here because both attributes are 'ios' (both get mapped to 'tvos').
-  f5c_tvos(0); // expected-warning {{'f5c_tvos' is deprecated: first deprecated in tvOS 3.0}}
-  f6_tvos(0); // expected-warning{{'f6_tvos' is deprecated: first deprecated in tvOS 3.0}}
+  f5c_tvos(0); // expected-warning {{'f5c_tvos' is deprecated: first deprecated in tvOS 13.0}}
+  f6_tvos(0); // expected-warning{{'f6_tvos' is deprecated: first deprecated in tvOS 13.0}}
 }
+
+#ifdef USE_VERSION_MAP
+// iOS 9.3 corresponds to tvOS 9.2, as indicated in 'SDKSettings.json'.
+void f11(int) __attribute__((availability(ios,deprecated=9.3))); // expected-note {{'f11' has been explicitly marked deprecated here}}
+
+void testWithVersionMap() {
+  f11(0); // expected-warning {{'f11' is deprecated: first deprecated in tvOS 9.2}}
+}
+#else
+// Without VersionMap, tvOS version is inferred incorrectly as 9.3.
+void f11(int) __attribute__((availability(ios,deprecated=9.3))); // expected-note {{'f11' has been explicitly marked deprecated here}}
+
+void testWithoutVersionMap() {
+  f11(0); // expected-warning {{'f11' is deprecated: first deprecated in tvOS 9.3}}
+}
+#endif

diff  --git a/clang/test/Sema/attr-availability-watchos.c b/clang/test/Sema/attr-availability-watchos.c
index dbcf2c24c6072..140a794cb605a 100644
--- a/clang/test/Sema/attr-availability-watchos.c
+++ b/clang/test/Sema/attr-availability-watchos.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 "-triple" "arm64-apple-watchos3.0" -fsyntax-only -verify %s
+// RUN: %clang_cc1 "-triple" "arm64-apple-watchos4.0" -fsyntax-only -verify %s
+// RUN: %clang_cc1 "-triple" "arm64-apple-watchos4.0" -DUSE_VERSION_MAP -isysroot %S/Inputs/WatchOS7.0.sdk -fsyntax-only -verify %s
 
 void f0(int) __attribute__((availability(ios,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
 void f1(int) __attribute__((availability(ios,introduced=2.1)));
@@ -58,3 +59,19 @@ void deprecatedAfterIntroduced() __attribute__((availability(ios,introduced=9.3,
 void test_ios_correctly_map_to_watchos() {
   deprecatedAfterIntroduced(); // expected-warning {{'deprecatedAfterIntroduced' is deprecated: first deprecated in watchOS 3}}
 }
+
+#ifdef USE_VERSION_MAP
+// iOS 10.3.1 corresponds to watchOS 3.2, as indicated in 'SDKSettings.json'.
+void f9(int) __attribute__((availability(ios,deprecated=10.3.1))); // expected-note {{'f9' has been explicitly marked deprecated here}}
+
+void testWithVersionMap() {
+  f9(0); // expected-warning {{'f9' is deprecated: first deprecated in watchOS 3.2}}
+}
+#else
+// Without VersionMap, watchOS version is inferred incorrectly as 3.3.1.
+void f9(int) __attribute__((availability(ios,deprecated=10.3.1))); // expected-note {{'f9' has been explicitly marked deprecated here}}
+
+void testWithoutVersionMap() {
+  f9(0); // expected-warning {{'f9' is deprecated: first deprecated in watchOS 3.3.1}}
+}
+#endif


        


More information about the cfe-commits mailing list