1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -verify %s
2// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -analyzer-config c++-template-inlining=false -DNO_INLINE -verify %s
3
4void clang_analyzer_eval(bool);
5
6// Do not crash on this templated code which uses a block.
7typedef void (^my_block)(void);
8static void useBlock(my_block block){}
9template<class T> class MyClass;
10typedef MyClass<float> Mf;
11
12template<class T>
13class MyClass
14{
15public:
16  MyClass() {}
17  MyClass(T a);
18  void I();
19private:
20 static const T one;
21};
22
23template<class T> const T MyClass<T>::one = static_cast<T>(1);
24template<class T> inline MyClass<T>::MyClass(T a){}
25template<class T> void MyClass<T>::I() {
26  static MyClass<T>* mPtr = 0;
27  useBlock(^{ mPtr = new MyClass<T> (MyClass<T>::one); });
28};
29int main(){
30  Mf m;
31  m.I();
32}
33
34
35// <rdar://problem/11949235>
36template<class T, unsigned N>
37inline unsigned array_lengthof(T (&)[N]) {
38  return N;
39}
40
41void testNonTypeTemplateInstantiation() {
42  const char *S[] = { "a", "b" };
43  clang_analyzer_eval(array_lengthof(S) == 2);
44#ifndef NO_INLINE
45  // expected-warning@-2 {{TRUE}}
46#else
47  // expected-warning@-4 {{UNKNOWN}}
48#endif
49}
50
51namespace rdar13954714 {
52  template <bool VALUE>
53  bool blockInTemplate() {
54    return (^() {
55      return VALUE;
56    })();
57  }
58
59  // force instantiation
60  template bool blockInTemplate<true>();
61
62  template <bool VALUE>
63  void blockWithStatic() {
64    (void)^() {
65      static int x;
66      return ++x;
67    };
68  }
69
70  // force instantiation
71  template void blockWithStatic<true>();
72}
73