erik.pilkington updated this revision to Diff 99605.
erik.pilkington added a comment.

> Can we ignore the TypeLocs with invalid location and instead look at 
> ObjCPropertyRefExprs with a class receiver?

Sure, good idea. This new patch does exactly that.

Thanks,
Erik


https://reviews.llvm.org/D33250

Files:
  lib/Sema/SemaDeclAttr.cpp
  test/SemaObjC/unguarded-availability.m


Index: test/SemaObjC/unguarded-availability.m
===================================================================
--- test/SemaObjC/unguarded-availability.m
+++ test/SemaObjC/unguarded-availability.m
@@ -135,6 +135,26 @@
     func_10_12();
 };
 
+AVAILABLE_10_12
+__attribute__((objc_root_class))
+@interface InterWithProp // expected-note 2 {{marked partial here}}
+@property(class) int x;
++ (void) setX: (int)newX AVAILABLE_10_12; // expected-note{{marked partial 
here}}
+@end
+void test_property(void) {
+  int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only 
available on macOS 10.12 or newer}} expected-note{{@available}}
+  InterWithProp.x = y; // expected-warning{{'InterWithProp' is only available 
on macOS 10.12 or newer}} expected-note{{@available}} expected-warning{{'setX:' 
is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
+__attribute__((objc_root_class))
+@interface Subscriptable
+- (id)objectAtIndexedSubscript:(int)sub AVAILABLE_10_12; // 
expected-note{{marked partial here}}
+@end
+
+void test_at(Subscriptable *x) {
+  id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only 
available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
 #ifdef OBJCPP
 
 int f(char) AVAILABLE_10_12;
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7252,6 +7252,12 @@
 
   bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
 
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) {
+    if (ObjCInterfaceDecl *ID = PRE->getClassReceiver())
+      DiagnoseDeclAvailability(ID, PRE->getReceiverLocation());
+    return true;
+  }
+
   bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
     if (ObjCMethodDecl *D = Msg->getMethodDecl())
       DiagnoseDeclAvailability(
@@ -7381,6 +7387,9 @@
   const Type *TyPtr = Ty.getTypePtr();
   SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()};
 
+  if (Range.isInvalid())
+    return true;
+
   if (const TagType *TT = dyn_cast<TagType>(TyPtr)) {
     TagDecl *TD = TT->getDecl();
     DiagnoseDeclAvailability(TD, Range);


Index: test/SemaObjC/unguarded-availability.m
===================================================================
--- test/SemaObjC/unguarded-availability.m
+++ test/SemaObjC/unguarded-availability.m
@@ -135,6 +135,26 @@
     func_10_12();
 };
 
+AVAILABLE_10_12
+__attribute__((objc_root_class))
+@interface InterWithProp // expected-note 2 {{marked partial here}}
+@property(class) int x;
++ (void) setX: (int)newX AVAILABLE_10_12; // expected-note{{marked partial here}}
+@end
+void test_property(void) {
+  int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  InterWithProp.x = y; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}} expected-warning{{'setX:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
+__attribute__((objc_root_class))
+@interface Subscriptable
+- (id)objectAtIndexedSubscript:(int)sub AVAILABLE_10_12; // expected-note{{marked partial here}}
+@end
+
+void test_at(Subscriptable *x) {
+  id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
 #ifdef OBJCPP
 
 int f(char) AVAILABLE_10_12;
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -7252,6 +7252,12 @@
 
   bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
 
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) {
+    if (ObjCInterfaceDecl *ID = PRE->getClassReceiver())
+      DiagnoseDeclAvailability(ID, PRE->getReceiverLocation());
+    return true;
+  }
+
   bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
     if (ObjCMethodDecl *D = Msg->getMethodDecl())
       DiagnoseDeclAvailability(
@@ -7381,6 +7387,9 @@
   const Type *TyPtr = Ty.getTypePtr();
   SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()};
 
+  if (Range.isInvalid())
+    return true;
+
   if (const TagType *TT = dyn_cast<TagType>(TyPtr)) {
     TagDecl *TD = TT->getDecl();
     DiagnoseDeclAvailability(TD, Range);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to