================
@@ -0,0 +1,256 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -fcxx-exceptions -std=c++20 -verify 
%s
+// These are in a separate file because errors (e.g. incompatible attributes) 
currently prevent
+// the FXAnalysis pass from running at all.
+
+// This diagnostic is re-enabled and exercised in isolation later in this file.
+#pragma clang diagnostic ignored "-Wperf-constraint-implies-noexcept"
+
+// --- CONSTRAINTS ---
+
+void nb1() [[clang::nonblocking]]
+{
+       int *pInt = new int; // expected-warning {{'nonblocking' function must 
not allocate or deallocate memory}}
+       delete pInt; // expected-warning {{'nonblocking' function must not 
allocate or deallocate memory}}
+}
+
+void nb2() [[clang::nonblocking]]
+{
+       static int global; // expected-warning {{'nonblocking' function must 
not have static locals}}
+}
+
+void nb3() [[clang::nonblocking]]
+{
+       try {
+               throw 42; // expected-warning {{'nonblocking' function must not 
throw or catch exceptions}}
+       }
+       catch (...) { // expected-warning {{'nonblocking' function must not 
throw or catch exceptions}}
+       }
+}
+
+void nb4_inline() {}
+void nb4_not_inline(); // expected-note {{declaration cannot be inferred 
'nonblocking' because it has no definition in this translation unit}}
+
+void nb4() [[clang::nonblocking]]
+{
+       nb4_inline(); // OK
+       nb4_not_inline(); // expected-warning {{'nonblocking' function must not 
call non-'nonblocking' function}}
+}
+
+
+struct HasVirtual {
+       virtual void unsafe(); // expected-note {{virtual method cannot be 
inferred 'nonblocking'}}
+};
+
+void nb5() [[clang::nonblocking]]
+{
+       HasVirtual hv;
+       hv.unsafe(); // expected-warning {{'nonblocking' function must not call 
non-'nonblocking' function}}
+}
+
+void nb6_unsafe(); // expected-note {{declaration cannot be inferred 
'nonblocking' because it has no definition in this translation unit}}
+void nb6_transitively_unsafe()
+{
+       nb6_unsafe(); // expected-note {{function cannot be inferred 
'nonblocking' because it calls non-'nonblocking' function}}
+}
+
+void nb6() [[clang::nonblocking]]
+{
+       nb6_transitively_unsafe(); // expected-warning {{'nonblocking' function 
must not call non-'nonblocking' function}}
+}
+
+thread_local int tl_var{ 42 };
+
+bool tl_test() [[clang::nonblocking]]
+{
+       return tl_var > 0; // expected-warning {{'nonblocking' function must 
not use thread-local variables}}
+}
+
+void nb7()
+{
+       // Make sure we verify blocks
+       auto blk = ^() [[clang::nonblocking]] {
+               throw 42; // expected-warning {{'nonblocking' function must not 
throw or catch exceptions}}
+       };
+}
+
+void nb8()
+{
+       // Make sure we verify lambdas
+       auto lambda = []() [[clang::nonblocking]] {
+               throw 42; // expected-warning {{'nonblocking' function must not 
throw or catch exceptions}}
+       };
+}
+
+void nb8a() [[clang::nonblocking]]
+{
+       // A blocking lambda shouldn't make the outer function unsafe.
+       auto unsafeLambda = []() {
+               throw 42;
+       };
+}
+
+void nb8b() [[clang::nonblocking]]
+{
+       // An unsafe lambda capture makes the outer function unsafe.
+       auto unsafeCapture = [foo = new int]() { // expected-warning 
{{'nonblocking' function must not allocate or deallocate memory}}
+               delete foo;
----------------
Sirraide wrote:

Maybe add a test for `__builtin_operator_new`/`__builtin_operator_delete` too.

https://github.com/llvm/llvm-project/pull/99656
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to