There's also the perpetually annoying 'a function calling itself in an infinite loop is UB'
Conversation
Check out this example using a loop:
gist.github.com/thestinger/7e6
LLVM considers noreturn to be an effect, and yet it doesn't consider a function that *may* not return to have an effect. This is a bug, but an intentional one because they chose to keep an unsafe optimization around.
1
4
They properly preserve functions that are pure but not nounwind, such as a chain of them like foo(); foo(); foo(); being optimized to foo(); but never being completely removed. They are missing an attribute for 'returns' or 'halts' and yet optimize without checking anyways.
1
1
So, even though it's known that this is broken for many years, they have kept the optimization enabled. No one has been motivated to deal with implementing a 'halts' attribute and adding support for detecting / propagating it in the function attribute pass and making it required.
2
1
That's just broken, but not too surprising, since it's not uncommon for compilers to have miscompile bugs in tough and unusual corner cases. But the context of this conversation is: do you need a new compiler to fix UB?
1
The fact that llvm has bugs doesn't really change the answer. Even a compiler that was designed to avoid UB could have miscompile bugs. Also, the context of the conversation allows for making changes to llvm - so this seems like the kind of thing that could be fixed.
1
1
I guess I don't understand the context. It seems to be about C, and I don't see how you can resolve that problem for C without coming up with a model to enforce a form of memory safety. What is the scope of UB that should be avoided? You mean, for a language like Rust or Swift?
2
The question of whether memory unsafety implies UB is sort of at the heart of the disconnect between the C spec and C practitioners. As a practitioner (and compiler guy) I view memory unsafety as a separate thing - after all a “bad” store still stores to a well defined place.
2
1
2
There is nothing well defined about what an out-of-bounds access or use-after-free will access. The compiler, linker and even runtime environment are assuming that is never going to happen and there's nothing defined about what the consequences are going to be from the C code.
3
1
In the machine code output by the compiler, it's perfectly well defined what an out-of-bounds access or use-after-free will do, and to what, although of course it depends on runtime state. It's just undefined in the input C code.
1
2
That's not a relevant response related to the thread. He states that he wants an optimizing compiler with a comparable amount of optimization, where the programmer is writing code for an abstract machine and the compiler is making transforms that preserve abstract semantics.
That wasn't my interpretation of his Tweet at the time, but on looking at further context, I think you are correct
1
I would definitely say that the standard should not say things are 'undefined' but rather come up with sensible constraints on how it should be implemented. Guaranteeing that signed overflow wraps would be a regression for safe implementations by forbidding them from trapping.
2
1
Show replies


