-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[clang] Taking address of unreachable function can be used to obtain identical integers that compare unequal #60596
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
Confirmed: https://godbolt.org/z/75z4zMTnd |
@llvm/issue-subscribers-clang-frontend
Using `__builtin_unreachable`, it's possible to create a function `a` that compiles to zero Assembly instructions, like this:
void a() {
__builtin_unreachable();
}
void b() {} With a:
b:
ret The function #include <stdlib.h>
#include <stdio.h>
void a() {
__builtin_unreachable();
}
void b() {}
int main() {
size_t ap = (size_t) a;
size_t bp = (size_t) b;
printf("%zu %zu %d\n", ap, bp, ap == bp);
} Executing this will reveal that My guess is that some optimization pass assumes that different functions have different addresses, which is required by the C standard. This bug is unlikely to happen in real programs, since:
Tested with |
This is known problem with unreachable: #48943 Right now it does not seem like anyone has the bandwidth to tackle this issue. I feel like this is not exactly a duplicate but if the OP feels like it is a close enough then feel free to close. |
@llvm/issue-subscribers-clang-codegen
Using `__builtin_unreachable`, it's possible to create a function `a` that compiles to zero Assembly instructions, like this:
void a() {
__builtin_unreachable();
}
void b() {} With a:
b:
ret The function #include <stdlib.h>
#include <stdio.h>
void a() {
__builtin_unreachable();
}
void b() {}
int main() {
size_t ap = (size_t) a;
size_t bp = (size_t) b;
printf("%zu %zu %d\n", ap, bp, ap == bp);
} Executing this will reveal that My guess is that some optimization pass assumes that different functions have different addresses, which is required by the C standard. This bug is unlikely to happen in real programs, since:
Tested with |
Using
__builtin_unreachable
, it's possible to create a functiona
that compiles to zero Assembly instructions, like this:With
-O1
or higher this compiles to:The function
a
is pretty useless, since calling it will unconditionally result in undefined behaviour. It is, however, possible to take its address, like this:Executing this will reveal that
ap
andbp
have identical values, sincea
andb
have the same address. However, it will also show thatap == bp
is false, which contradicts that.My guess is that some optimization pass assumes that different functions have different addresses, which is required by the C standard.
This bug is unlikely to happen in real programs, since:
a) few programs have functions that have unconditionally undefined behaviour,
b) even fewer programs will take the address of such a function, and
c) fewer still programs compare function pointers.
__builtin_unreachable
can also be replaced by other statements with undefined behaviour, such asfor (int i=0; i>=0; i++);
.Tested with
clang
andclang++
15.0.7 with an optimization level of 1.The text was updated successfully, but these errors were encountered: