[clang] [LifetimeSafety] Add support for destructive function calls (PR #195064)
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 30 12:50:42 PDT 2026
================
@@ -540,6 +540,71 @@ void function_captured_ref_invalidated() {
} // namespace callable_wrappers
+// FIXME: does not report a double free
+namespace explicit_destructor {
+
+void explicit_destructor_invalidates_pointer() {
+ std::string s = "42";
+ const char *p = s.data(); // expected-warning {{object whose reference is captured is later invalidated}}
+ s.~basic_string(); // expected-note {{invalidated here}}
+ (void)*p; // expected-note {{later used here}}
+}
+
+void pointer_destructor_invalidates_pointer() {
+ char storage[sizeof(std::string)];
+ std::string *obj = new (storage) std::string("42"); // expected-warning {{object whose reference is captured is later invalidated}}
+ const char *p = obj->data();
+ obj->~basic_string(); // expected-note {{invalidated here}}
+ (void)*p; // expected-note {{later used here}}
+}
+
+void destroy_at_invalidates_pointer() {
+ char storage[sizeof(std::string)];
+ std::string *obj = new (storage) std::string("42"); // expected-warning {{object whose reference is captured is later invalidated}}
+ const char *p = obj->data();
+ std::destroy_at(obj); // expected-note {{invalidated here}}
+ (void)*p; // expected-note {{later used here}}
+}
+
+void destroy_at_then_placement_new_rescues_pointer() {
+ char storage[sizeof(std::string)];
+ std::string *obj = new (storage) std::string("42");
+ const char *p = obj->data();
+ std::destroy_at(obj);
+ obj = new (storage) std::string("23");
+ p = obj->data();
+ (void)*p;
+}
+
+void destroy_at_invalidates_array_pointer() {
+ std::string arr[1] = {"42"};
+ std::string (&arr_ref)[1] = arr;
+ const char *p = arr[0].data(); // expected-warning {{object whose reference is captured is later invalidated}}
+ std::destroy_at(&arr_ref); // expected-note {{invalidated here}}
+ (void)*p; // expected-note {{later used here}}
+}
+
+void reference_destructor_invalidates_pointer() {
+ std::string s = "42";
+ std::string &ref = s; // expected-warning {{object whose reference is captured is later invalidated}}
+ const char *p = ref.data();
+ std::destroy_at(&ref); // expected-note {{invalidated here}}
+ (void)*p; // expected-note {{later used here}}
+}
+
+struct StringOwner {
+ std::string s;
+};
+
+void member_destructor_invalidates_pointer() {
+ StringOwner owner = {"42"};
+ const char *p = owner.s.data(); // expected-warning {{object whose reference is captured is later invalidated}}
+ owner.s.~basic_string(); // expected-note {{invalidated here}}
+ (void)*p; // expected-note {{later used here}}
+}
+
----------------
usx95 wrote:
No. It should be fine to have this false-positive for now. This PR is not the reason for this FP. Should be fixed more systematically later.
https://github.com/llvm/llvm-project/pull/195064
More information about the cfe-commits
mailing list