================ @@ -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) { ---------------- ymand wrote:
Why is this only in strict mode? As long as `cond` is satisfiable (not dead code), we have a safety violation. https://github.com/llvm/llvm-project/pull/149731 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits