Repository navigation
Reject C++ pointer casts to undersized integers #454
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
base: main
Are you sure you want to change the base?
Changes from all commits
04c1e80
9ddded2
389fa8f
345a8dd
8118f59
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 |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| [GH #454] | ||
| Reject C++ pointer casts to undersized integers | ||
|
|
||
| In GNU C++ mode, pointer-to-integer reinterpret_cast conversions now | ||
| require a destination type large enough to hold the pointer value. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14037,14 +14037,14 @@ well as C++ mode. | |
| ) || | ||
| (is_nullptr(source_type) && !source_type->incomplete)) && | ||
| is_integral(dest_type) && | ||
| (C_mode() || ms_extensions || gpp_mode || | ||
| (C_mode() || ms_extensions || | ||
| dest_of_ptr_cast_big_enough(source_type, dest_type))) { | ||
|
Contributor
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 tracked down why that gpp_mode is there. It's for this test case: Prior to GCC 4, this was accepted with a warning (https://godbolt.org/z/fG4YcKKr9). |
||
| /* Pointer or std::nullptr_t (but not the managed nullptr type, | ||
| identified by being incomplete) --> integral is okay | ||
| -- In C mode, always (size of destination is not an issue; see | ||
| 6.3.4 in the ISO C89 standard) | ||
| -- In C++ mode, if (a) the integer is big enough or (b) it's | ||
| not big enough but we're compiling in Microsoft or GNU mode. */ | ||
| not big enough but we're compiling in Microsoft mode. */ | ||
| okay = TRUE; | ||
| if (!dest_of_ptr_cast_big_enough(source_type, dest_type)) { | ||
| /* The destination is not large enough to hold all of the bits | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| //type:fp | ||
| //options_all:--c++20 | ||
| //options:--g++ --gnu_version=130300:--strict | ||
| using size_type = decltype(sizeof(0)); | ||
| static_assert(sizeof(size_type) >= sizeof(void*), "pointer width"); | ||
| size_type wide(void *p) { return reinterpret_cast<size_type>(p); } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| //type:fn | ||
|
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.
|
||
| //options_all:--c++20 | ||
| //options:--g++ --gnu_version=130300:--g++ --gnu_version=150200:--strict | ||
| // A pointer-to-integer reinterpret_cast requires sufficient destination width. | ||
| static_assert(sizeof(void*) > sizeof(unsigned char), "pointer width"); | ||
| unsigned char narrow_object(void *p) { | ||
| return reinterpret_cast<unsigned char>(p); // Must be an error in GNU mode. | ||
| } | ||
| unsigned char narrow_function(void (*p)()) { | ||
| return reinterpret_cast<unsigned char>(p); // Must also be an error. | ||
| } | ||
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'd add a small example here.