Skip to content

Commit a5a88ca

Browse files
committed
fix(pset): fix nested invalidation inside *(*this).value
1 parent c697303 commit a5a88ca

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

integration_test/safety/contract_return.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,40 @@ int* get2()
3232
static int x;
3333
static int* y = &x;
3434
return y;
35+
}
36+
37+
struct Dummy {
38+
int m;
39+
};
40+
41+
const int* get3();
42+
const int* get4(const Dummy& d);
43+
const int* get5(const Owner<int>& d);
44+
const int* get6(const Owner<Dummy>& d);
45+
const int* get7(const Owner<Pair<int, int>>& d);
46+
47+
void test_contract_return()
48+
{
49+
__lifetime_contracts(&get3);
50+
// expected-warning@-1 {{pset(Post((return value))) = ((global), (null))}}
51+
52+
__lifetime_contracts(&get4);
53+
// expected-warning@-1 {{pset(Pre(d)) = (*d)}}
54+
// expected-warning@-2 {{pset(Pre((*d).m)) = (*d)}}
55+
// expected-warning@-3 {{pset(Post((return value))) = ((null), *d)}}
56+
57+
__lifetime_contracts(&get5);
58+
// expected-warning@-1 {{pset(Pre(d)) = (*d)}}
59+
// expected-warning@-2 {{pset(Pre(*d)) = (**d)}}
60+
// expected-warning@-3 {{pset(Post((return value))) = ((null), **d)}}
61+
62+
__lifetime_contracts(&get6);
63+
// expected-warning@-1 {{pset(Pre(d)) = (*d)}}
64+
// expected-warning@-2 {{pset(Pre(*d)) = (**d)}}
65+
// expected-warning@-3 {{pset(Post((return value))) = ((null), **d)}}
66+
67+
__lifetime_contracts(&get7);
68+
// expected-warning@-1 {{pset(Pre(d)) = (*d)}}
69+
// expected-warning@-2 {{pset(Pre(*d)) = (**d)}}
70+
// expected-warning@-3 {{pset(Post((return value))) = ((null), **d)}}
3571
}

lib/lifetime/LifetimePsetBuilder.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ class PSetsBuilder final : public ConstStmtVisitor<PSetsBuilder, void>, public P
841841
}
842842

843843
if (PS.containsParent(V)) {
844-
// WORKAROUND: https://github.com/qqiangwu/cppsafe/issues/82
844+
// BADCASE: https://github.com/qqiangwu/cppsafe/issues/82
845845
//
846846
// when move var with pset {*container}, only invalidate the var itself,
847847
// containers and iterators are not invalidated.
@@ -851,7 +851,6 @@ class PSetsBuilder final : public ConstStmtVisitor<PSetsBuilder, void>, public P
851851
// for (auto& x : cont) {
852852
// p = std::move(x);
853853
//}
854-
855854
// for (auto& x: cont) {
856855
// use(x);
857856
//}
@@ -879,6 +878,20 @@ class PSetsBuilder final : public ConstStmtVisitor<PSetsBuilder, void>, public P
879878

880879
auto DerefV = V;
881880
DerefV.deref();
881+
if (Var == DerefV) {
882+
// WORKAROUND
883+
//<code>
884+
// inline void PinnableWideColumns::MoveValue(std::string&& value) {
885+
// std::string* const buf = value_.GetSelf();
886+
// assert(buf);
887+
//
888+
// *buf = std::move(value); // PMap[(*(*this).value_)] = (**(*this).value_)
889+
//
890+
// value_.PinSelf();
891+
//}
892+
//</code>
893+
continue;
894+
}
882895
if (PS.containsParent(DerefV)) {
883896
setPSet(PSet::singleton(Var), PSet::invalid(Reason), Reason.getRange());
884897
}

0 commit comments

Comments
 (0)