-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[Clang] Add release note for pointer overflow optimization change #122462
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,29 @@ code bases. | |
containing strict-aliasing violations. The new default behavior can be | ||
disabled using ``-fno-pointer-tbaa``. | ||
|
||
- Clang will now more aggressively use undefined behavior on pointer addition | ||
overflow for optimization purposes. For example, a check like | ||
``ptr + unsigned_offset < ptr`` will now optimize to ``false``, because | ||
``ptr + unsigned_offset`` will cause undefined behavior if it overflows (or | ||
advances past the end of the object). | ||
|
||
Previously, ``ptr + unsigned_offset < ptr`` was optimized (by both Clang and | ||
GCC) to ``(ssize_t)unsigned_offset < 0``. This also results in an incorrect | ||
overflow check, but in a way that is less apparent when only testing with | ||
pointers in the low half of the address space. | ||
|
||
To avoid pointer addition overflow, it is necessary to perform the addition | ||
on integers, for example using | ||
``(uintptr_t)ptr + unsigned_offset < (uintptr_t)ptr``. Sometimes, it is also | ||
possible to rewrite checks by only comparing the offset. For example, | ||
``ptr + offset < end_ptr && ptr + offset >= ptr`` can be written as | ||
``offset < (uintptr_t)(end_ptr - ptr)``. | ||
|
||
Undefined behavior due to pointer addition overflow can be reliably detected | ||
using ``-fsanitize=pointer-overflow``. It is also possible to use | ||
``-fno-strict-overflow`` to opt-in to a language dialect where signed integer | ||
and pointer overflow are well-defined. | ||
Comment on lines
+81
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused by this flag vs. -fwrapv (which we went with in Chromium). Is there a difference? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With Clang, I'm also considering adding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. Thanks for explaining! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And here's the PR for |
||
|
||
C/C++ Language Potentially Breaking Changes | ||
------------------------------------------- | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add a motivating example to show this is not about pedantry but is useful for removing redundant checks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's hard to add an example that is small and simple enough for a release note. After all, the distinguishing feature between a desirable and an undesirable optimization in this context is just how many layers of abstraction there are. (This is Schrödinger's programmer: Doesn't want the compiler to optimize trivial cases because its "obviously wrong". Does want it to optimize complex cases.)
E.g. one of the motivating cases I have lying around is https://godbolt.org/z/3Y5bTxzqq, and that is both too large for a release note and too reduced to be really meaningful :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.