What can be done about that? Stop using terrible programming styles.
If you're going to use a singleton, then it should be a singleton: one instance, period. There's no need for managing its lifetime with smart pointers; it's always there. What's the point of destroying it only to recreate it later? Especially if the recreation function isn't given special parameters to recreate it later?
However, to your question:
does it guarantee (it doesn't) that the destructor of the previous singleton has completed
Does it matter? In order for the object's destructor to be started, the count of shared_ptr references to the object must be zero. So the weak_ptr is already empty. An object's lifetime ends when its destructor starts (just as an object's lifetime begins when its constructor completes). So the singleton itself is already destroyed; you're just doing cleanup work.
So there is no problem with creating a new instance of the singleton within the callstack of the old instance's destructor. It simply won't be accessing itself.
Threading
In a multithreaded environment, this kind of interface is already terribly broken without some kind of lock within the get function that returns/creates the singleton. Without such mutual exclusion, multiple threads could try to create the singleton simultaneously, which could cause the construction of multiple singleton instances.
As for resources within the singleton itself, the release of such resources has to be governed by some form of mutual exclusion mechanism already. The only time when a resource is itself a singleton. But unlike the singleton we're talking about, it would be one that cannot be owned by multiple pieces of code.
In that case, your singleton shouldn't have ownership of that resource at all. It can reference it, but it cannot destroy or create it.