llvm-project/clang/test/Sema/attr-availability.c

174 lines
10 KiB
C
Raw Normal View History

// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -verify %s
// RUN: %clang_cc1 -D WARN_PARTIAL -Wpartial-availability -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -verify %s
//
Implement a new 'availability' attribute, that allows one to specify which versions of an OS provide a certain facility. For example, void foo() __attribute__((availability(macosx,introduced=10.2,deprecated=10.4,obsoleted=10.6))); says that the function "foo" was introduced in 10.2, deprecated in 10.4, and completely obsoleted in 10.6. This attribute ties in with the deployment targets (e.g., -mmacosx-version-min=10.1 specifies that we want to deploy back to Mac OS X 10.1). There are several concrete behaviors that this attribute enables, as illustrated with the function foo() above: - If we choose a deployment target >= Mac OS X 10.4, uses of "foo" will result in a deprecation warning, as if we had placed attribute((deprecated)) on it (but with a better diagnostic) - If we choose a deployment target >= Mac OS X 10.6, uses of "foo" will result in an "unavailable" warning (in C)/error (in C++), as if we had placed attribute((unavailable)) on it - If we choose a deployment target prior to 10.2, foo() is weak-imported (if it is a kind of entity that can be weak imported), as if we had placed the weak_import attribute on it. Naturally, there can be multiple availability attributes on a declaration, for different platforms; only the current platform matters when checking availability attributes. The only platforms this attribute currently works for are "ios" and "macosx", since we already have -mxxxx-version-min flags for them and we have experience there with macro tricks translating down to the deprecated/unavailable/weak_import attributes. The end goal is to open this up to other platforms, and even extension to other "platforms" that are really libraries (say, through a #pragma clang define_system), but that hasn't yet been designed and we may want to shake out more issues with this narrower problem first. Addresses <rdar://problem/6690412>. As a drive-by bug-fix, if an entity is both deprecated and unavailable, we only emit the "unavailable" diagnostic. llvm-svn: 128127
2011-03-23 08:50:03 +08:00
void f0() __attribute__((availability(macosx,introduced=10.4,deprecated=10.2))); // expected-warning{{feature cannot be deprecated in macOS version 10.2 before it was introduced in version 10.4; attribute ignored}}
Implement a new 'availability' attribute, that allows one to specify which versions of an OS provide a certain facility. For example, void foo() __attribute__((availability(macosx,introduced=10.2,deprecated=10.4,obsoleted=10.6))); says that the function "foo" was introduced in 10.2, deprecated in 10.4, and completely obsoleted in 10.6. This attribute ties in with the deployment targets (e.g., -mmacosx-version-min=10.1 specifies that we want to deploy back to Mac OS X 10.1). There are several concrete behaviors that this attribute enables, as illustrated with the function foo() above: - If we choose a deployment target >= Mac OS X 10.4, uses of "foo" will result in a deprecation warning, as if we had placed attribute((deprecated)) on it (but with a better diagnostic) - If we choose a deployment target >= Mac OS X 10.6, uses of "foo" will result in an "unavailable" warning (in C)/error (in C++), as if we had placed attribute((unavailable)) on it - If we choose a deployment target prior to 10.2, foo() is weak-imported (if it is a kind of entity that can be weak imported), as if we had placed the weak_import attribute on it. Naturally, there can be multiple availability attributes on a declaration, for different platforms; only the current platform matters when checking availability attributes. The only platforms this attribute currently works for are "ios" and "macosx", since we already have -mxxxx-version-min flags for them and we have experience there with macro tricks translating down to the deprecated/unavailable/weak_import attributes. The end goal is to open this up to other platforms, and even extension to other "platforms" that are really libraries (say, through a #pragma clang define_system), but that hasn't yet been designed and we may want to shake out more issues with this narrower problem first. Addresses <rdar://problem/6690412>. As a drive-by bug-fix, if an entity is both deprecated and unavailable, we only emit the "unavailable" diagnostic. llvm-svn: 128127
2011-03-23 08:50:03 +08:00
void f1() __attribute__((availability(ios,obsoleted=2.1,deprecated=3.0))); // expected-warning{{feature cannot be obsoleted in iOS version 2.1 before it was deprecated in version 3.0; attribute ignored}}
void f2() __attribute__((availability(ios,introduced=2.1,deprecated=2.1)));
Implement a new 'availability' attribute, that allows one to specify which versions of an OS provide a certain facility. For example, void foo() __attribute__((availability(macosx,introduced=10.2,deprecated=10.4,obsoleted=10.6))); says that the function "foo" was introduced in 10.2, deprecated in 10.4, and completely obsoleted in 10.6. This attribute ties in with the deployment targets (e.g., -mmacosx-version-min=10.1 specifies that we want to deploy back to Mac OS X 10.1). There are several concrete behaviors that this attribute enables, as illustrated with the function foo() above: - If we choose a deployment target >= Mac OS X 10.4, uses of "foo" will result in a deprecation warning, as if we had placed attribute((deprecated)) on it (but with a better diagnostic) - If we choose a deployment target >= Mac OS X 10.6, uses of "foo" will result in an "unavailable" warning (in C)/error (in C++), as if we had placed attribute((unavailable)) on it - If we choose a deployment target prior to 10.2, foo() is weak-imported (if it is a kind of entity that can be weak imported), as if we had placed the weak_import attribute on it. Naturally, there can be multiple availability attributes on a declaration, for different platforms; only the current platform matters when checking availability attributes. The only platforms this attribute currently works for are "ios" and "macosx", since we already have -mxxxx-version-min flags for them and we have experience there with macro tricks translating down to the deprecated/unavailable/weak_import attributes. The end goal is to open this up to other platforms, and even extension to other "platforms" that are really libraries (say, through a #pragma clang define_system), but that hasn't yet been designed and we may want to shake out more issues with this narrower problem first. Addresses <rdar://problem/6690412>. As a drive-by bug-fix, if an entity is both deprecated and unavailable, we only emit the "unavailable" diagnostic. llvm-svn: 128127
2011-03-23 08:50:03 +08:00
void f3() __attribute__((availability(otheros,introduced=2.2))); // expected-warning{{unknown platform 'otheros' in availability macro}}
// rdar://10095131
extern void
ATSFontGetName(const char *oName) __attribute__((availability(macosx,introduced=8.0,deprecated=9.0, message="use CTFontCopyFullName"))); // expected-note {{'ATSFontGetName' has been explicitly marked deprecated here}}
extern void
ATSFontGetPostScriptName(int flags) __attribute__((availability(macosx,introduced=8.0,obsoleted=9.0, message="use ATSFontGetFullPostScriptName"))); // expected-note {{'ATSFontGetPostScriptName' has been explicitly marked unavailable here}}
#if defined(WARN_PARTIAL)
// expected-note@+3 {{has been explicitly marked partial here}}
#endif
extern void
PartiallyAvailable() __attribute__((availability(macosx,introduced=10.8)));
#ifdef WARN_PARTIAL
// expected-note@+2 2 {{marked partial here}}
#endif
enum __attribute__((availability(macosx,introduced=10.8))) PartialEnum {
kPartialEnumConstant,
};
void test_10095131() {
ATSFontGetName("Hello"); // expected-warning {{'ATSFontGetName' is deprecated: first deprecated in macOS 9.0 - use CTFontCopyFullName}}
ATSFontGetPostScriptName(100); // expected-error {{'ATSFontGetPostScriptName' is unavailable: obsoleted in macOS 9.0 - use ATSFontGetFullPostScriptName}}
#if defined(WARN_PARTIAL)
// expected-warning@+2 {{is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'PartiallyAvailable' in a __builtin_available check to silence this warning}}
#endif
PartiallyAvailable();
}
#ifdef WARN_PARTIAL
// FIXME: This note should point to the declaration with the availability
// attribute.
// expected-note@+2 {{marked partial here}}
#endif
extern void PartiallyAvailable() ;
void with_redeclaration() {
#ifdef WARN_PARTIAL
// expected-warning@+4 {{'PartiallyAvailable' is only available on macOS 10.8 or newer}} expected-note@+4 {{__builtin_available}}
// expected-warning@+4 {{'PartialEnum' is only available on macOS 10.8 or newer}} expected-note@+4 {{__builtin_available}}
// expected-warning@+3 {{'kPartialEnumConstant' is only available on macOS 10.8 or newer}} expected-note@+3 {{__builtin_available}}
#endif
PartiallyAvailable();
enum PartialEnum p = kPartialEnumConstant;
}
// rdar://10711037
__attribute__((availability(macos, unavailable))) // expected-warning {{attribute 'availability' is ignored}}
enum {
NSDataWritingFileProtectionWriteOnly = 0x30000000,
NSDataWritingFileProtectionCompleteUntilUserAuthentication = 0x40000000,
};
void f4(int) __attribute__((availability(ios,deprecated=3.0)));
void f4(int) __attribute__((availability(ios,introduced=4.0))); // expected-warning {{feature cannot be deprecated in iOS version 3.0 before it was introduced in version 4.0; attribute ignored}}
void f5(int) __attribute__((availability(ios,deprecated=3.0),
availability(ios,introduced=4.0))); // expected-warning {{feature cannot be deprecated in iOS version 3.0 before it was introduced in version 4.0; attribute ignored}}
void f6(int) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{previous attribute is here}}
void f6(int) __attribute__((availability(ios,deprecated=4.0))); // expected-warning {{availability does not match previous declaration}}
void f7(int) __attribute__((availability(ios,introduced=2.0)));
void f7(int) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{previous attribute is here}}
void f7(int) __attribute__((availability(ios,deprecated=4.0))); // expected-warning {{availability does not match previous declaration}}
// <rdar://problem/11886458>
#if !__has_feature(attribute_availability_with_message)
# error "Missing __has_feature"
#endif
extern int x __attribute__((availability(macosx,introduced=10.5)));
extern int x;
void f8() {
int (^b)(int);
b = ^ (int i) __attribute__((availability(macosx,introduced=10.2))) { return 1; }; // expected-warning {{'availability' attribute only applies to named declarations}}
}
extern int x2 __attribute__((availability(macosx,introduced=10.2))); // expected-note {{previous attribute is here}}
extern int x2 __attribute__((availability(macosx,introduced=10.5))); // expected-warning {{availability does not match previous declaration}}
enum Original {
OriginalDeprecated __attribute__((availability(macosx, deprecated=10.2))), // expected-note + {{'OriginalDeprecated' has been explicitly marked deprecated here}}
OriginalUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'OriginalUnavailable' has been explicitly marked unavailable here}}
};
enum AllDeprecated { // expected-note + {{'AllDeprecated' has been explicitly marked deprecated here}}
AllDeprecatedCase,
AllDeprecatedUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'AllDeprecatedUnavailable' has been explicitly marked unavailable here}}
} __attribute__((availability(macosx, deprecated=10.2)));
enum AllUnavailable { // expected-note + {{'AllUnavailable' has been explicitly marked unavailable here}}
AllUnavailableCase,
} __attribute__((availability(macosx, unavailable)));
enum User {
UserOD = OriginalDeprecated, // expected-warning {{deprecated}}
UserODDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalDeprecated,
UserODUnavailable __attribute__((availability(macosx, unavailable))) = OriginalDeprecated,
UserOU = OriginalUnavailable, // expected-error {{unavailable}}
UserOUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalUnavailable, // expected-error {{unavailable}}
UserOUUnavailable __attribute__((availability(macosx, unavailable))) = OriginalUnavailable,
UserAD = AllDeprecatedCase, // expected-warning {{deprecated}}
UserADDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedCase,
UserADUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedCase,
UserADU = AllDeprecatedUnavailable, // expected-error {{unavailable}}
UserADUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedUnavailable, // expected-error {{unavailable}}
UserADUUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedUnavailable,
UserAU = AllUnavailableCase, // expected-error {{unavailable}}
UserAUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllUnavailableCase, // expected-error {{unavailable}}
UserAUUnavailable __attribute__((availability(macosx, unavailable))) = AllUnavailableCase,
};
enum UserDeprecated {
UserDeprecatedOD = OriginalDeprecated,
UserDeprecatedODDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalDeprecated,
UserDeprecatedODUnavailable __attribute__((availability(macosx, unavailable))) = OriginalDeprecated,
UserDeprecatedOU = OriginalUnavailable, // expected-error {{unavailable}}
UserDeprecatedOUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalUnavailable, // expected-error {{unavailable}}
UserDeprecatedOUUnavailable __attribute__((availability(macosx, unavailable))) = OriginalUnavailable,
UserDeprecatedAD = AllDeprecatedCase,
UserDeprecatedADDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedCase,
UserDeprecatedADUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedCase,
UserDeprecatedADU = AllDeprecatedUnavailable, // expected-error {{unavailable}}
UserDeprecatedADUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedUnavailable, // expected-error {{unavailable}}
UserDeprecatedADUUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedUnavailable,
UserDeprecatedAU = AllUnavailableCase, // expected-error {{unavailable}}
UserDeprecatedAUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllUnavailableCase, // expected-error {{unavailable}}
UserDeprecatedAUUnavailable __attribute__((availability(macosx, unavailable))) = AllUnavailableCase,
} __attribute__((availability(macosx, deprecated=10.2)));
enum UserUnavailable {
UserUnavailableOD = OriginalDeprecated,
UserUnavailableODDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalDeprecated,
UserUnavailableODUnavailable __attribute__((availability(macosx, unavailable))) = OriginalDeprecated,
UserUnavailableOU = OriginalUnavailable,
UserUnavailableOUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalUnavailable,
UserUnavailableOUUnavailable __attribute__((availability(macosx, unavailable))) = OriginalUnavailable,
UserUnavailableAD = AllDeprecatedCase,
UserUnavailableADDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedCase,
UserUnavailableADUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedCase,
UserUnavailableADU = AllDeprecatedUnavailable,
UserUnavailableADUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedUnavailable,
UserUnavailableADUUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedUnavailable,
UserUnavailableAU = AllUnavailableCase,
UserUnavailableAUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllUnavailableCase,
UserUnavailableAUUnavailable __attribute__((availability(macosx, unavailable))) = AllUnavailableCase,
} __attribute__((availability(macosx, unavailable)));