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