================
@@ -0,0 +1,157 @@
+// RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety-noescape -Wlifetime-safety
-Wno-dangling -verify %s
+
+struct [[gsl::Owner]] MyObj {
+ int id;
+ ~MyObj() {} // Non-trivial destructor
+};
+
+struct [[gsl::Pointer()]] View {
+ View(const MyObj&); // Borrows from MyObj
+ View();
+ void use() const;
+};
+
+View return_noescape_directly(const MyObj& in [[clang::noescape]]) { //
expected-warning {{parameter is marked [[clang::noescape]] but escapes}}
+ return in; // expected-note {{returned here}}
+}
+
+View return_one_of_two(
+ const MyObj& a [[clang::noescape]], // expected-warning {{parameter is
marked [[clang::noescape]] but escapes}}
+ const MyObj& b [[clang::noescape]],
+ bool cond) {
+ if (cond)
+ return a; // expected-note {{returned here}}
+ return View();
+}
+
+View return_both(
+ const MyObj& a [[clang::noescape]], // expected-warning {{parameter is
marked [[clang::noescape]] but escapes}}
+ const MyObj& b [[clang::noescape]], // expected-warning {{parameter is
marked [[clang::noescape]] but escapes}}
+ bool cond) {
+ if (cond)
+ return a; // expected-note {{returned here}}
+ return b; // expected-note {{returned here}}
+}
+
+View mixed_noescape_lifetimebound(
+ const MyObj& a [[clang::noescape]], // expected-warning {{parameter is
marked [[clang::noescape]] but escapes}}
+ const MyObj& b [[clang::lifetimebound]],
+ bool cond) {
+ if (cond)
+ return a; // expected-note {{returned here}}
+ return b;
+}
+
+View mixed_only_noescape_escapes(
+ const MyObj& a [[clang::noescape]],
+ const MyObj& b [[clang::lifetimebound]]) {
+ (void)a;
+ return b;
+}
+
+View multiple_reassign(
+ const MyObj& a [[clang::noescape]],
+ const MyObj& b [[clang::noescape]], // expected-warning {{parameter is
marked [[clang::noescape]] but escapes}}
+ const MyObj& c [[clang::noescape]], // expected-warning {{parameter is
marked [[clang::noescape]] but escapes}}
+ bool cond) {
+ View v = a;
+ if (cond)
+ v = b;
+ else
+ v = c;
+ return v; // expected-note 2 {{returned here}}
+}
+
+int* return_noescape_pointer(int* p [[clang::noescape]]) { // expected-warning
{{parameter is marked [[clang::noescape]] but escapes}}
+ return p; // expected-note {{returned here}}
+}
+
+MyObj& return_noescape_reference(MyObj& r [[clang::noescape]]) { //
expected-warning {{parameter is marked [[clang::noescape]] but escapes}}
+ return r; // expected-note {{returned here}}
+}
+
+View return_via_local(const MyObj& in [[clang::noescape]]) { //
expected-warning {{parameter is marked [[clang::noescape]] but escapes}}
+ View v = in;
+ return v; // expected-note {{returned here}}
+}
+
+void use_locally(const MyObj& in [[clang::noescape]]) {
+ View v = in;
+ v.use();
+}
+
+View return_without_noescape(const MyObj& in) {
+ return in;
+}
+
+View return_with_lifetimebound(const MyObj& in [[clang::lifetimebound]]) {
+ return in;
+}
+
+void pointer_used_locally(MyObj* p [[clang::noescape]]) {
+ p->id = 42;
+}
+
+// Noescape should take precedence and warn since the parameter does escape.
+View both_noescape_and_lifetimebound(
+ const MyObj& in [[clang::noescape]] [[clang::lifetimebound]]) { //
expected-warning {{parameter is marked [[clang::noescape]] but escapes}}
+ return in; // expected-note {{returned here}}
+}
+
+View identity_lifetimebound(View v [[clang::lifetimebound]]) { return v; }
+
+View escape_through_lifetimebound_call(
+ const MyObj& in [[clang::noescape]]) { // expected-warning {{parameter is
marked [[clang::noescape]] but escapes}}
+ return identity_lifetimebound(in); // expected-note {{returned here}}
+}
+
+View no_annotation_identity(View v) { return v; }
+
+// FIXME: Escaping through a function without lifetimebound is not detected.
----------------
usx95 wrote:
This will be diagnosed if you enable `-flifetime-safety-inference` :)
https://github.com/llvm/llvm-project/pull/177260
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits