3 ms·
Instead we should maybe argue how undefined variable and undefined behaviour handling in LLVM is making things worse than they actually could be: Undef variabl
by legulere 11y ago
Instead we should maybe argue how undefined variable and undefined behaviour handling in LLVM is making things worse than they actually could be:
Undef variables taking on different values at different use points can lead to e.g. a == a being false. Code paths being possible with undefined values, that wouldn't be possible with any value sounds like a terrible idea to me, possibly exploitable, at least a source for heisenbugs
When llvm finds undefined behaviour in a code path (not possible undefined behaviour, but there actually is undefined behaviour), it does strange things instead of just trapping. When the execution reaches that code path, the program already is in an erroneous state, no need to optimize stuff there.
For instance:
int main(int argc, char argv) {
int a = 1;
int b = 0;
printf("%d", a/b);
}
compiles to:
define i32 @main(i32 %argc, i8 nocapture readnone %argv) #0 {
%1 = tail call i32 (i8, ...) @printf(i8* getelementptr inbounds ([3 x i8]* @.str, i64 0, i64 0), i32 undef) #2
ret i32 0
}
Why let the program behave buggy when llvm can see that undefined behaviour will occur? Why not just trap instead? That would have zero cost.
- lomnakkus 11y ago> Why let the program behave buggy when llvm can see that undefined behaviour will occur? It's not quite that easy. Because compilers these days have a large number of phases/optimization passes it can be prohibitively difficult to trace back from the location of a potential UB to what might/does trigger it (in the source). So what compilers do is ASSUME that no UB can occur, hence there's no need to generate a check for "b=0". You can run clang with -fsanitize=undefined, though, and get runtime-checks for many UBs. It'll cost you runtime performance, though.