summaryrefslogtreecommitdiffstats
path: root/test/Analysis/misc-ps-region-store.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/misc-ps-region-store.m')
-rw-r--r--test/Analysis/misc-ps-region-store.m99
1 files changed, 97 insertions, 2 deletions
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index e5113ba..e736e0f 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -1,5 +1,5 @@
-// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks %s
-// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks %s
+// RUN: clang -cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: clang -cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
typedef struct objc_selector *SEL;
typedef signed char BOOL;
@@ -541,3 +541,98 @@ double rdar_6811085(void) {
return u + 10; // expected-warning{{The left operand of '+' is a garbage value}}
}
+//===----------------------------------------------------------------------===//
+// Path-sensitive tests for blocks.
+//===----------------------------------------------------------------------===//
+
+void indirect_block_call(void (^f)());
+
+int blocks_1(int *p, int z) {
+ __block int *q = 0;
+ void (^bar)() = ^{ q = p; };
+
+ if (z == 1) {
+ // The call to 'bar' might cause 'q' to be invalidated.
+ bar();
+ *q = 0x1; // no-warning
+ }
+ else if (z == 2) {
+ // The function 'indirect_block_call' might invoke bar, thus causing
+ // 'q' to possibly be invalidated.
+ indirect_block_call(bar);
+ *q = 0x1; // no-warning
+ }
+ else {
+ *q = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+ }
+ return z;
+}
+
+int blocks_2(int *p, int z) {
+ int *q = 0;
+ void (^bar)(int **) = ^(int **r){ *r = p; };
+
+ if (z) {
+ // The call to 'bar' might cause 'q' to be invalidated.
+ bar(&q);
+ *q = 0x1; // no-warning
+ }
+ else {
+ *q = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}}
+ }
+ return z;
+}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7462324> - Test that variables passed using __blocks
+// are not treated as being uninitialized.
+//===----------------------------------------------------------------------===//
+
+typedef void (^RDar_7462324_Callback)(id obj);
+
+@interface RDar7462324
+- (void) foo:(id)target;
+- (void) foo_positive:(id)target;
+
+@end
+
+@implementation RDar7462324
+- (void) foo:(id)target {
+ __block RDar_7462324_Callback builder = ((void*) 0);
+ builder = ^(id object) {
+ if (object) {
+ builder(self); // no-warning
+ }
+ };
+ builder(target);
+}
+- (void) foo_positive:(id)target {
+ __block RDar_7462324_Callback builder = ((void*) 0);
+ builder = ^(id object) {
+ id x;
+ if (object) {
+ builder(x); // expected-warning{{Pass-by-value argument in function call is undefined}}
+ }
+ };
+ builder(target);
+}
+@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7468209> - Scanning for live variables within a block should
+// not crash on variables passed by reference via __block.
+//===----------------------------------------------------------------------===//
+
+int rdar7468209_aux();
+void rdar7468209_aux2();
+
+void rdar7468209() {
+ __block int x = 0;
+ ^{
+ x = rdar7468209_aux();
+ // We need a second statement so that 'x' would be removed from the store if it wasn't
+ // passed by reference.
+ rdar7468209_aux_2();
+ }();
+}
+
OpenPOWER on IntegriCloud