forked from OSchip/llvm-project
[analyzer] Add an annotation to allow suppression of direct ivar
assignment llvm-svn: 172597
This commit is contained in:
parent
8a023580c7
commit
6519564c97
|
@ -155,6 +155,18 @@ void DirectIvarAssignment::checkASTDecl(const ObjCImplementationDecl *D,
|
|||
}
|
||||
}
|
||||
|
||||
static bool isAnnotatedToAllowDirectAssignment(const ObjCPropertyDecl *D) {
|
||||
for (specific_attr_iterator<AnnotateAttr>
|
||||
AI = D->specific_attr_begin<AnnotateAttr>(),
|
||||
AE = D->specific_attr_end<AnnotateAttr>(); AI != AE; ++AI) {
|
||||
const AnnotateAttr *Ann = *AI;
|
||||
if (Ann->getAnnotation() ==
|
||||
"objc_allow_direct_instance_variable_assignment")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
|
||||
const BinaryOperator *BO) {
|
||||
if (!BO->isAssignmentOp())
|
||||
|
@ -168,8 +180,14 @@ void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
|
|||
|
||||
if (const ObjCIvarDecl *D = IvarRef->getDecl()) {
|
||||
IvarToPropertyMapTy::const_iterator I = IvarToPropMap.find(D);
|
||||
|
||||
if (I != IvarToPropMap.end()) {
|
||||
const ObjCPropertyDecl *PD = I->second;
|
||||
// Skip warnings on Ivars that correspond to properties, annotated with
|
||||
// objc_allow_direct_instance_variable_assignment. This annotation serves
|
||||
// as a false positive suppression mechanism for the checker.
|
||||
if (isAnnotatedToAllowDirectAssignment(PD))
|
||||
return;
|
||||
|
||||
ObjCMethodDecl *GetterMethod =
|
||||
InterfD->getInstanceMethod(PD->getGetterName());
|
||||
|
|
|
@ -13,14 +13,14 @@ typedef signed char BOOL;
|
|||
@interface MyClass;
|
||||
@end
|
||||
|
||||
@interface AnnotatedClass :NSObject {
|
||||
@interface AnnotatedClass : NSObject {
|
||||
}
|
||||
- (void) someMethod: (MyClass*)In __attribute__((annotate("objc_no_direct_instance_variable_assignment")));
|
||||
- (void) someMethodNotAnnaotated: (MyClass*)In;
|
||||
@end
|
||||
|
||||
|
||||
@interface TestProperty :AnnotatedClass {
|
||||
@interface TestProperty : AnnotatedClass {
|
||||
MyClass *_Z;
|
||||
id _nonSynth;
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ typedef signed char BOOL;
|
|||
|
||||
@property (assign, nonatomic) MyClass* Z; // non synthesized ivar, implemented setter
|
||||
@property (readonly) id nonSynth; // non synthesized, explicitly implemented to return ivar with expected name
|
||||
|
||||
@property (assign) MyClass* NotX __attribute__((annotate("objc_allow_direct_instance_variable_assignment"))); // warnings should be suppressed
|
||||
|
||||
@end
|
||||
|
||||
@implementation TestProperty
|
||||
|
@ -44,6 +47,7 @@ typedef signed char BOOL;
|
|||
_Y = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
|
||||
_Z = In; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
|
||||
_nonSynth = 0; // expected-warning {{Direct assignment to an instance variable backing a property; use the setter instead}}
|
||||
_NotX = 0; // no-warning
|
||||
}
|
||||
- (void) someMethodNotAnnaotated: (MyClass*)In {
|
||||
(__A) = In;
|
||||
|
|
Loading…
Reference in New Issue