Disabled account.
To clarify, my points 1 and 2 were mostly rants about the standard, not questions or anything really actionable.
The behavior of
ret 0
is indeed bogus, but it's a bug that only triggers when accessing memory at a constant location (e.g., like one would do when writing an OS), so I'll postpone these memory references are truly used.Returning in
rax
therdi
passed seems like a good idea. I'll see if that's easy to support.
I checked the standard and you're right, undefined behavior is triggered by the assignment. But even then, I think cc+qbe are not doing anything wrong because as far as I understand the clobber happens at the assignment in
main
.I now remember that
ret
with no argument is actually explicitly allowed in qbe to permit the compilation of fall-through returns. Usingret 0
is actually not an idea as good as I thought because that would make the test program crash insideg
; this behavior would violate the standard in case the return value is not used by the caller.That "dynamic" aspect of C about fall-through returns is really badly broken: 1.
return;
in a function which has a non-void return type is inconsistent with falling through; and 2. any function with "return type" T is actually a function which, upon return, either gives you a T back or void...
Isn't this program triggering undefined behavior anyway? One possible solution could be to return the constant 0 on fall-through returns for non-void functions. What do you think?
For the __builtin_xxx issues, one option is to write regular functions in assembly that use an efficient implementation, and link those to all the executables created.
When speed is critical QBE instructions could be added but, as much as possible, QBE's instruction selection should be improved (for e.g., rol ror).
If I understand correctly, it is a case identical to the one we have seen earlier with divisions by zero. Consequently, this is also an issue which I should fix in QBE.
I would heavily prioritize memory-safety checks. Those are the ones responsible for serious vulnerabilities. An undefined overflow is only a problem when your compiler makes dumb assumptions about it not possibly happening; it could be the first step of an exploit but is likely followed by an unsafe memory access.