If I understand correctly, everything is working as intended: a fuzzer caught a bug in an unreleased version of clang. The title makes it sound like somebody fucked up pretty badly.
Question for any low-level optimizing compiler engineers here: I obviously realize these are all important, but in your judgment, how much of making an error-free compiler would you say is about having a comprehensive test suite, vs. having <i>very</i> careful software engineers, vs. having extremely thorough code reviews, vs. something else? Put another way, if you were to lose one of these, which ones do you think would have the most/least negative impact (or be the easiest/hardest to make up for with other things) in terms of the correctness of the final product?
These sorts of bugs are more common than you may think! Here’s gcc miscompiling fish shell: <a href="https://github.com/fish-shell/fish-shell/issues/6962" rel="nofollow">https://github.com/fish-shell/fish-shell/issues/6962</a>
I don't understand trying to use the trunk version of a under-development compiler. Would you use the binaries built from an unstable compiler in production?<p>Given that here we talk about SQLite, what's the advantage to use clang 11 instead of a previous version?
Given that it's SQLite, this is likely a compiler bug. However, the code given is insufficient to demonstrate a compiler bug. Given:<p><pre><code> c = pMem->flags;
sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype));
</code></pre>
You could have say:<p><pre><code> sqlite3VdbeMemRelease(struct foo pMem) {
*(some_other_type *)&pMem->flags = bar;
}
</code></pre>
In which case the C aliasing rules would allow the compiler to assume that the assignment through "some_other_type" does not affect the assignment through whatever type pMem->flags is.<p>I have seen this bug happen before, when compilers got better at inlining, where it was something like<p><pre><code> void getAddressOfSomething(intptr_t *address);
...
char *p;
getAddressOfSomething((intptr_t *)&p)
*p=foo
</code></pre>
The compiler could reorder the \*p=foo line to be before the getAddressOfSomething call for the same reason.<p>TL;DR: Turn of strict aliasing via compiler flags (-fno-strict-aliasing on gcc) if you ever type-pun anywhere without using a union.
<p><pre><code> c = pMem->flags;
sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype));
</code></pre>
'pMem->flags' is a u16[1]. Shouldn't it be copied to 'c'. How can 'sqlite3VdbeMemRelease' alter the value of 'c'.<p>[1]<a href="https://github.com/smparkes/sqlite/blob/8caf9219240123fbe6cff67b1e0da778c62d7621/src/vdbeInt.h#L148" rel="nofollow">https://github.com/smparkes/sqlite/blob/8caf9219240123fbe6cf...</a>
Holy cow, this happened at -O1. This doesn't seem like the sort of optimization that should be possible at such a low level. I've run into plenty of trouble with higher level optimization flags in compilers before, but this is wild.
I see several references in this thread to "a bug in Clang that is already fixed", but I can't see anywhere where anyone references this bug.<p>Can anyone point to the bug report (and/or fix) in Clang?