[PATCH] D28495: [analyzer] Support inlining of '[self classMethod]' and '[[self class] classMethod]'
Devin Coughlin via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 9 18:41:30 PST 2017
dcoughlin added inline comments.
================
Comment at: lib/StaticAnalyzer/Core/CallEvent.cpp:972
+ Receiver == getSelfSVal().getAsRegion())
+ return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
+
----------------
Here is a case where dispatching via the compile-time type of E is not safe:
```
#import <Foundation/Foundation.h>
void clang_analyzer_eval(int);
@interface Parent : NSObject
+ (int)a;
+ (int)b;
@end
@interface Child : Parent
@end
@interface Other : NSObject
+(void)run;
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
[Other run];
}
return 0;
}
@implementation Other
+(void)run {
int result = [Child a];
clang_analyzer_eval(result == 12);
printf("result is %d\n", result);
}
@end
@implementation Parent
+ (int)a; {
return [self b];
}
+ (int)b; {
return 12;
}
@end
@implementation Child
+ (int)b; {
return 100;
}
@end
```
Running this code will print 'result is 100' but the clang_analyzer_eval() will incorrectly yield 'TRUE'.
What do you think about adding a new SVal for ObjC 'Class' values that know what interface declaration they come from? Then 'self' in a class method would be filled in with something meaningful in `ObjCMethodCall::getReceiverSVal()` and we could do proper dynamic dispatch for class methods just like we do for instance methods now.
================
Comment at: lib/StaticAnalyzer/Core/CallEvent.cpp:977
+ // limiting as the test cases in Analysis/inlining/InlineObjCClassMethod.m
+ // shows. A better way would be to accosiate the meta type with the symbol
+ // using the dynamic type info tracking and use it here.
----------------
accosiate-->associate
================
Comment at: test/Analysis/inlining/InlineObjCClassMethod.m:269
+ unsigned result0 = [self returns10];
+ clang_analyzer_eval(result0 == 10); // expected-warning{{TRUE}}
+}
----------------
I think it would be good to duplicate some of these tests in `-(void)instanceMethod` since calling `[self class]` is most-commonly used in instance methods:
```
unsigned result2 = [[self class] returns30];
clang_analyzer_eval(result2 == 30); // expected-warning{{TRUE}}
unsigned result3 = [[super class] returns30];
clang_analyzer_eval(result3 == 100); // expected-warning{{UNKNOWN}}
```
https://reviews.llvm.org/D28495
More information about the cfe-commits
mailing list