Pull in r200899 from upstream clang trunk (by Serge Pavlov): Allow transformation of VariableArray to ConstantArray. In the following code: struct A { static const int sz; }; template void f() { T arr[A::sz]; } the array 'arr' is represented as a variable size array in the template. If 'A::sz' gets value below in the translation unit, the array in instantiation can turn into constant size array. This change fixes PR18633. Differential Revision: http://llvm-reviews.chandlerc.com/D2688 Introduced here: http://svnweb.freebsd.org/changeset/base/261680 Index: tools/clang/test/SemaCXX/c99-variable-length-array.cpp =================================================================== --- tools/clang/test/SemaCXX/c99-variable-length-array.cpp +++ tools/clang/test/SemaCXX/c99-variable-length-array.cpp @@ -140,3 +140,24 @@ namespace PR11744 { } int test = f(0); // expected-note {{instantiation of}} } + +namespace pr18633 { + struct A1 { + static const int sz; + static const int sz2; + }; + const int A1::sz2 = 11; + template + void func () { + int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}} + } + template + void func2 () { + int arr[A1::sz2]; + } + const int A1::sz = 12; + void func2() { + func(); + func2(); + } +} Index: tools/clang/lib/Sema/TreeTransform.h =================================================================== --- tools/clang/lib/Sema/TreeTransform.h +++ tools/clang/lib/Sema/TreeTransform.h @@ -3966,7 +3966,9 @@ TreeTransform::TransformVariableArrayType return QualType(); } - VariableArrayTypeLoc NewTL = TLB.push(Result); + // We might have constant size array now, but fortunately it has the same + // location layout. + ArrayTypeLoc NewTL = TLB.push(Result); NewTL.setLBracketLoc(TL.getLBracketLoc()); NewTL.setRBracketLoc(TL.getRBracketLoc()); NewTL.setSizeExpr(Size);