]> granicus.if.org Git - clang/commitdiff
Allow transformation of VariableArray to ConstantArray.
authorSerge Pavlov <sepavloff@gmail.com>
Thu, 6 Feb 2014 03:49:11 +0000 (03:49 +0000)
committerSerge Pavlov <sepavloff@gmail.com>
Thu, 6 Feb 2014 03:49:11 +0000 (03:49 +0000)
In the following code:

    struct A { static const int sz; };
    template<class T> 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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200899 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/TreeTransform.h
test/SemaCXX/c99-variable-length-array.cpp

index 93cb48332123a5ab1681c5af033a1b9416545e52..7afed1a448022ddc5be767f3598d131b61f7ed9f 100644 (file)
@@ -3929,7 +3929,9 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
       return QualType();
   }
 
-  VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
+  // We might have constant size array now, but fortunately it has the same
+  // location layout.
+  ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
   NewTL.setLBracketLoc(TL.getLBracketLoc());
   NewTL.setRBracketLoc(TL.getRBracketLoc());
   NewTL.setSizeExpr(Size);
index bb620c71fa070ae135897adbdd6835bf65391ba7..237f56458dab3c77b7ab44eef0ec1c3aac8bfea8 100644 (file)
@@ -140,3 +140,24 @@ namespace PR11744 {
   }
   int test = f<int>(0); // expected-note {{instantiation of}}
 }
+
+namespace pr18633 {
+  struct A1 {
+    static const int sz;
+    static const int sz2;
+  };
+  const int A1::sz2 = 11;
+  template<typename T>
+  void func () {
+    int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}}
+  }
+  template<typename T>
+  void func2 () {
+    int arr[A1::sz2];
+  }
+  const int A1::sz = 12;
+  void func2() {
+    func<int>();
+    func2<int>();
+  }
+}