
struct {
    float f;
} Foo;

struct {
    Foo *foo;
} Bar;

Foo *psFooAlloc () {
    Foo *foo = (Foo *) psAlloc (1);
    return (foo);
}

psFooFree (Foo *foo) {
    Nref = GetRef (foo);
    switch (Nref) {
      case 0: 
	return;
      case 1:
	DecrRef (foo);
	psFree (foo);
	return;
      default:
	DecrRef (foo);
	return;
    }
    return;				// cannot reach here
}

Bar *psBarAlloc () {

    Bar *bar = (Bar *) psAlloc (1);
    bar[0].foo = NULL;

    return (bar);

}

psBarFree (Bar *bar) {
    Nref = GetRef (bar);
    switch (Nref) {
      case 0: 
	return;
      case 1:
	psFooFree (bar[0].foo);
	DecrRef (bar);
	psFree (bar);
	return;
      default:
	DecrRef (bar);
	return;
    }
    return;				// cannot reach here
}

Bar *psBarSet (Foo *foo) {
    Bar *bar = NULL;
    bar = psBarAlloc ();
    bar[0].foo = foo;
    IncrRef (foo);
}

main.bad () {

    Foo *foo = NULL;
    Bar *bar = NULL;

    foo = psFooAlloc ();		// Nref(foo) = 1
    bar = psBarSet (foo);		// Nref(foo) = 2
    psFree (foo);			// Nref(foo) = 1  ** returns an error **
    psFree (bar);			// Nref(foo) = 1  ** does not free foo **
}

main.good () {

    Foo *foo = NULL;
    Bar *bar = NULL;

    foo = psFooAlloc ();		// Nref(foo) = 1
    bar = psBarSet (foo);		// Nref(foo) = 2
    psFooFree (foo);			// Nref(foo) = 1
    psBarFree (bar);			// Nref(foo) = 0
}
