[Availability] Improve availability to consider functions run at load time
Summary:
There are some functions/methods that run when the application launches
or the library loads. Those functions will run reguardless the OS
version as long as it satifies the minimum deployment target. Annotate
them with availability attributes doesn't really make sense because they
are essentially available on all targets since minimum deployment
target.
rdar://problem/36093384
Reviewers: arphaman, erik.pilkington
Reviewed By: erik.pilkington
Subscribers: erik.pilkington, cfe-commits
Differential Revision: https://reviews.llvm.org/D45699
llvm-svn: 330166
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index e692b35..84f9f77 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9139,6 +9139,21 @@
AddToScope = false;
}
+ // Diagnose availability attributes. Availability cannot be used on functions
+ // that are run during load/unload.
+ if (const auto *attr = NewFD->getAttr<AvailabilityAttr>()) {
+ if (NewFD->hasAttr<ConstructorAttr>()) {
+ Diag(attr->getLocation(), diag::warn_availability_on_static_initializer)
+ << 1;
+ NewFD->dropAttr<AvailabilityAttr>();
+ }
+ if (NewFD->hasAttr<DestructorAttr>()) {
+ Diag(attr->getLocation(), diag::warn_availability_on_static_initializer)
+ << 2;
+ NewFD->dropAttr<AvailabilityAttr>();
+ }
+ }
+
return NewFD;
}
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 23528f3..74a7925 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6823,6 +6823,12 @@
return false;
// An implementation implicitly has the availability of the interface.
+ // Unless it is "+load" method.
+ if (const auto *MethodD = dyn_cast<ObjCMethodDecl>(Ctx))
+ if (MethodD->isClassMethod() &&
+ MethodD->getSelector().getAsString() == "load")
+ return true;
+
if (const auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) {
if (const ObjCInterfaceDecl *Interface = CatOrImpl->getClassInterface())
if (CheckContext(Interface))
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 75c5ff5..5b8a9f3 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -4734,6 +4734,17 @@
Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
checkObjCMethodX86VectorTypes(*this, ObjCMethod);
+ // + load method cannot have availability attributes. It get called on
+ // startup, so it has to have the availability of the deployment target.
+ if (const auto *attr = ObjCMethod->getAttr<AvailabilityAttr>()) {
+ if (ObjCMethod->isClassMethod() &&
+ ObjCMethod->getSelector().getAsString() == "load") {
+ Diag(attr->getLocation(), diag::warn_availability_on_static_initializer)
+ << 0;
+ ObjCMethod->dropAttr<AvailabilityAttr>();
+ }
+ }
+
ActOnDocumentableDecl(ObjCMethod);
return ObjCMethod;