================
@@ -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}}
----------------
usx95 wrote:

In principle, `lifetimebound` and `noescape` should not occur together on a 
param as they are contradictory. This should be diagnosed differently without 
needing lifetime analysis at all. This belongs to a different PR.

Can you add a FIXME: to diagnose this differently for now.

https://github.com/llvm/llvm-project/pull/177260
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to