From 521d382430ca482d4dc40ccd1c9ec226c714d9e9 Mon Sep 17 00:00:00 2001 From: qqiangwu Date: Thu, 30 Jan 2025 23:32:13 +0800 Subject: [PATCH] fix(pset): fix nested invalidation inside *(*this).value --- integration_test/safety/contract_return.cpp | 36 +++++++++++++++++++++ lib/lifetime/LifetimePsetBuilder.cpp | 17 ++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/integration_test/safety/contract_return.cpp b/integration_test/safety/contract_return.cpp index c395d80..610fad6 100644 --- a/integration_test/safety/contract_return.cpp +++ b/integration_test/safety/contract_return.cpp @@ -32,4 +32,40 @@ int* get2() static int x; static int* y = &x; return y; +} + +struct Dummy { + int m; +}; + +const int* get3(); +const int* get4(const Dummy& d); +const int* get5(const Owner& d); +const int* get6(const Owner& d); +const int* get7(const Owner>& d); + +void test_contract_return() +{ + __lifetime_contracts(&get3); + // expected-warning@-1 {{pset(Post((return value))) = ((global), (null))}} + + __lifetime_contracts(&get4); + // expected-warning@-1 {{pset(Pre(d)) = (*d)}} + // expected-warning@-2 {{pset(Pre((*d).m)) = (*d)}} + // expected-warning@-3 {{pset(Post((return value))) = ((null), *d)}} + + __lifetime_contracts(&get5); + // expected-warning@-1 {{pset(Pre(d)) = (*d)}} + // expected-warning@-2 {{pset(Pre(*d)) = (**d)}} + // expected-warning@-3 {{pset(Post((return value))) = ((null), **d)}} + + __lifetime_contracts(&get6); + // expected-warning@-1 {{pset(Pre(d)) = (*d)}} + // expected-warning@-2 {{pset(Pre(*d)) = (**d)}} + // expected-warning@-3 {{pset(Post((return value))) = ((null), **d)}} + + __lifetime_contracts(&get7); + // expected-warning@-1 {{pset(Pre(d)) = (*d)}} + // expected-warning@-2 {{pset(Pre(*d)) = (**d)}} + // expected-warning@-3 {{pset(Post((return value))) = ((null), **d)}} } \ No newline at end of file diff --git a/lib/lifetime/LifetimePsetBuilder.cpp b/lib/lifetime/LifetimePsetBuilder.cpp index 5f1022e..a338081 100644 --- a/lib/lifetime/LifetimePsetBuilder.cpp +++ b/lib/lifetime/LifetimePsetBuilder.cpp @@ -841,7 +841,7 @@ class PSetsBuilder final : public ConstStmtVisitor, public P } if (PS.containsParent(V)) { - // WORKAROUND: https://github.com/qqiangwu/cppsafe/issues/82 + // BADCASE: https://github.com/qqiangwu/cppsafe/issues/82 // // when move var with pset {*container}, only invalidate the var itself, // containers and iterators are not invalidated. @@ -851,7 +851,6 @@ class PSetsBuilder final : public ConstStmtVisitor, public P // for (auto& x : cont) { // p = std::move(x); //} - // for (auto& x: cont) { // use(x); //} @@ -879,6 +878,20 @@ class PSetsBuilder final : public ConstStmtVisitor, public P auto DerefV = V; DerefV.deref(); + if (Var == DerefV) { + // WORKAROUND + // + // inline void PinnableWideColumns::MoveValue(std::string&& value) { + // std::string* const buf = value_.GetSelf(); + // assert(buf); + // + // *buf = std::move(value); // PMap[(*(*this).value_)] = (**(*this).value_) + // + // value_.PinSelf(); + //} + // + continue; + } if (PS.containsParent(DerefV)) { setPSet(PSet::singleton(Var), PSet::invalid(Reason), Reason.getRange()); }