summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-03-28 23:15:22 +0000
committerAnna Zaks <ganna@apple.com>2013-03-28 23:15:22 +0000
commit05fb371efc0edf15ef4aa8acea373fcc1211ad68 (patch)
tree0220acc1df41102a6a55caf285bfb964cf408be2 /clang/test/Analysis
parent96b42608abbed1a32ad03d905a9377c09a0efb57 (diff)
downloadbcm5719-llvm-05fb371efc0edf15ef4aa8acea373fcc1211ad68.tar.gz
bcm5719-llvm-05fb371efc0edf15ef4aa8acea373fcc1211ad68.zip
[analyzer] Apply the suppression rules to the nil receiver only if the value participates in the computation of the nil we warn about.
We should only suppress a bug report if the IDCed or null returned nil value is directly related to the value we are warning about. This was not the case for nil receivers - we would suppress a bug report that had an IDCed nil receiver on the path regardless of how it’s related to the warning. 1) Thread EnableNullFPSuppression parameter through the visitors to differentiate between tracking the value which is directly responsible for the bug and other values that visitors are tracking (ex: general tracking of nil receivers). 2) in trackNullOrUndef specifically address the case when a value of the message send is nil due to the receiver being nil. llvm-svn: 178309
Diffstat (limited to 'clang/test/Analysis')
-rw-r--r--clang/test/Analysis/NSContainers.m27
-rw-r--r--clang/test/Analysis/inlining/inline-defensive-checks.m69
2 files changed, 94 insertions, 2 deletions
diff --git a/clang/test/Analysis/NSContainers.m b/clang/test/Analysis/NSContainers.m
index 828a9acfdd1..d6fded5fd05 100644
--- a/clang/test/Analysis/NSContainers.m
+++ b/clang/test/Analysis/NSContainers.m
@@ -153,15 +153,24 @@ void testIDC(NSMutableDictionary *d, NSString *key) {
d[key] = @"abc"; // no-warning
}
-@interface Foo
+@interface Foo {
+@public
+ int x;
+}
- (int *)getPtr;
- (int)getInt;
+- (NSMutableDictionary *)getDictPtr;
+@property (retain, readonly, nonatomic) Foo* data;
+- (NSString*) stringForKeyFE: (id<NSCopying>)key;
@end
void idc2(id x) {
if (!x)
return;
}
+Foo *retNil() {
+ return 0;
+}
void testIDC2(Foo *obj) {
idc2(obj);
@@ -173,3 +182,19 @@ int testIDC3(Foo *obj) {
return 1/[obj getInt];
}
+void testNilReceiverIDC(Foo *obj, NSString *key) {
+ NSMutableDictionary *D = [obj getDictPtr];
+ idc(D);
+ D[key] = @"abc"; // no-warning
+}
+
+void testNilReceiverRetNil2(NSMutableDictionary *D, Foo *FooPtrIn, id value) {
+ NSString* const kKeyIdentifier = @"key";
+ Foo *FooPtr = retNil();
+ NSString *key = [[FooPtr data] stringForKeyFE: kKeyIdentifier];
+ // key is nil because FooPtr is nil. However, FooPtr is set to nil inside an
+ // inlined function, so this error report should be suppressed.
+ [D setObject: value forKey: key]; // no-warning
+}
+
+
diff --git a/clang/test/Analysis/inlining/inline-defensive-checks.m b/clang/test/Analysis/inlining/inline-defensive-checks.m
index bafc812486c..a757af3d2fa 100644
--- a/clang/test/Analysis/inlining/inline-defensive-checks.m
+++ b/clang/test/Analysis/inlining/inline-defensive-checks.m
@@ -16,7 +16,6 @@ typedef struct objc_object {
-(id)retain;
@end
-// expected-no-diagnostics
// Check that inline defensive checks is triggered for null expressions
// within CompoundLiteralExpr.
typedef union {
@@ -44,3 +43,71 @@ dispatch_resume(dispatch_object_t object);
dispatch_resume(p); // no warning
}
@end
+
+// Test nil receiver suppression.
+// We only suppress on nil receiver if the nil value is directly causing the bug.
+@interface Foo {
+@public
+ int x;
+}
+- (Foo *)getFooPtr;
+@end
+
+Foo *retNil() {
+ return 0;
+}
+
+Foo *retInputOrNil(Foo *p) {
+ if (p)
+ return p;
+ return 0;
+}
+
+void idc(Foo *p) {
+ if (p)
+ ;
+}
+
+int testNilReceiver(Foo* fPtr) {
+ if (fPtr)
+ ;
+ // On a path where fPtr is nil, mem should be nil.
+ Foo *mem = [fPtr getFooPtr];
+ return mem->x; // expected-warning {{Access to instance variable 'x' results in a dereference of a null pointer}}
+}
+
+int dontSuppressNilReceiverRetNullCond(Foo* fPtr) {
+ unsigned zero = 0;
+ fPtr = retInputOrNil(fPtr);
+ // On a path where fPtr is nil, mem should be nil.
+ // The warning is not suppressed because the receiver being nil is not
+ // directly related to the value that triggers the warning.
+ Foo *mem = [fPtr getFooPtr];
+ if (!mem)
+ return 5/zero; // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int dontSuppressNilReceiverRetNull(Foo* fPtr) {
+ unsigned zero = 0;
+ fPtr = retNil();
+ // On a path where fPtr is nil, mem should be nil.
+ // The warning is not suppressed because the receiver being nil is not
+ // directly related to the value that triggers the warning.
+ Foo *mem = [fPtr getFooPtr];
+ if (!mem)
+ return 5/zero; // expected-warning {{Division by zero}}
+ return 0;
+}
+
+int dontSuppressNilReceiverIDC(Foo* fPtr) {
+ unsigned zero = 0;
+ idc(fPtr);
+ // On a path where fPtr is nil, mem should be nil.
+ // The warning is not suppressed because the receiver being nil is not
+ // directly related to the value that triggers the warning.
+ Foo *mem = [fPtr getFooPtr];
+ if (!mem)
+ return 5/zero; // expected-warning {{Division by zero}}
+ return 0;
+}
OpenPOWER on IntegriCloud