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" } */
+    };
+}