Something got broken around version 16.6.1 of Visual C++ compiler

Ancient piece of code started giving troubles:

template <typename T>
class ATL_NO_VTABLE CMediaControlT :
    ...
{
    ...
    STDMETHOD(Run)()
    {
        ...
        T* MSVC_FIX_VOLATILE pT = static_cast<T*>(this); // <<--------------------------------
        CRoCriticalSectionLock GraphLock(pT->m_GraphCriticalSection);
        pT->FilterGraphNeeded();
        __D(pT->GetMediaControl(), E_NOINTERFACE);
        pT->PrepareCue();
        pT->DoRun();
        __if_exists(T::Fire_Running)
        {
            pT->Fire_Running();
        }
    ...
}

When MSVC_FIX_VOLATILE is nothing, it appears that optimizing compiler forgets pT and uses just some variation of adjusted this, which makes sense overall because static cast between the two can be resolved at compile time.

However, the problem is that the value of this is wrong and there is undefined behavior scenario.

If I make MSVC_FIX_VOLATILE to be volatile and have the variable pT somewhat “heavier”, optimizing compiler would forget this and uses pT directly with everything working as expected.

The problem still exists in current 16.6.2.

Leave a Reply