-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[clang] Function with empty loop has no return, has a duplicate address #60588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is undefined behavior, note 1 right under the forward progress paragraph says:
We can also read N1528 which justifies why this is considered undefined behavior. |
That's fair, I was unsure if it's undefined behaviour. Either way, two functions shouldn't have the same address, whether or not calling them is undefined behaviour. |
Once you have undefined behavior then you no longer have any expectations as to the results. The optimizations are going to assume well-formed programs and won't have the expected results if that is not the case. |
But the provided code snippet doesn't contain undefined behaviour. Undefined behaviour would only occur if the program actually encountered an infinite loop, which it doesn't, sice |
It looks like this is a duplicate of #48943 (comment) even though the undefined behavior is different. @dwblaikie do you still plan on adding a |
You're right, that's a very similar issue. The root issue is the same, but as I pointed out, this technically causes a violation of the specification, while that issue deals mostly with ergonomics. Should I move my comments to that issue? |
I hope this won't be considered spam, but i submitted a clarified version as #60596 that removes mentions of infinite loops and focuses on the strange comparison. |
Never did figure out a nice way to do it - probably should just settle for the OK ways to do it. I think there's already a couple of different "OK" tools that LLVM has that are turned on on some targets - there's TrapUnreachable, which is probably too pessimistic (traps on every unreachable? But maybe only on those that survive to codegen - so maybe not so bad?) & then there's some other feature I think we enable on Windows that puts a trap or nop on zero length functions, I think?
Yeah, no worries - don't mind if it's this bug or the new one you filed. |
That's actually not true. The problematic code doesn't need to be executed for UB to take effect. |
Consider the following code sample:
Function
a
contains an infinite loop without a constant controlling expression and without side-effects. The C11 and C17 standards allow implementations to assume that such a loop terminates. This code also happens to be valid C++ code. In C++11 and later, side-effect free infinite loops may also be assumed to terminate, as any thread can be assumed to eventually terminate or perform some kind of side-effect. Theb
function obviously has no strange or undefined behaviour.When the function
a
is compiled with eitherclang
orclang++
with at least-O1
for x86-64, the result will be an instructionless function:This means calling
a
will have the same result as callingb
. It's unclear whether this is allowed by either standard, as both just say the loop "may be assumed to terminate", not specifically that an infinite loop has undefined behaviour. One could say this only allows a compiler to remove a loop it cannot prove to terminate, not to assume a loop it can prove not to terminate will never be called. (Edit: It's well understood to be undefined behaviour.)Either way, this has another effect:
a
andb
now have the same address.We can append a small
main
function to the above snippet:The
identity
function just returns its argument in a wayclang
cannot inline. When we compile (with-O1
or higher) and run the full program, we get0 1
, which meansa
andb
are both identical and different. This seems to be a violation of the spec, since:a) different functions shouldn't be equal, and
b) two different values shouldn't suddenly become equal after passing them through an identity function.
This was tried with
clang
andclang++
version 14.0.0-1ubuntu1, and it can be observed to happen in version 15.0.0 through the Compiler Explorer.The text was updated successfully, but these errors were encountered: