-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Resolve MSVC C4244 level 2 warnings #17076
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: master
Are you sure you want to change the base?
Conversation
@@ -473,7 +473,7 @@ PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max) | |||
/* This is an inlined version of the RAND_RANGE_BADSCALING macro that does not invoke UB when encountering | |||
* (max - min) > ZEND_LONG_MAX. | |||
*/ | |||
zend_ulong offset = (double) ( (double) max - min + 1.0) * (r / (PHP_MT_RAND_MAX + 1.0)); | |||
zend_ulong offset = (zend_ulong) (((double) max - min + 1.0) * (r / (PHP_MT_RAND_MAX + 1.0))); |
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.
The old version appears to "over-cast", so I simplified. @TimWolla, @zeriyoshi, thoughts?
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.
looks good!
ext/soap/php_encoding.c
Outdated
@@ -1028,7 +1028,7 @@ static zval *to_zval_double(zval *ret, encodeTypePtr type, xmlNodePtr data) | |||
whiteSpace_collapse(data->children->content); | |||
switch (is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0)) { | |||
case IS_LONG: | |||
ZVAL_DOUBLE(ret, lval); | |||
ZVAL_DOUBLE(ret, (double) lval); |
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.
Is this cast fine, @nielsdos?
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.
Yes
That sounds good.
This calculation is a rough heuristic which helps find the known text
encoding which best matches some given byte sequence. Which way we round
fractional values really does not matter much.
I support @cmb69's suggestion.
…On Sat, Dec 7, 2024, 7:49 PM Christoph M. Becker ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In ext/mbstring/mbstring.c
<#17076 (comment)>:
> @@ -3348,7 +3348,7 @@ try_next_encoding:;
}
for (size_t i = 0; i < length; i++) {
- array[i].demerits *= array[i].multiplier;
+ array[i].demerits *= (uint64_t) array[i].multiplier;
Well, to make the test
<https://github.com/php/php-src/actions/runs/12212106167/job/34070184398?pr=17076#step:13:136>
pass, probably
⬇️ Suggested change
- array[i].demerits *= (uint64_t) array[i].multiplier;
+ array[i].demerits = (uint64_t) (array[i].demerits * array[i].multiplier);
—
Reply to this email directly, view it on GitHub
<#17076 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAIESX3RO7I7IGEOOGDENJL2ELHB3AVCNFSM6AAAAABTGCW43OVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDIOBWGQ3TONZUGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@@ -156,7 +156,7 @@ void gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality) | |||
if (quality >= gdWebpLossless) { | |||
out_size = WebPEncodeLosslessRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, &out); | |||
} else { | |||
out_size = WebPEncodeRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, quality, &out); | |||
out_size = WebPEncodeRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, (float) quality, &out); |
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.
The simple cast is fine here to suppress the warning. ext/gd catches values < -1 early, and for libgd, such values cause WebPEncodeRGBA()
to fail.
@@ -2137,8 +2137,7 @@ gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, in | |||
/* round to two decimals and keep the 100x multiplication to use it in the common square angles | |||
case later. Keep the two decimal precisions so smaller rotation steps can be done, useful for | |||
slow animations. */ | |||
const int angle_rounded = fmod((int) floorf(angle * 100), 360 * 100); | |||
|
|||
const int angle_rounded = (int) fmod((int) floorf(angle * 100), 360 * 100); |
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.
This looks seriously overengineered. Why are there even float operations, instead of
const int angle_rounded = (int) fmod((int) floorf(angle * 100), 360 * 100); | |
const int angle_rounded = ((int) (angle * 100)) % (360 * 100); |
@@ -1134,7 +1134,7 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) | |||
TBB: but watch out for /0! */ | |||
double ac = cos (atan2 (dy, dx)); | |||
if (ac != 0) { | |||
wid = thick / ac; | |||
wid = (int) (thick / ac); |
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.
It seems to me that rounding would make sense here, but likely introduces a subtle BC break; as such casting to int is okay.
@@ -2827,7 +2827,7 @@ void gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c) | |||
* same footprint. | |||
*/ | |||
if (y >= y1 && y < y2) { | |||
im->polyInts[ints++] = (float) ((y - y1) * (x2 - x1)) / (float) (y2 - y1) + 0.5 + x1; | |||
im->polyInts[ints++] = (int) ((float) ((y - y1) * (x2 - x1)) / (float) (y2 - y1) + 0.5 + x1); |
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.
This one is okay.
@@ -81,7 +81,7 @@ static int quality2Quantizer(int quality) { | |||
|
|||
float scaleFactor = (float) AVIF_QUANTIZER_WORST_QUALITY / (float) MAX_QUALITY; | |||
|
|||
return round(scaleFactor * (MAX_QUALITY - clampedQuality)); | |||
return (int) round(scaleFactor * (MAX_QUALITY - clampedQuality)); |
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 the float calculation is unnecessary here. The following should be good enough:
return (int) round(scaleFactor * (MAX_QUALITY - clampedQuality)); | |
return clampedQuality * AVIF_QUANTIZER_WORST_QUALITY / MAX_QUALITY; |
But changing this now would introduce a subtle BC break, so just casting to int appears to be sensible for now.
@@ -103,7 +103,7 @@ static avifBool setEncoderTilesAndThreads(avifEncoder *encoder, avifRGBImage *rg | |||
|
|||
// The number of tiles in any dimension will always be a power of 2. We can only specify log(2)tiles. | |||
|
|||
tilesLog2 = floor(log2(tiles)); | |||
tilesLog2 = (int) floor(log2(tiles)); |
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.
Why do we even floor()
here instead of casting to int right away:
tilesLog2 = (int) floor(log2(tiles)); | |
tilesLog2 = (int) log2(tiles); |
And given we're interested in the log2 of an integer, there are even options not requiring an FP instruction (especially since tiles <= 8). But okay.
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.
FFI changes look good to me.
These got already approval by the respective code owners in GH-17076.
* master: Resolve some MSVC C4244 level 2 warnings
C4146[1] is about unary minus applied to unsigned operands; that behavior is well defined, and apparently used deliberately in the code base. C4244[2] is about possible loss of data when converting to another arithmetic type. This is addressed by another PR[3]. Anyhow, it seems like a no brainer to elevate to `/W2` even if we have to exempt two categories of warnings, since we can catch some others. [1] <https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4146?view=msvc-170> [2] <https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4244> [3] <php#17076>
C4146[1] is about unary minus applied to unsigned operands; that behavior is well defined, and apparently used deliberately in the code base. C4244[2] is about possible loss of data when converting to another arithmetic type. This is addressed by another PR[3]. Anyhow, it seems like a no brainer to elevate to `/W2` even if we have to exempt two categories of warnings, since we can catch some others. [1] <https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4146?view=msvc-170> [2] <https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4244> [3] <#17076>
Level 2 C4244 warnings hint at possible loss of data. So far this PR silences them by explicitly casting, what actually may be appropriate in some cases (possibly for FFI); in some other cases the warnings might be bogus, in which case we may want to add suitable assertions. There may be some cases, though, which hint at edge case bugs (in which case these should better be fixed).
It would be great if we can properly solve this. Maybe some of the code owners can have a look?
Note that the change to the CFLAGS for CI is not supposed to be committed; it's just to see whether I've missed some of these warnings when testing locally.
PS: any changes to the bundled libgd should be coordinated with upstream.