77
88// --- CONSTRAINTS ---
99
10- void nl1 () [[clang::nonblocking]]
10+ void nb1 () [[clang::nonblocking]]
1111{
1212 int *pInt = new int ; // expected-warning {{'nonblocking' function must not allocate or deallocate memory}}
1313 delete pInt; // expected-warning {{'nonblocking' function must not allocate or deallocate memory}}
1414}
1515
16- void nl2 () [[clang::nonblocking]]
16+ void nb2 () [[clang::nonblocking]]
1717{
1818 static int global; // expected-warning {{'nonblocking' function must not have static locals}}
1919}
2020
21- void nl3 () [[clang::nonblocking]]
21+ void nb3 () [[clang::nonblocking]]
2222{
2323 try {
2424 throw 42 ; // expected-warning {{'nonblocking' function must not throw or catch exceptions}}
@@ -27,35 +27,35 @@ void nl3() [[clang::nonblocking]]
2727 }
2828}
2929
30- void nl4_inline () {}
31- void nl4_not_inline (); // expected-note {{function cannot be inferred 'nonblocking' because it has no definition in this translation unit}}
30+ void nb4_inline () {}
31+ void nb4_not_inline (); // expected-note {{function cannot be inferred 'nonblocking' because it has no definition in this translation unit}}
3232
33- void nl4 () [[clang::nonblocking]]
33+ void nb4 () [[clang::nonblocking]]
3434{
35- nl4_inline (); // OK
36- nl4_not_inline (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
35+ nb4_inline (); // OK
36+ nb4_not_inline (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
3737}
3838
3939
4040struct HasVirtual {
4141 virtual void unsafe (); // expected-note {{virtual method cannot be inferred 'nonblocking'}}
4242};
4343
44- void nl5 () [[clang::nonblocking]]
44+ void nb5 () [[clang::nonblocking]]
4545{
4646 HasVirtual hv;
4747 hv.unsafe (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
4848}
4949
50- void nl6_unsafe (); // expected-note {{function cannot be inferred 'nonblocking' because it has no definition in this translation unit}}
51- void nl6_transitively_unsafe ()
50+ void nb6_unsafe (); // expected-note {{function cannot be inferred 'nonblocking' because it has no definition in this translation unit}}
51+ void nb6_transitively_unsafe ()
5252{
53- nl6_unsafe (); // expected-note {{function cannot be inferred 'nonblocking' because it calls non-'nonblocking' function}}
53+ nb6_unsafe (); // expected-note {{function cannot be inferred 'nonblocking' because it calls non-'nonblocking' function}}
5454}
5555
56- void nl6 () [[clang::nonblocking]]
56+ void nb6 () [[clang::nonblocking]]
5757{
58- nl6_transitively_unsafe (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
58+ nb6_transitively_unsafe (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
5959}
6060
6161thread_local int tl_var{ 42 };
@@ -65,15 +65,15 @@ bool tl_test() [[clang::nonblocking]]
6565 return tl_var > 0 ; // expected-warning {{'nonblocking' function must not use thread-local variables}}
6666}
6767
68- void nl7 ()
68+ void nb7 ()
6969{
7070 // Make sure we verify blocks
7171 auto blk = ^() [[clang::nonblocking]] {
7272 throw 42 ; // expected-warning {{'nonblocking' function must not throw or catch exceptions}}
7373 };
7474}
7575
76- void nl8 ()
76+ void nb8 ()
7777{
7878 // Make sure we verify lambdas
7979 auto lambda = []() [[clang::nonblocking]] {
@@ -111,7 +111,7 @@ void nl8()
111111 }
112112 };
113113
114- void nl9 () [[clang::nonblocking]]
114+ void nb9 () [[clang::nonblocking]]
115115{
116116 Adder<int >::add_explicit (1 , 2 );
117117 Adder<int >::add_implicit (1 , 2 );
@@ -121,7 +121,7 @@ void nl9() [[clang::nonblocking]]
121121 expected-note {{in template expansion here}}
122122}
123123
124- void nl10 (
124+ void nb10 (
125125 void (*fp1)(), // expected-note {{function pointer cannot be inferred 'nonblocking'}}
126126 void (*fp2)() [[clang::nonblocking]]
127127 ) [[clang::nonblocking]]
@@ -131,20 +131,20 @@ void nl10(
131131}
132132
133133// Interactions with nonblocking(false)
134- void nl11_no_inference_1 () [[clang::nonblocking(false )]] // expected-note {{function does not permit inference of 'nonblocking'}}
134+ void nb11_no_inference_1 () [[clang::nonblocking(false )]] // expected-note {{function does not permit inference of 'nonblocking'}}
135135{
136136}
137- void nl11_no_inference_2 () [[clang::nonblocking(false )]]; // expected-note {{function does not permit inference of 'nonblocking'}}
137+ void nb11_no_inference_2 () [[clang::nonblocking(false )]]; // expected-note {{function does not permit inference of 'nonblocking'}}
138138
139139template <bool V>
140140struct ComputedNB {
141141 void method () [[clang::nonblocking(V)]]; // expected-note {{function does not permit inference of 'nonblocking'}}
142142};
143143
144- void nl11 () [[clang::nonblocking]]
144+ void nb11 () [[clang::nonblocking]]
145145{
146- nl11_no_inference_1 (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
147- nl11_no_inference_2 (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
146+ nb11_no_inference_1 (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
147+ nb11_no_inference_2 (); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function}}
148148
149149 ComputedNB<true > CNB_true;
150150 CNB_true.method ();
@@ -154,11 +154,11 @@ void nl11() [[clang::nonblocking]]
154154}
155155
156156// Verify that when attached to a redeclaration, the attribute successfully attaches.
157- void nl12 () {
157+ void nb12 () {
158158 static int x; // expected-warning {{'nonblocking' function must not have static locals}}
159159}
160- void nl12 () [[clang::nonblocking]];
161- void nl13 () [[clang::nonblocking]] { nl12 (); }
160+ void nb12 () [[clang::nonblocking]];
161+ void nb13 () [[clang::nonblocking]] { nb12 (); }
162162
163163// C++ member function pointers
164164struct PTMFTester {
@@ -175,21 +175,34 @@ void PTMFTester::convert() [[clang::nonblocking]]
175175}
176176
177177// Block variables
178- void nl17 (void (^blk)() [[clang::nonblocking]]) [[clang::nonblocking]] {
178+ void nb17 (void (^blk)() [[clang::nonblocking]]) [[clang::nonblocking]] {
179179 blk ();
180180}
181181
182182// References to blocks
183- void nl18 (void (^block)() [[clang::nonblocking]]) [[clang::nonblocking]]
183+ void nb18 (void (^block)() [[clang::nonblocking]]) [[clang::nonblocking]]
184184{
185185 auto &ref = block;
186186 ref ();
187187}
188188
189+ // Verify traversal of implicit code paths - constructors and destructors.
190+ struct Unsafe {
191+ static void problem1 (); // expected-note {{function cannot be inferred 'nonblocking' because it has no definition in this translation unit}}
192+ static void problem2 (); // expected-note {{function cannot be inferred 'nonblocking' because it has no definition in this translation unit}}
193+
194+ Unsafe () { problem1 (); } // expected-note {{function cannot be inferred 'nonblocking' because it calls non-'nonblocking' function 'Unsafe::problem1'}}
195+ ~Unsafe () { problem2 (); } // expected-note {{function cannot be inferred 'nonblocking' because it calls non-'nonblocking' function 'Unsafe::problem2'}}
196+ };
197+
198+ struct DerivedFromUnsafe : public Unsafe {
199+ DerivedFromUnsafe () [[clang::nonblocking]] {} // expected-warning {{'nonblocking' function must not call non-'nonblocking' function 'Unsafe::Unsafe'}}
200+ ~DerivedFromUnsafe () [[clang::nonblocking]] {} // expected-warning {{'nonblocking' function must not call non-'nonblocking' function 'Unsafe::~Unsafe'}}
201+ };
189202
190203// --- nonblocking implies noexcept ---
191204#pragma clang diagnostic warning "-Wperf-constraint-implies-noexcept"
192205
193- void nl19 () [[clang::nonblocking]] // expected-warning {{'nonblocking' function should be declared noexcept}}
206+ void nb19 () [[clang::nonblocking]] // expected-warning {{'nonblocking' function should be declared noexcept}}
194207{
195208}
0 commit comments