Fix PR32933: crash on lambda capture of VLA

https://bugs.llvm.org/show_bug.cgi?id=32933

Turns out clang wasn't really handling vla's (*) in C++11's for-range entirely correctly. 

For e.g. This would lead to generation of buggy IR:

  void foo(int b) {
    int vla[b];
    b = -1;  // This store would affect the '__end = vla + b'
    for (int &c : vla) 
      c = 0;
  }

Additionally, code-gen would get confused when VLA's were reference-captured by lambdas, and then used in a for-range, which would result in an attempt to generate IR for '__end = vla + b' within the lambda's body - without any capture of 'b' - hence the assertion.

This patch modifies clang, so that for VLA's it translates the end pointer approximately into:
  __end = __begin + sizeof(vla)/sizeof(vla->getElementType())

As opposed to the __end = __begin + b;

I considered passing a magic value into codegen - or having codegen special case the '__end' variable when it referred to a variably-modified type, but I decided against that approach, because it smelled like I would be increasing a complicated form of coupling, that I think would be even harder to maintain than the above approach (which can easily be optimized (-O1) to refer to the run-time bound that was calculated upon array's creation or copied into the lambda's closure object).


(*) why oh why gcc would you enable this by default?! ;)

llvm-svn: 303026
diff --git a/clang/test/SemaCXX/for-range-examples.cpp b/clang/test/SemaCXX/for-range-examples.cpp
index 08a9982..d6b527f 100644
--- a/clang/test/SemaCXX/for-range-examples.cpp
+++ b/clang/test/SemaCXX/for-range-examples.cpp
@@ -241,3 +241,37 @@
     }
   }
 }
+
+namespace PR32933 {
+// https://bugs.llvm.org/show_bug.cgi?id=32933
+void foo ()
+{ 
+  int b = 1, a[b];
+  a[0] = 0;
+  [&] { for (int c : a) 0; } ();
+}
+
+
+int foo(int b) {
+  int varr[b][(b+=8)];
+  b = 15; 
+  [&] {
+    int i = 0;
+    for (auto &c : varr) 
+    {
+      c[0] = ++b;
+    }
+    [&] {
+      int i = 0;
+      for (auto &c : varr) {
+        int j = 0;
+        for(auto &c2 : c) {
+          ++j;
+        }
+        ++i;
+      }
+    }();
+  }();
+  return b;
+}
+}
\ No newline at end of file