diff options
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/Analysis/retain-release-crashes.m | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/clang/test/Analysis/retain-release-crashes.m b/clang/test/Analysis/retain-release-crashes.m new file mode 100644 index 00000000000..40171a39c95 --- /dev/null +++ b/clang/test/Analysis/retain-release-crashes.m @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit,debug.ExprInspection -verify -w %s + +// This file contains crash regression tests; please do not remove any checkers +// from the RUN line because they may have been necessary to produce the crash. +// (Adding checkers should be fine.) + +void clang_analyzer_eval(int); + +@interface NSObject +- (id)init; +@end + +@interface Foo : NSObject +@end + +void touch(id, SEL); +id getObject(); +int getInt(); + + +@implementation Foo +// Bizarre crash related to the ExprEngine reaching a previously-seen +// ExplodedNode /during/ the processing of a message. Removing any +// parts of this test case seem not to trigger the crash any longer. +// <rdar://problem/12243648> +- (id)init { + // Step 0: properly call the superclass's initializer + self = [super init]; + if (!self) return self; + + // Step 1: Perturb the state with a new conjured symbol. + int value = getInt(); + + // Step 2: Loop. Some loops seem to trigger this, some don't. + // The original used a for-in loop. + while (--value) { + // Step 3: Make it impossible to retain-count 'self' by calling + // a function that takes a "callback" (in this case, a selector). + // Note that this does not trigger the crash if you use a message! + touch(self, @selector(hi)); + } + + // Step 4: Use 'self', so that we know it's non-nil. + [self bar]; + + // Step 5: Once again, make it impossible to retain-count 'self'... + // ...while letting ObjCSelfInitChecker mark this as an interesting + // message, since 'self' is an argument... + // ...but this time do it in such a way that we'll also assume that + // 'other' is non-nil. Once we've made the latter assumption, we + // should cache out. + id other = getObject(); + [other use:self withSelector:@selector(hi)]; + + // Step 6: Check that we did, in fact, keep the assumptions about 'self' + // and 'other' being non-nil. + clang_analyzer_eval(other != 0); // expected-warning{{TRUE}} + clang_analyzer_eval(self != 0); // expected-warning{{TRUE}} + + return self; +} +@end |

