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