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>
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>
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