Value::referTo(ValueTree::getPropertyAsValue()) seems to leak if the property doesn't exist

this function doesn’t check if the property exists on the tree before returning it.

Value ValueTree::getPropertyAsValue (const Identifier& name, UndoManager* undoManager, bool updateSynchronously)
{
    return Value (new ValueTreePropertyValueSource (*this, name, undoManager, updateSynchronously));
}

calls this:

struct ValueTreePropertyValueSource  : public Value::ValueSource,
                                       private ValueTree::Listener
{
    ValueTreePropertyValueSource (const ValueTree& vt, const Identifier& prop, UndoManager* um, bool sync)
        : tree (vt), property (prop), undoManager (um), updateSynchronously (sync)
    {
        tree.addListener (this);
    }

    ~ValueTreePropertyValueSource() override
    {
        tree.removeListener (this);
    }

    var getValue() const override                 { return tree[property]; } // <-- here

which calls this:

const var& ValueTree::operator[] (const Identifier& name) const noexcept
{
    return object == nullptr ? getNullVarRef() : object->properties[name];
}

which calls this:

const var& NamedValueSet::operator[] (const Identifier& name) const noexcept
{
    if (auto* v = getVarPointer (name))
        return *v;

    return getNullVarRef();
}

This caused a leak for me because I was doing this:

    showCompletedButton.getToggleStateValue().referTo(rootItem->tree.getPropertyAsValue("showCompleted", nullptr));

and the ‘showCompleted’ property didn’t exist on the tree.

once I added the property, the leak went away.

    if( !rootItem->tree.hasProperty("showCompleted") )
        rootItem->tree.setProperty("showCompleted", true, nullptr);

a jassert( tree.hasProperty(name) ) in getPropertyAsValue() would’ve been nice!

What is leaking exactly? That’ll call through to getNullVarRef() which just returns a ref to a static empty var.

Besides, I wonder if you can accidentally add a DynamicObject to the empty static var…?
Or anything else unexpected…
Don’t know, what’s happening in the actual case though.

I’ll try to throw together a PIP that demonstrates the leak.