Visual Studio 2015 Code Analysis C6386 warns of buffer overrun

Static code analysis is hard, tracing possible values of an expression like 3 + 2 * nNumItems is hard, and tracing actual possible values is often near to impossible. This is why it is a warning, not error. So far for the obvious.

Now, looking at how you describe that this warning behaves, I would bet on a “bug”, or rather, I should say it with less stress, deficiency, in the static analyzer.

I can see some imaginary possible causes behind this warning on original nWords[1] = 2 and global nNumItems. They are really weird and I don’t think a reasonable analyst would add such rules to the analyzer. Also, I were right, then you should have these warnings on nWords[0] = 1 as well.

The fact that you don’t see them on that proves my ideas wrong, so I stop here.

Instead, I would like to focus on that static code analysis is hard. It does not matter how well-written the analyzer and its rules are. For some cases, it will make errors, and for other cases it will simply fail and won’t be even able to guess, and for other cases it will timeout and just let go. Until we have some breakthrough in AI or breakthrough in solving NP-hard problems, you will probably have to get used to the fact, that when you are using static code analyzers, then you have to write code in a way that they can comprehend, not count on that they can comprehend everything you can write.

Last thought, when I see this error:

file.cpp(18): warning C6386: Buffer overrun while writing to ‘nWords’: the writable size is ‘nTotal*4’ bytes, but ‘8’ bytes might be written.

the first thing that I notice is nTotal*4 and 8. If you were using a hardcoded values, you would probably get an error like

file.cpp(18): warning C6386: Buffer overrun while writing to ‘nWords’: the writable size is ‘1024’ bytes, but ‘8192’ bytes might be written.

The fact that you see nTotal*4 seems to imply that the static code analyzer actually failed to guess the value under nTotal and it left it as symbolic name, which formed an expression incomparable to 8. Therefore, the analyzer did theonly thing it could – it reported a problem, and described it as well as it could. Still, it’s just my guess.

// EDIT – note for Dan’s answer about guessing: nNumItems <- SIZE_MAX

I actually think that he’s may be quite about the SIZE_MAX. I played a bit with some SAT solvers from Microsoft, and one thing they did well was solving set of constraints in integer domain. Actually unsigned int x = SIZE_MAX; std::cout << ( (3+2*x)*sizeof(int) ); prints 4 (of course), and that is the only value of x for which the expression is less than 8.

I’m pretty sure that the constraint solver from microsoft I played with can detect this case when checking satisfiability of ((3+2*x)*4) < 8 in integer ring domain – hence the warning could be issued. However, I would expect the warning to include the result and print something like:

nTotal*4 < 8 when {nTotal=1,nNumItems=4294967295}`

since the analyzer had would have this information already. But then, that’s.. probably expecting too much from it. Developers behind it probably wouldn’t have thought of formatting such detailed warning message, or considered current format of the message to be more user-friendly.

Leave a Comment