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

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

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 {{'PartiallyAvailable' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#endif
extern void
PartiallyAvailable() __attribute__((availability(macosx,introduced=10.8)));
#ifdef WARN_PARTIAL
// expected-note@+2 2 {{'PartialEnum' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#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 {{'PartiallyAvailable' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
#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}}
Append new attributes to the end of an AttributeList. Recommit of r335084 after revert in r335516. ... instead of prepending it at the beginning (the original behavior since implemented in r122535 2010-12-23). This builds up an AttributeList in the the order in which the attributes appear in the source. The reverse order caused nodes for attributes in the AST (e.g. LoopHint) to be in the reverse order, and therefore printed in the wrong order in -ast-dump. Some TODO comments mention this. The order was explicitly reversed for enable_if attribute overload resolution and name mangling, which is not necessary anymore with this patch. The change unfortunately has some secondary effect, especially on diagnostic output. In the simplest cases, the CHECK lines or expected diagnostic were changed to the the new output. If the kind of error/warning changed, the attributes' order was changed instead. This unfortunately causes some 'previous occurrence here' hints to be textually after the main marker. This typically happens when attributes are merged, but are incompatible to each other. Interchanging the role of the the main and note SourceLocation will also cause the case where two different declaration's attributes (in contrast to multiple attributes of the same declaration) are merged to be reverse. There is no easy fix because sometimes previous attributes are merged into a new declaration's attribute list, sometimes new attributes are added to a previous declaration's attribute list. Since 'previous occurrence here' pointing to locations after the main marker is not rare, I left the markers as-is; it is only relevant when the attributes are declared in the same declaration anyway. Differential Revision: https://reviews.llvm.org/D48100 llvm-svn: 338800
2018-08-03 09:21:16 +08:00
void f5(int) __attribute__((availability(ios,deprecated=3.0), // expected-warning {{feature cannot be deprecated in iOS version 3.0 before it was introduced in version 4.0; attribute ignored}}
availability(ios,introduced=4.0)));
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)));