================
@@ -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
+};
+
----------------
dougsonos wrote:

Added  one. This revealed a bug: when verifying a destructor, both bases and 
virtual bases were being traversed but this meant that a virtual base would get 
visited twice. Fixed that by ignoring the virtual bases.

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