<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Dec 3, 2013 at 11:05 PM, Mikael Lyngvig <span dir="ltr"><<a href="mailto:mikael@lyngvig.org" target="_blank">mikael@lyngvig.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>[This is a rather long mail because I feel the topic is extremely important.  I've never before experienced a C or C++ compiler that silently outputs crash-burn-and-die instructions and I think I've used more than 10 of the sort.]</div>


<div><br></div>Hmm, I am mostly thinking of this in terms of an LLVM IR generator who does not have the benefit of an expertly written front-end that can add run-time checks.</div></blockquote><div><br></div><div>LLVM IR is not a place to put language-level diagnostics, and the users of a compiler frontend are only interested in language-level diagnostics.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">  I just tried this command:<div><br></div><div>


   clang -c -S -O2 -fsanitize=undefined test.ll</div>
<div>   a.out</div><div><br></div><div>
And it didn't change anything.  The ud2 instructions are still there and there are no checks.  And on Windows, this seems to yield nothing but a mouse cursor that blinks once and then the program exits as if nothing had happened.  This is possibly caused by the fact that I always operate with Windows Error Reporting disabled.  </div>
</div></blockquote><div><br></div><div>UBSan works at the C/C++ language level. It doesn't work at the IR level.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">




<div><br></div><div>I am in the process of reading Regehr's and Lattner's articles on the undefined behavior of C, C++, and Objective-C.  I just don't understand why a tool has to sort of work against you when it can easily work for you.<br>
</div></div></blockquote><div><br></div><div>To a compiler writer, UB means "I don't have to handle that case". It's not "I have to detect this case and emit a ud2". In many cases (most?), the problem of deciding whether the program actually has undefined behavior would require solving the halting problem. That is why UBSan is a runtime check.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>



</div><div><br></div><div>Is there any way at all that I can be informed of the appearance of "ud2" (and similar on other platforms) code in my program by the compiler or an associated tool?  Okay, I could do two compilations, one with -S and then grep for "ud2", and then a second without -C, but that seems both non-portable and slow.  I tried the above command with -Wall and got no diagnostic whatsoever even though my hand-crafted program appears to be mostly useless junk, which can be seen by the fact that two "ud2" instructions are output, in different places, so that the program literally has no chance of running to completion no matter what input it gets (the first "ud2" appears right after the frame pointer has been set up in main()).</div>
</div></blockquote><div><br></div><div>The program could have set up a SIGILL handler in a static initializer, then catch SIGILL upon executing the ud2, and then patch its code to replace that instruction with a nop and continue.</div>
<div><br></div><div>Yes, that's crazy, but notice that in order to reason that "the program literally has no chance of running to completion", you had to *assume* that the scenario I just described would not happen. That sort of assumption making is basically the same thing that the optimizer does w.r.t. UB.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">


<div><br></div><div>A silently emitted and later executed "ud2" would make any program go astray and chances are that the programmer incorrectly believes that everything is almost okay, if for no other reason than that the compiler has not told him otherwise.  And, yes, I do know about module tests and so on, but they are not perfect either.  The "ud2" instruction sort of reduces the user of LLVM IR to a user of an interpreted language - the program must be checked as if it was written in Python or PHP, because you never know when an "ud2" instruction might be emitted, not as if it was statically checked by an advanced compiler.  Not exactly what he or she had in mind when adopting LLVM in the first place, I suspect.</div>
</div></blockquote><div><br></div><div>It's not LLVM's job to ensure that your program has "correct semantics". That is the language frontend's job; it's not the job of "an advanced compiler": it's the most basic responsibility of a language frontend. All LLVM knows is the correct semantics for its own IR, not your language.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">



<div><br></div><div>I am perfectly aware that *I* am the person to ultimately blame for "ud2" instructions in my code, but as a non-omniscient entity, I'd like to be told when my tool discovers something that I have missed.  That's the main reason I prefer statically checked languages - the assurance that I have been told about the little errors and that I can focus my attention on the big things when testing.  As far as I can tell, the "ud2" invalidates all sensible assumptions regarding the static checks of the compiler.  You might get a few "ud2"s or not.  Sort of like throwing a dice and hoping for the best.  The above is also part of why I am personally not very fond of C and C++, this to such an extent that I stay away from coding in these languages if I can at all do so.  But is LLVM IR C/C++ specific?</div>
</div></blockquote><div><br></div><div>The optimizer is only obligated to preserve a set of defined behaviors. If you stay within those defined behaviors, your program will function correctly, if not, then all bets are off. It is a bug in your frontend (not your users' code) if your language claims to be "safe" (i.e. has no undefined behaviors) and yet the program runs into LLVM IR level UB.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">


<div><br></div><div>At the very least, I think that an early stage of the bitcode processor ought to issue a warning if any undefined behavior, whatsoever, is detected, so that people can learn to code differently and rest assured that all is not as bad as it could be.</div>
</div></blockquote><div><br></div><div>You aren't understanding that detecting undefined behavior is basically asking "will the program do X", and in general that is equivalent to the halting problem, meaning that there is nothing that can be done statically which will answer the question. Thus, you have to add runtime checks if you want to detect it. The fact that it reduces to the halting problem means that detecting it statically is not an issue of "detect or don't detect it", but rather one of "how many heuristics can you tack on for detecting certain limited cases of it".</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>  It may be my years with Ada, but I definitely think you want to tell people about any and all undefined things they do in their source code.  The sooner, the better!</div>
</div></blockquote><div><br></div><div>The only way to get rid of undefined behavior is to define the result of all constructs in a language. For the reasons I mentioned above, that will entail adding runtime checks in a Turing-complete language (i.e. any interesting one). LLVM needs to be able to efficiently compile languages like C/C++ without runtime checks, so it has to support the notion of undefined behavior, which is basically an escape hatch for simplifying certain static reasoning about the runtime behavior of a program, and without which those languages cannot be competitively optimized.</div>
<div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class="HOEnZb"><font color="#888888">

<div><br></div><div><br></div><div>-- Mikael</div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">2013/12/4 Sean Silva <span dir="ltr"><<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>></span><br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Doing this would make clang's diagnostic output dependent on the optimization level, which is absolutely verboten.<br>

</div><div><br></div><div>Also, a ud2 doesn't mean your program has a bug, and I doubt an asm-level diagnostic would be useful to anyone.</div>
<div><br></div><div>A ud2 just means "if control flow ever reaches this point, the program has undefined behavior"; in that sense, they don't even have to be emitted.</div><div><br></div>btw, compiling with -fsanitize=undefined should turn most/all of those ud2's into runtime checks that will give you a nice diagnostic if they are violated.<div>


<div><br></div><div>-- Sean Silva</div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Dec 3, 2013 at 8:58 PM, Mikael Lyngvig <span dir="ltr"><<a href="mailto:mikael@lyngvig.org" target="_blank">mikael@lyngvig.org</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Is it just me or would it be nifty if Clang emitted a warning message when it generates an "ud2" (UnDefined2) instruction.  I know this is x86-specific, but it would be sort of nice to know up front.  After all, the compiler knows perfectly well that it is outputting an "ud2" instruction and I'm pretty sure almost every programmer out there would like to share the unhappy news.<span><font color="#888888"><div>



<br></div><div><div><br></div><div>-- Mikael</div><div><br></div></div></font></span></div>
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div></div>