]> granicus.if.org Git - clang/commit
Fix PR32933: crash on lambda capture of VLA
authorFaisal Vali <faisalv@yahoo.com>
Mon, 15 May 2017 01:49:19 +0000 (01:49 +0000)
committerFaisal Vali <faisalv@yahoo.com>
Mon, 15 May 2017 01:49:19 +0000 (01:49 +0000)
commit0f9b7cd618ad70955e67f9c3c9b48321a13dc624
tree940f2a7043f9c72dc3f41e1c79ec0914aca10b68
parent848b631d3a1e857e2ad2fe61f09ad6de50e89c25
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?! ;)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303026 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Sema/SemaStmt.cpp
test/CodeGenCXX/vla.cpp
test/SemaCXX/for-range-examples.cpp