1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -fblocks |
2 | |
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(); |
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(); |
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> |
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: |
67 | void set(const T &v0) { |
68 | #pragma clang __debug captured |
69 | { |
70 | v = v0; |
71 | } |
72 | } |
73 | }; |
74 | |
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. |
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> |
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 | |
112 | void test_lambda() { |
113 | template_capture_in_lambda<int>(); // OK |
114 | } |
115 | |
116 | struct Foo { |
117 | void foo() { } |
118 | static void bar() { } |
119 | }; |
120 | |
121 | template <typename 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 | |
134 | void test_template_capture_func() { |
135 | Foo Obj; |
136 | template_capture_func(Obj); |
137 | } |
138 | |
139 | template <typename T> |
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 | |
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 | |
168 | void test_capture_with_attributes() { |
169 | [[]] // expected-error {{an attribute list cannot appear here}} |
170 | #pragma clang __debug captured |
171 | { |
172 | } |
173 | } |
174 | |