[clang] [LifetimeSafety] Implement a basic use-after-free diagnostic (PR #149731)
Yitzhak Mandelbaum via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 31 09:40:55 PDT 2025
================
@@ -0,0 +1,263 @@
+// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -Wexperimental-lifetime-safety -verify %s
+
+struct MyObj {
+ int id;
+ ~MyObj() {} // Non-trivial destructor
+ MyObj operator+(MyObj);
+};
+
+//===----------------------------------------------------------------------===//
+// Basic Definite Use-After-Free (-W...permissive)
+// These are cases where the pointer is guaranteed to be dangling at the use site.
+//===----------------------------------------------------------------------===//
+
+void definite_simple_case() {
+ MyObj* p;
+ {
+ MyObj s;
+ p = &s; // expected-warning {{object whose reference is captured does not live long enough}}
+ } // expected-note {{destroyed here}}
+ (void)*p; // expected-note {{later used here}}
+}
+
+void no_use_no_error() {
+ MyObj* p;
+ {
+ MyObj s;
+ p = &s;
+ }
+}
+
+void definite_pointer_chain() {
+ MyObj* p;
+ MyObj* q;
+ {
+ MyObj s;
+ p = &s; // expected-warning {{does not live long enough}}
+ q = p;
+ } // expected-note {{destroyed here}}
+ (void)*q; // expected-note {{later used here}}
+}
+
+void definite_multiple_uses_one_warning() {
+ MyObj* p;
+ {
+ MyObj s;
+ p = &s; // expected-warning {{does not live long enough}}
+ } // expected-note {{destroyed here}}
+ (void)*p; // expected-note {{later used here}}
+ // No second warning for the same loan.
+ p->id = 1;
+ MyObj* q = p;
+ (void)*q;
+}
+
+void definite_multiple_pointers() {
+ MyObj *p, *q, *r;
+ {
+ MyObj s;
+ p = &s; // expected-warning {{does not live long enough}}
+ q = &s; // expected-warning {{does not live long enough}}
+ r = &s; // expected-warning {{does not live long enough}}
+ } // expected-note 3 {{destroyed here}}
+ (void)*p; // expected-note {{later used here}}
+ (void)*q; // expected-note {{later used here}}
+ (void)*r; // expected-note {{later used here}}
+}
+
+void definite_single_pointer_multiple_loans(bool cond) {
+ MyObj *p;
+ if (cond){
+ MyObj s;
+ p = &s; // expected-warning {{does not live long enough}}
+ } // expected-note {{destroyed here}}
+ else {
+ MyObj t;
+ p = &t; // expected-warning {{does not live long enough}}
+ } // expected-note {{destroyed here}}
+ (void)*p; // expected-note 2 {{later used here}}
+}
+
+
+//===----------------------------------------------------------------------===//
+// Potential (Maybe) Use-After-Free (-W...strict)
+// These are cases where the pointer *may* become dangling, depending on the path taken.
+//===----------------------------------------------------------------------===//
+
+void potential_if_branch(bool cond) {
+ MyObj safe;
+ MyObj* p = &safe;
+ if (cond) {
+ MyObj temp;
+ p = &temp; // expected-warning {{object whose reference is captured may not live long enough}}
+ } // expected-note {{destroyed here}}
+ (void)*p; // expected-note {{later used here}}
+}
+
+void potential_else_branch(bool cond) {
----------------
ymand wrote:
Is this different than the previous test? I can't find it...
https://github.com/llvm/llvm-project/pull/149731
More information about the cfe-commits
mailing list