[clang] nonblocking/nonallocating attributes: 2nd pass caller/callee analysis (PR #99656)

via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 28 05:52:27 PDT 2024


================
@@ -210,24 +210,88 @@ void nb18(void (^block)() [[clang::nonblocking]]) [[clang::nonblocking]]
 }
 
 // Builtin functions
-void nb18a() [[clang::nonblocking]] {
+void nb19() [[clang::nonblocking]] {
 	__builtin_assume(1);
 	void *ptr = __builtin_malloc(1); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function '__builtin_malloc'}}
 	__builtin_free(ptr); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function '__builtin_free'}}
+	
+	void *p2 = __builtin_operator_new(1); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function '__builtin_operator_new'}}
+	__builtin_operator_delete(p2); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function '__builtin_operator_delete'}}
+}
+
+// Function try-block
+void catches() try {} catch (...) {} // expected-note {{function cannot be inferred 'nonblocking' because it throws or catches exceptions}}
+
+void nb20() [[clang::nonblocking]] {
+	catches(); // expected-warning {{'nonblocking' function must not call non-'nonblocking' function 'catches'}}
+}
+
+struct S {
+    int x;
+    S(int x) try : x(x) {} catch (...) {} // expected-note {{constructor cannot be inferred 'nonblocking' because it throws or catches exceptions}}
+    S(double) : x((throw 3, 3)) {} // expected-note {{member initializer cannot be inferred 'nonblocking' because it throws or catches exceptions}} \
+                                      expected-note {{in constructor here}}
+};
+
+int badi(); // expected-note {{declaration cannot be inferred 'nonblocking' because it has no definition in this translation unit}} \
+            // expected-note {{declaration cannot be inferred 'nonblocking' because it has no definition in this translation unit}}
+
+struct A {                // expected-note {{in implicit constructor here}}
+    int x = (throw 3, 3); // expected-note {{member initializer cannot be inferred 'nonblocking' because it throws or catches exceptions}}
+};
+
+struct B {
+    int y = badi(); // expected-note {{member initializer cannot be inferred 'nonblocking' because it calls non-'nonblocking' function 'badi'}}
+};
+
+void f() [[clang::nonblocking]] {
+    S s1(3);   // expected-warning {{'nonblocking' function must not call non-'nonblocking' constructor 'S::S'}}
+    S s2(3.0); // expected-warning {{'nonblocking' function must not call non-'nonblocking' constructor 'S::S'}}
+    A a;       // expected-warning {{'nonblocking' function must not call non-'nonblocking' constructor 'A::A'}}
+    B b;       // expected-warning {{'nonblocking' function must not call non-'nonblocking' constructor 'B::B'}}
+}
+
+struct T {
+	int x = badi();               // expected-warning {{'nonblocking' constructor's member initializer must not call non-'nonblocking' function 'badi'}}
+	T() [[clang::nonblocking]] {} // expected-note {{in constructor here}}
+	T(int x) [[clang::nonblocking]] : x(x) {} // OK
+};
+
----------------
Sirraide wrote:

Do we have tests for virtual inheritance anywhere?

https://github.com/llvm/llvm-project/pull/99656


More information about the cfe-commits mailing list