|
|
@ -16,18 +16,33 @@ struct A {
|
|
|
|
~A() { delete b; }
|
|
|
|
~A() { delete b; }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct ReferenceWrapper {
|
|
|
|
struct ReferenceWrapperHeap {
|
|
|
|
ReferenceWrapper(A& a) : b(a.getb()){};
|
|
|
|
ReferenceWrapperHeap(A& a) : b(a.getb()){};
|
|
|
|
B* b;
|
|
|
|
B* b;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
ReferenceWrapper getwrapper() {
|
|
|
|
ReferenceWrapperHeap getwrapperHeap() {
|
|
|
|
A a(1);
|
|
|
|
A a(1);
|
|
|
|
return a; // We store a.b in ReferenceWrapper, but we delete a.b in the
|
|
|
|
return a; // We store a.b in ReferenceWrapper, but we delete a.b in the
|
|
|
|
// destructor of A
|
|
|
|
// destructor of A
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int FN_reference_wrapper_bad() {
|
|
|
|
int FN_reference_wrapper_heap_bad() {
|
|
|
|
ReferenceWrapper rw = getwrapper();
|
|
|
|
ReferenceWrapperHeap rw = getwrapperHeap();
|
|
|
|
|
|
|
|
return rw.b->f; // we want to report use after lifetime bug here
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ReferenceWrapperStack {
|
|
|
|
|
|
|
|
ReferenceWrapperStack(B& bref) : b(&bref){};
|
|
|
|
|
|
|
|
B* b;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ReferenceWrapperStack getwrapperStack() {
|
|
|
|
|
|
|
|
B b(1);
|
|
|
|
|
|
|
|
return b;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int FN_reference_wrapper_stack_bad() {
|
|
|
|
|
|
|
|
ReferenceWrapperStack rw = getwrapperStack();
|
|
|
|
return rw.b->f; // we want to report use after lifetime bug here
|
|
|
|
return rw.b->f; // we want to report use after lifetime bug here
|
|
|
|
}
|
|
|
|
}
|
|
|
|