Vanishing warning

Yet another MSVC story. Visual Studio has a nice compile-time warning when trying to access a static array with invalid index - C4789. According to documentation it’s mostly meant for various ‘copy’ functions (memcpy/strcpy etc), but it seems to work on ‘simple’ accesses as well. Consider (here’s a Godbolt link):

struct Tab
{
    float tab[2];
};
void Foo(const Tab&);
void Bar(float forward)
{
    Tab tab;
    tab.tab[0] = forward;
    tab.tab[2] = forward; // OOB access!

    Foo(tab);
}

Compile this one without any optimizations and we get: warning C4789: buffer 'tab' of size 8 bytes will be overrun; 4 bytes will be written starting at offset 8. Nice! (obviously code is simplified a bit and very wrong, but it’s mostly to demonstrate).

However, we now build our Release build, add an /Ox compilation option and… the code compiles silently, warning is gone.

1movss   DWORD PTR tab$[rsp], xmm0
2movss   DWORD PTR tab$[rsp+8], xmm0
3call    void Foo(Tab const & __ptr64)

If you analyze how compiler manages the stack, it’s actually ‘harmless’ as we seem to dedicated more memory than necessary for tab (16 bytes).

tab$ = 32
__$ArrayPad$ = 48

Let’s see what happens if you access an index that way out of range (so that we’d actually be outside even the generously ‘allocated’ space):

tab.tab[4] = forward; // OOB access!

Compile with /Ox and… not only the warning is not there, the invalid access is actually silently eliminated!

1; tab[0] only, where's my (badly broken)  tab[4]?
2movss   DWORD PTR tab$[rsp], xmm0 
3call    void Foo(Tab const & __ptr64)

You could argue it’s not the worst thing, since it’s very unlikely we do want to write to index 4, but I’m not sure I can fully endorse it here ;)

If you’d like to follow this bug I filed a report here

More Reading