[LLVMdev] interesting possible compiler bug

Reed Kotler rkotler at mips.com
Wed Oct 3 09:36:17 PDT 2012


My friend sent me the first days worth of discussion on this topic from 
the C committee discussion list and it was very long with many 
contradictory opinions and citing evidence from a variety of sources.

I don't feel comfortable posting the discussion because it was not from 
a public forum.

But  I can say there was far from any consensus regarding this issue I 
originally raised.


On 10/02/2012 03:01 PM, Richard Smith wrote:
> See also this proposal for the next C++ committee meeting, which aims 
> to clarify this case and others like it:
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3433.html
>
> On Tue, Oct 2, 2012 at 9:49 AM, Reed Kotler <rkotler at mips.com 
> <mailto:rkotler at mips.com>> wrote:
>
>     I've sent this issue to some friends on the C++ committee.
>
>     The first response I received indicates that the person thinks the
>     optimizer is within it's rights to optimize away the call to malloc.
>
>     Here are some points, extracted from the response:
>
>     "There is no observable behavior (a technical term in the
>     standard) that violates requirements of the standard. In
>     particular, malloc in the abstract machine defined by the standard
>     need not ever fail."
>
>     "On linux in particular, malloc (almost) never fails, because
>     Linux does not actually make malloc'd memory available until it is
>     used. Here the allocated memory is never used, so if the compiler
>     recognizes malloc as a standard library function with well-defined
>     semantics, it can eliminate the actual call and pretend it succeeded.
>
>     Since variable curr is not visible outside main and is not
>     declared volatile, it can be optimized away."
>
>
>
>
>     On 10/02/2012 02:12 AM, Nick Lewycky wrote:
>
>         David Chisnall wrote:
>
>             On 2 Oct 2012, at 03:40, Nick Lewycky wrote:
>
>                 As far as I know, this optimization is legal. Fix the
>                 test with a
>                 volatile pointer:
>
>
>             Why would that be required?
>
>
>         It isn't. My suggestion for fixing the test is to make use of the
>         returned pointer in a fashion that the compiler is forbidden
>         to elide
>         it: make it an observable side-effect using volatile. Another
>         way would
>         be to take the pointer and print it to file or stdout. Perhaps
>         you can
>         think of others.
>
>            malloc() is defined by the standard to return a pointer that is
>         distinct from any other valid pointer, or NULL.  Any
>         optimisation that
>         makes any assumptions about its next value is invalid.
>
>         Nowhere do we make assumptions about malloc's next value.
>
>         This is a straight-forward application of the as-if rule. The
>         malloc
>         call behaves as-if it allocated memory. Because we prove that
>         the code
>         doesn't use that memory, we can get away with allocating no
>         memory at
>         all and not change the behaviour of the program.
>
>         But we did change the behaviour of the program, didn't we?
>         Well, we
>         haven't changed the behaviour of the program in any way that is
>         observable through a well-defined mechanism. Crashes, running
>         out of
>         memory, or asking the kernel for your processes' memory usage
>         isn't
>         behaviour you get to rely on. The first two really aren't
>         defined in the
>         language, and the last one goes through I/O which is permitted
>         to do its
>         own thing. (For instance, we don't forbid constant-folding
>         "1+1" because
>         a program may fopen and disassemble itself to look for the
>         "add 1, 1"
>         instruction.)
>
>                 int main() {
>                    volatile char *curr;
>
>                    do {
>                      curr = malloc(1);
>                      int i = *curr;
>
>
>             This, in particular, looks very wrong.  If curr is void,
>             then you are
>             dereferencing an invalid pointer, and so you are doing
>             something
>             undefined.
>
>
>         Do you mean, if curr is NULL? It's a char*, not void*.
>
>         In fact, this version of the code is completely free to elide the
>         conditional loop, because by dereferencing the pointer you are
>         asserting
>         that it is not NULL (or, at least, that if it is then after
>         this point
>         the program is in an undefined state and so any behaviour is
>         legal) and
>         so it is completely free to generate the code that it in fact does
>         generate without this test.  So here we have another bug,
>         because the
>         testq in your output is redundant after the movb.
>
>         Yes, good point, I totally missed the NULL dereference. I haven't
>         checked what happens if you write:
>
>            curr = malloc(1);
>            if (curr)
>              int i = *curr;
>
>         but I expect that would work.
>
>         Nick
>
>
>     _______________________________________________
>     LLVM Developers mailing list
>     LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
>     http://llvm.cs.uiuc.edu
>     http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121003/1c39098b/attachment.html>


More information about the llvm-dev mailing list