Diagnose misused __block variables. Radar 7760213. Patch by Fariborz Jahanian!
llvm-svn: 98913
diff --git a/llvm-gcc-4.2/gcc/ChangeLog.apple b/llvm-gcc-4.2/gcc/ChangeLog.apple
index edfdb62..144f52f 100644
--- a/llvm-gcc-4.2/gcc/ChangeLog.apple
+++ b/llvm-gcc-4.2/gcc/ChangeLog.apple
@@ -1,3 +1,11 @@
+2010-03-16 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 7760213
+ * c-common.h (HasByrefArray): New decl.
+ * c-common.c (HasByrefArray): New definition.
+ * c-typeck.c (build_external_ref): Diagnose access of
+ __block array.
+
2010-01-07 Jim Grosbach <grosbach@apple.com>
Radar 7519550
diff --git a/llvm-gcc-4.2/gcc/c-common.c b/llvm-gcc-4.2/gcc/c-common.c
index 4e7e6ca..aa579a1 100644
--- a/llvm-gcc-4.2/gcc/c-common.c
+++ b/llvm-gcc-4.2/gcc/c-common.c
@@ -9355,4 +9355,20 @@
return build_function_call (build_block_object_dispose_decl (), func_params);
}
/* APPLE LOCAL end radar 5847976 */
+/* APPLE LOCAL begin radar 7760213 */
+int HasByrefArray(tree byrefType)
+{
+ tree s1;
+ /* Check for possibility of an error condition. */
+ if (TREE_CODE(byrefType) != RECORD_TYPE)
+ return 0;
+
+ for (s1 = TYPE_FIELDS (byrefType); s1; s1 = TREE_CHAIN (s1))
+ {
+ if (TREE_CODE(TREE_TYPE(s1)) == ARRAY_TYPE)
+ return 1;
+ }
+ return 0;
+}
+/* APPLE LOCAL end radar 7760213 */
#include "gt-c-common.h"
diff --git a/llvm-gcc-4.2/gcc/c-common.h b/llvm-gcc-4.2/gcc/c-common.h
index db3434f..6f03d8c 100644
--- a/llvm-gcc-4.2/gcc/c-common.h
+++ b/llvm-gcc-4.2/gcc/c-common.h
@@ -1242,6 +1242,9 @@
/* APPLE LOCAL radar 6353006 */
extern tree c_build_generic_block_struct_type (void);
+/* APPLE LOCAL radar 7760213 */
+extern int HasByrefArray(tree);
+
/* In c-omp.c */
extern tree c_finish_omp_master (tree);
extern tree c_finish_omp_critical (tree, tree);
diff --git a/llvm-gcc-4.2/gcc/c-typeck.c b/llvm-gcc-4.2/gcc/c-typeck.c
index 8b7bd64..19373f0 100644
--- a/llvm-gcc-4.2/gcc/c-typeck.c
+++ b/llvm-gcc-4.2/gcc/c-typeck.c
@@ -2146,6 +2146,7 @@
"array indexing");
}
}
+
/* Build an external reference to identifier ID. FUN indicates
whether this will be used for a function call. LOC is the source
@@ -2209,9 +2210,14 @@
{
/* APPLE LOCAL begin radar 5803600 (C++ ci) */
/* byref globals are directly accessed. */
- if (!gdecl)
+ /* APPLE LOCAL begin radar 7760213 */
+ if (!gdecl) {
+ if (HasByrefArray(TREE_TYPE (decl)))
+ error ("cannot access __block variable of array type inside block");
/* build a decl for the byref variable. */
decl = build_block_byref_decl (id, decl, decl);
+ }
+ /* APPLE LOCAL end radar 7760213 */
else
add_block_global_byref_list (decl);
}
diff --git a/llvm-gcc-4.2/gcc/cp/semantics.c b/llvm-gcc-4.2/gcc/cp/semantics.c
index 3c75f45..f732f25 100644
--- a/llvm-gcc-4.2/gcc/cp/semantics.c
+++ b/llvm-gcc-4.2/gcc/cp/semantics.c
@@ -2511,9 +2511,14 @@
|| (TREE_CODE (decl) == VAR_DECL && COPYABLE_BYREF_LOCAL_VAR (decl)))
{
/* byref globals are directly accessed. */
- if (!gdecl)
+ /* APPLE LOCAL begin radar 7760213 */
+ if (!gdecl) {
+ if (HasByrefArray(TREE_TYPE (decl)))
+ error ("cannot access __block variable of array type inside block");
/* build a decl for the byref variable. */
decl = build_block_byref_decl (name, decl, decl);
+ }
+ /* APPLE LOCAL end radar 7760213 */
else
add_block_global_byref_list (decl);
}
diff --git a/llvm-gcc-4.2/gcc/testsuite/ChangeLog.apple b/llvm-gcc-4.2/gcc/testsuite/ChangeLog.apple
index 40e751d..4f4a68b 100644
--- a/llvm-gcc-4.2/gcc/testsuite/ChangeLog.apple
+++ b/llvm-gcc-4.2/gcc/testsuite/ChangeLog.apple
@@ -3,6 +3,12 @@
Radar 6671703
* objc.dg/arm-scalar-atomic-copyStruct.m: New.
+2010-03-16 Fariborz Jahanian <fjahanian@apple.com>
+
+ Radar 7760213
+ * gcc.apple/block-dynamic-array.c: Modified.
+ * g++.apple/block-dynamic-array.C: Modified.
+
2009-11-03 Stuart Hastings <stuart@apple.com>
Radar 6951876
diff --git a/llvm-gcc-4.2/gcc/testsuite/g++.apple/block-dynamic-array.C b/llvm-gcc-4.2/gcc/testsuite/g++.apple/block-dynamic-array.C
index 7ecc406..d11e87d 100644
--- a/llvm-gcc-4.2/gcc/testsuite/g++.apple/block-dynamic-array.C
+++ b/llvm-gcc-4.2/gcc/testsuite/g++.apple/block-dynamic-array.C
@@ -75,3 +75,12 @@
[pool drain];
return 0 + res;
}
+
+int test()
+{
+__block int arr[100];
+
+ ^ {
+ (void)arr[2]; /* { dg-error "cannot access __block variable of array type inside block" } */
+ };
+}
diff --git a/llvm-gcc-4.2/gcc/testsuite/gcc.apple/block-dynamic-array.c b/llvm-gcc-4.2/gcc/testsuite/gcc.apple/block-dynamic-array.c
index 6301ca4..1be0c31 100644
--- a/llvm-gcc-4.2/gcc/testsuite/gcc.apple/block-dynamic-array.c
+++ b/llvm-gcc-4.2/gcc/testsuite/gcc.apple/block-dynamic-array.c
@@ -75,3 +75,12 @@
[pool drain];
return 0 + res;
}
+
+int test()
+{
+__block int arr[100];
+
+ ^ {
+ (void)arr[2]; /* { dg-error "cannot access __block variable of array type inside block" } */
+ };
+}