If you want to bypass virtual dispatch and call the function body you have defined, you must qualify the function name:
virtual ~A() { A::f(); } // OK.
Otherwise, the call will initiate virtual dispatch, but only to the base class, because the object of derived type has already been destroyed before its bases.
C++11 §12.7/4 directly addresses your question:
Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). When a virtual function is called directly or indirectly from a constructor or from a destructor, including during the construction or destruction of the class’s non-static data members, and the object to which the call applies is the object (call it x) under construction or destruction, the function called is the final overrider in the constructor’s or destructor’s class and not one overriding it in a more-derived class. If the virtual function call uses an explicit class member access (5.2.5) and the object expression refers to the complete object of x or one of that object’s base class subobjects but not x or one of its base class subobjects, the behavior is undefined.
However, §10.4/6 forbids doing this with a pure virtual function:
Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.
So, it's UB.
The effect of "pure virtual" is to hide the function definition from virtual lookup. You will never reach the definition of a pure virtual function from a dynamic dispatch function call, except perhaps as an effect of undefined behavior.