1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -fblocks
2 
test_nest_lambda()3 void test_nest_lambda() {
4   int x;
5   int y;
6   [&,y]() {
7     int z;
8     #pragma clang __debug captured
9     {
10       x = y; // OK
11       y = z; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}}
12       z = y; // OK
13     }
14   }();
15 
16   int a;
17   #pragma clang __debug captured
18   {
19     int b;
20     int c;
21     [&,c]() {
22       a = b; // OK
23       b = c; // OK
24       c = a; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}}
25     }();
26   }
27 }
28 
29 class test_obj_capture {
30   int a;
31   void b();
test()32   static void test() {
33     test_obj_capture c;
34     #pragma clang __debug captured
35     { (void)c.a; }  // OK
36     #pragma clang __debug captured
37     { c.b(); }      // OK
38   }
39 };
40 
41 class test_this_capture {
42   int a;
43   void b();
test()44   void test() {
45     #pragma clang __debug captured
46     { (void)this; } // OK
47     #pragma clang __debug captured
48     { (void)a; }    // OK
49     #pragma clang __debug captured
50     { b(); }        // OK
51   }
52 };
53 
54 template <typename T>
template_capture_var()55 void template_capture_var() {
56   T x; // expected-error{{declaration of reference variable 'x' requires an initializer}}
57   #pragma clang _debug captured
58   {
59     (void)x;
60   }
61 }
62 
63 template <typename T>
64 class Val {
65   T v;
66 public:
set(const T & v0)67   void set(const T &v0) {
68     #pragma clang __debug captured
69     {
70       v = v0;
71     }
72   }
73 };
74 
test_capture_var()75 void test_capture_var() {
76   template_capture_var<int>(); // OK
77   template_capture_var<int&>(); // expected-note{{in instantiation of function template specialization 'template_capture_var<int &>' requested here}}
78 
79   Val<float> Obj;
80   Obj.set(0.0f); // OK
81 }
82 
83 template <typename S, typename T>
template_capture_var(S x,T y)84 S template_capture_var(S x, T y) {  // expected-note{{variable 'y' declared const here}}
85   #pragma clang _debug captured
86   {
87     x++;
88     y++;  // expected-error{{cannot assign to variable 'y' with const-qualified type 'const int'}}
89   }
90 
91   return x;
92 }
93 
94 // Check if can recover from a template error.
test_capture_var_error()95 void test_capture_var_error() {
96   template_capture_var<int, int>(0, 1); // OK
97   template_capture_var<int, const int>(0, 1); // expected-note{{in instantiation of function template specialization 'template_capture_var<int, const int>' requested here}}
98   template_capture_var<int, int>(0, 1); // OK
99 }
100 
101 template <typename T>
template_capture_in_lambda()102 void template_capture_in_lambda() {
103   T x, y;
104   [=, &y]() {
105     #pragma clang __debug captured
106     {
107       y += x;
108     }
109   }();
110 }
111 
test_lambda()112 void test_lambda() {
113   template_capture_in_lambda<int>(); // OK
114 }
115 
116 struct Foo {
fooFoo117   void foo() { }
barFoo118   static void bar() { }
119 };
120 
121 template <typename T>
template_capture_func(T & t)122 void template_capture_func(T &t) {
123   #pragma clang __debug captured
124   {
125     t.foo();
126   }
127 
128   #pragma clang __debug captured
129   {
130     T::bar();
131   }
132 }
133 
test_template_capture_func()134 void test_template_capture_func() {
135   Foo Obj;
136   template_capture_func(Obj);
137 }
138 
139 template <typename T>
captured_sum(const T & a,const T & b)140 T captured_sum(const T &a, const T &b) {
141   T result;
142 
143   #pragma clang __debug captured
144   {
145     result = a + b;
146   }
147 
148   return result;
149 }
150 
151 template <typename T, typename... Args>
captured_sum(const T & a,const Args &...args)152 T captured_sum(const T &a, const Args&... args) {
153   T result;
154 
155   #pragma clang __debug captured
156   {
157     result = a + captured_sum(args...);
158   }
159 
160   return result;
161 }
162 
test_capture_variadic()163 void test_capture_variadic() {
164   (void)captured_sum(1, 2, 3); // OK
165   (void)captured_sum(1, 2, 3, 4, 5); // OK
166 }
167 
test_capture_with_attributes()168 void test_capture_with_attributes() {
169   [[]] // expected-error {{an attribute list cannot appear here}}
170   #pragma clang __debug captured
171   {
172   }
173 }
174