RESOLVED FIXED Bug 173622
reinterpret_cast does not evaluate to constexpr
https://bugs.webkit.org/show_bug.cgi?id=173622
Summary reinterpret_cast does not evaluate to constexpr
Daewoong Jang
Reported 2017-06-20 15:39:53 PDT
MSVC does not evaluate reinterpret_cast as a constant expression. This change is needed for supporting bmalloc on Windows(https://bugs.webkit.org/show_bug.cgi?id=143310).
Attachments
patch (2.11 KB, patch)
2017-06-20 15:41 PDT, Daewoong Jang
no flags
patch (2.26 KB, patch)
2017-06-21 15:10 PDT, Daewoong Jang
no flags
patch (2.40 KB, patch)
2017-06-22 05:44 PDT, Daewoong Jang
no flags
patch (2.58 KB, patch)
2017-07-05 15:58 PDT, Daewoong Jang
no flags
Daewoong Jang
Comment 1 2017-06-20 15:41:45 PDT
Build Bot
Comment 2 2017-06-20 15:56:44 PDT
Attachment 313445 [details] did not pass style-queue: ERROR: Source/bmalloc/bmalloc/Algorithm.h:55: bitwise_cast is incorrectly named. Don't use underscores in your identifier names. [readability/naming/underscores] [4] Total errors found: 1 in 2 files If any of these errors are false positives, please file a bug against check-webkit-style.
Daewoong Jang
Comment 3 2017-06-21 15:10:30 PDT
Build Bot
Comment 4 2017-06-21 15:13:22 PDT
Attachment 313554 [details] did not pass style-queue: ERROR: Source/bmalloc/bmalloc/Algorithm.h:56: bitwise_cast is incorrectly named. Don't use underscores in your identifier names. [readability/naming/underscores] [4] Total errors found: 1 in 2 files If any of these errors are false positives, please file a bug against check-webkit-style.
Yusuke Suzuki
Comment 5 2017-06-22 03:02:55 PDT
IIRC, std::memcpy is not constexpr in C++14. And reinterpret_cast is so too. Thus, we cannot use this thing as constexpr. I think we should prepare two versions of this function by overriding. One for T*, and one for T. And in T case, we do not perform reinterpret_cast<>. Instead, we will use static_cast<uintptr_t>(). In that case, we can make it as constexpr. Because this roundUpToMultipleOf is sometimes used for size_t, this enforces compilers to calculate constant values for that case (with constant values). And in the case of T*, we will just use reinterpret_cast<>. And we do not annotate constexpr for that.
Yusuke Suzuki
Comment 6 2017-06-22 03:03:49 PDT
(In reply to Yusuke Suzuki from comment #5) > IIRC, std::memcpy is not constexpr in C++14. And reinterpret_cast is so too. > Thus, we cannot use this thing as constexpr. We need to wait http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0202r0.html integration to the spec. > > I think we should prepare two versions of this function by overriding. > One for T*, and one for T. > And in T case, we do not perform reinterpret_cast<>. Instead, we will use > static_cast<uintptr_t>(). In that case, we can make it as constexpr. > Because this roundUpToMultipleOf is sometimes used for size_t, this enforces > compilers to calculate constant values for that case (with constant values). > > And in the case of T*, we will just use reinterpret_cast<>. And we do not > annotate constexpr for that.
Daewoong Jang
Comment 7 2017-06-22 05:44:20 PDT
Daewoong Jang
Comment 8 2017-06-22 07:03:32 PDT
(In reply to Yusuke Suzuki from comment #5) > IIRC, std::memcpy is not constexpr in C++14. And reinterpret_cast is so too. > Thus, we cannot use this thing as constexpr. > > I think we should prepare two versions of this function by overriding. > One for T*, and one for T. > And in T case, we do not perform reinterpret_cast<>. Instead, we will use > static_cast<uintptr_t>(). In that case, we can make it as constexpr. > Because this roundUpToMultipleOf is sometimes used for size_t, this enforces > compilers to calculate constant values for that case (with constant values). > > And in the case of T*, we will just use reinterpret_cast<>. And we do not > annotate constexpr for that. I updated the patch as you suggested. Thanks!
JF Bastien
Comment 9 2017-06-22 09:11:31 PDT
Comment on attachment 313610 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=313610&action=review > We need to wait http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0202r0.html integration to the spec. Unfortunately the committee is split on whether memcpy should be constexpr. I think http://wg21.link/p0476 may get you what you want... if the committee agrees to constexpr. > Source/bmalloc/bmalloc/Algorithm.h:51 > template<typename T> inline constexpr T mask(T value, uintptr_t mask) Which types do we expect to get for T here? Are they all valid? Is widening or narrowing OK? I would use enable_if to check invariants are met. > Source/bmalloc/bmalloc/Algorithm.h:71 > template<typename T> inline T roundUpToMultipleOf(size_t divisor, T x) Ditto on T.
Geoffrey Garen
Comment 10 2017-06-22 09:39:39 PDT
Comment on attachment 313610 [details] patch What function requires mask() or roundUpToMultipleOf to be constexpr? Can we make them not constexpr?
Daewoong Jang
Comment 11 2017-06-22 15:40:33 PDT
(In reply to Geoffrey Garen from comment #10) > Comment on attachment 313610 [details] > patch > > What function requires mask() or roundUpToMultipleOf to be constexpr? Can we > make them not constexpr? It seems that constexpr at roundUpToMultipleOf() could be removed, but mask() needs to be constexpr due to Sizes::maskSizeClass(). And reinterpret_cast still couldn't be used as MSVC is complaining that "cannot convert from std::size_t to uintptr_t". If you think the constexpr of roundUpToMultipleOf() should be removed, I'll update the patch. >> Source/bmalloc/bmalloc/Algorithm.h:51 >> template<typename T> inline constexpr T mask(T value, uintptr_t mask) >Which types do we expect to get for T here? Are they all valid? Is widening or >narrowing OK? I would use enable_if to check invariants are met. >> Source/bmalloc/bmalloc/Algorithm.h:71 >> template<typename T> inline T roundUpToMultipleOf(size_t divisor, T x) >Ditto on T. Regarding Bastien's review, could you let me know which types are valid and which are not? Thank you for review.
Yusuke Suzuki
Comment 12 2017-07-04 23:10:58 PDT
Comment on attachment 313610 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=313610&action=review >>> Source/bmalloc/bmalloc/Algorithm.h:51 >>> template<typename T> inline constexpr T mask(T value, uintptr_t mask) >> >> Which types do we expect to get for T here? Are they all valid? Is widening or narrowing OK? I would use enable_if to check invariants are met. > > The original code using reinterpret_cast requires that it does not cause any widening and narrowing. Let's add `static_assert(sizeof(T) == sizeof(uintptr_t), "");` in this function. >>> Source/bmalloc/bmalloc/Algorithm.h:71 >>> template<typename T> inline T roundUpToMultipleOf(size_t divisor, T x) >> >> Ditto on T. > > Ditto. Let's add `static_assert(sizeof(T) == sizeof(uintptr_t), "");`.
Daewoong Jang
Comment 13 2017-07-05 15:58:01 PDT
Daewoong Jang
Comment 14 2017-07-05 17:00:58 PDT
I think the patch is got a lot better. Thanks!
Yusuke Suzuki
Comment 15 2017-07-05 19:02:07 PDT
Comment on attachment 314660 [details] patch r=me
WebKit Commit Bot
Comment 16 2017-07-05 19:30:43 PDT
Comment on attachment 314660 [details] patch Clearing flags on attachment: 314660 Committed r219181: <http://trac.webkit.org/changeset/219181>
WebKit Commit Bot
Comment 17 2017-07-05 19:30:45 PDT
All reviewed patches have been landed. Closing bug.
Filip Pizlo
Comment 18 2017-10-16 12:51:11 PDT
Comment on attachment 314660 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=314660&action=review > Source/bmalloc/bmalloc/Algorithm.h:53 > + static_assert(sizeof(T) == sizeof(uintptr_t), "sizeof(T) must be equal to sizeof(uintptr_t)."); What is the purpose of this assertion? > Source/bmalloc/bmalloc/Algorithm.h:75 > + static_assert(sizeof(T) == sizeof(uintptr_t), "sizeof(T) must be equal to sizeof(uintptr_t)."); What is the purpose of this assertion?
Daewoong Jang
Comment 19 2017-10-16 16:43:20 PDT
(In reply to Filip Pizlo from comment #18) > Comment on attachment 314660 [details] > patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=314660&action=review > > > Source/bmalloc/bmalloc/Algorithm.h:53 > > + static_assert(sizeof(T) == sizeof(uintptr_t), "sizeof(T) must be equal to sizeof(uintptr_t)."); > > What is the purpose of this assertion? > > > Source/bmalloc/bmalloc/Algorithm.h:75 > > + static_assert(sizeof(T) == sizeof(uintptr_t), "sizeof(T) must be equal to sizeof(uintptr_t)."); > > What is the purpose of this assertion? Please refer to comment #9 and #12.
Filip Pizlo
Comment 20 2017-10-16 19:41:12 PDT
(In reply to Daewoong Jang from comment #19) > (In reply to Filip Pizlo from comment #18) > > Comment on attachment 314660 [details] > > patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=314660&action=review > > > > > Source/bmalloc/bmalloc/Algorithm.h:53 > > > + static_assert(sizeof(T) == sizeof(uintptr_t), "sizeof(T) must be equal to sizeof(uintptr_t)."); > > > > What is the purpose of this assertion? > > > > > Source/bmalloc/bmalloc/Algorithm.h:75 > > > + static_assert(sizeof(T) == sizeof(uintptr_t), "sizeof(T) must be equal to sizeof(uintptr_t)."); > > > > What is the purpose of this assertion? > > Please refer to comment #9 and #12. Thanks. In the future, it would be useful to put information about this in the ChangeLog.
Note You need to log in before you can comment on or make changes to this bug.