[PATCH] D33250: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location
This revision was automatically updated to reflect the committed changes. Closed by commit rL303562: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong… (authored by epilk). Changed prior to commit: https://reviews.llvm.org/D33250?vs=99605=99772#toc Repository: rL LLVM https://reviews.llvm.org/D33250 Files: cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/SemaObjC/unguarded-availability.m Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp === --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp @@ -7258,6 +7258,12 @@ bool TraverseLambdaExpr(LambdaExpr *E) { return true; } + bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) { +if (PRE->isClassReceiver()) + DiagnoseDeclAvailability(PRE->getClassReceiver(), PRE->getReceiverLocation()); +return true; + } + bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) { if (ObjCMethodDecl *D = Msg->getMethodDecl()) DiagnoseDeclAvailability( @@ -7387,6 +7393,9 @@ const Type *TyPtr = Ty.getTypePtr(); SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()}; + if (Range.isInvalid()) +return true; + if (const TagType *TT = dyn_cast(TyPtr)) { TagDecl *TD = TT->getDecl(); DiagnoseDeclAvailability(TD, Range); Index: cfe/trunk/test/SemaObjC/unguarded-availability.m === --- cfe/trunk/test/SemaObjC/unguarded-availability.m +++ cfe/trunk/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: cfe/trunk/lib/Sema/SemaDeclAttr.cpp === --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp @@ -7258,6 +7258,12 @@ bool TraverseLambdaExpr(LambdaExpr *E) { return true; } + bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) { +if (PRE->isClassReceiver()) + DiagnoseDeclAvailability(PRE->getClassReceiver(), PRE->getReceiverLocation()); +return true; + } + bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) { if (ObjCMethodDecl *D = Msg->getMethodDecl()) DiagnoseDeclAvailability( @@ -7387,6 +7393,9 @@ const Type *TyPtr = Ty.getTypePtr(); SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()}; + if (Range.isInvalid()) +return true; + if (const TagType *TT = dyn_cast(TyPtr)) { TagDecl *TD = TT->getDecl(); DiagnoseDeclAvailability(TD, Range); Index: cfe/trunk/test/SemaObjC/unguarded-availability.m === --- cfe/trunk/test/SemaObjC/unguarded-availability.m +++ cfe/trunk/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; ___ cfe-commits mailing list cfe-commits@lists.llvm.org
[PATCH] D33250: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location
arphaman accepted this revision. arphaman added a comment. This revision is now accepted and ready to land. LGTM with one change below: Comment at: lib/Sema/SemaDeclAttr.cpp:7256 + bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) { +if (ObjCInterfaceDecl *ID = PRE->getClassReceiver()) + DiagnoseDeclAvailability(ID, PRE->getReceiverLocation()); `getClassReceiver` calls `get` in a PointerUnion, which will trigger an assertion when the PRE is not a class receiver. Please rewrite this `if` to something like: ``` if (PRE->isClassReceiver()) DiagnoseDeclAvailability(PRE->getClassReceiver(), PRE->getReceiverLocation()); ``` https://reviews.llvm.org/D33250 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33250: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location
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(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(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
[PATCH] D33250: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location
arphaman added inline comments. Comment at: test/SemaObjC/unguarded-availability.m:141 +@interface InterWithProp // expected-note 2 {{marked partial here}} +@property int x; +@end Should this be `@property(class)`? https://reviews.llvm.org/D33250 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33250: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location
arphaman added a comment. Hmm, I don't like how we end with a location that points to `x` instead of `InterWithProp`. Can we ignore the TypeLocs with invalid location and instead look at `ObjCPropertyRefExpr`s with a class receiver? https://reviews.llvm.org/D33250 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33250: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location
erik.pilkington updated this revision to Diff 99235. erik.pilkington added a comment. Just noticed this can be simplified a bit, NFC compared to the last version of the diff. 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,17 @@ func_10_12(); }; +AVAILABLE_10_12 +__attribute__((objc_root_class)) +@interface InterWithProp // expected-note 2 {{marked partial here}} +@property int x; +@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}} +} + #ifdef OBJCPP int f(char) AVAILABLE_10_12; Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -7370,7 +7370,8 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) { const Type *TyPtr = Ty.getTypePtr(); - SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()}; + SourceRange Range(StmtStack.back()->getLocStart(), +StmtStack.back()->getLocEnd()); if (const TagType *TT = dyn_cast(TyPtr)) { TagDecl *TD = TT->getDecl(); Index: test/SemaObjC/unguarded-availability.m === --- test/SemaObjC/unguarded-availability.m +++ test/SemaObjC/unguarded-availability.m @@ -135,6 +135,17 @@ func_10_12(); }; +AVAILABLE_10_12 +__attribute__((objc_root_class)) +@interface InterWithProp // expected-note 2 {{marked partial here}} +@property int x; +@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}} +} + #ifdef OBJCPP int f(char) AVAILABLE_10_12; Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -7370,7 +7370,8 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) { const Type *TyPtr = Ty.getTypePtr(); - SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()}; + SourceRange Range(StmtStack.back()->getLocStart(), +StmtStack.back()->getLocEnd()); if (const TagType *TT = dyn_cast(TyPtr)) { TagDecl *TD = TT->getDecl(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33250: [Sema][ObjC] Fix a bug where -Wunguarded-availability was emitted at the wrong location
erik.pilkington created this revision. Previously, we used TypeLocs to find the correct SourceLocations to emit -Wunguarded-availability. Unfortunately, TypeLocs can't be trusted as they sometimes have an an empty SourceLocation component. This new patch maintains the enclosing SourceLocation to be used instead. Thanks for taking a look, 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,17 @@ func_10_12(); }; +AVAILABLE_10_12 +__attribute__((objc_root_class)) +@interface InterWithProp // expected-note 2 {{marked partial here}} +@property int x; +@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}} +} + #ifdef OBJCPP int f(char) AVAILABLE_10_12; Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -7221,6 +7221,8 @@ SmallVectorAvailabilityStack; SmallVector StmtStack; + SourceRange CurrentRange; + void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range); public: @@ -7234,7 +7236,10 @@ if (!S) return true; StmtStack.push_back(S); +SourceRange LastRange(S->getLocStart(), S->getLocEnd()); +std::swap(LastRange, CurrentRange); bool Result = Base::TraverseStmt(S); +std::swap(LastRange, CurrentRange); StmtStack.pop_back(); return Result; } @@ -7370,21 +7375,18 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) { const Type *TyPtr = Ty.getTypePtr(); - SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()}; - if (const TagType *TT = dyn_cast(TyPtr)) { TagDecl *TD = TT->getDecl(); -DiagnoseDeclAvailability(TD, Range); +DiagnoseDeclAvailability(TD, CurrentRange); } else if (const TypedefType *TD = dyn_cast(TyPtr)) { TypedefNameDecl *D = TD->getDecl(); -DiagnoseDeclAvailability(D, Range); +DiagnoseDeclAvailability(D, CurrentRange); } else if (const auto *ObjCO = dyn_cast(TyPtr)) { if (NamedDecl *D = ObjCO->getInterface()) - DiagnoseDeclAvailability(D, Range); + DiagnoseDeclAvailability(D, CurrentRange); } - return true; } Index: test/SemaObjC/unguarded-availability.m === --- test/SemaObjC/unguarded-availability.m +++ test/SemaObjC/unguarded-availability.m @@ -135,6 +135,17 @@ func_10_12(); }; +AVAILABLE_10_12 +__attribute__((objc_root_class)) +@interface InterWithProp // expected-note 2 {{marked partial here}} +@property int x; +@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}} +} + #ifdef OBJCPP int f(char) AVAILABLE_10_12; Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -7221,6 +7221,8 @@ SmallVector AvailabilityStack; SmallVector StmtStack; + SourceRange CurrentRange; + void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range); public: @@ -7234,7 +7236,10 @@ if (!S) return true; StmtStack.push_back(S); +SourceRange LastRange(S->getLocStart(), S->getLocEnd()); +std::swap(LastRange, CurrentRange); bool Result = Base::TraverseStmt(S); +std::swap(LastRange, CurrentRange); StmtStack.pop_back(); return Result; } @@ -7370,21 +7375,18 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) { const Type *TyPtr = Ty.getTypePtr(); - SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()}; - if (const TagType *TT = dyn_cast(TyPtr)) { TagDecl *TD = TT->getDecl(); -DiagnoseDeclAvailability(TD, Range); +DiagnoseDeclAvailability(TD, CurrentRange); } else if (const TypedefType *TD = dyn_cast(TyPtr)) { TypedefNameDecl *D = TD->getDecl(); -DiagnoseDeclAvailability(D, Range); +DiagnoseDeclAvailability(D, CurrentRange); } else if (const auto *ObjCO = dyn_cast(TyPtr)) { if (NamedDecl *D = ObjCO->getInterface()) - DiagnoseDeclAvailability(D, Range); + DiagnoseDeclAvailability(D, CurrentRange); } - return true; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org