Skip to content

Zend: Add unsigned suffix for bitmask flags #14449

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Girgias
Copy link
Member

@Girgias Girgias commented Jun 3, 2024

Bit shifts are only well-defined for unsigned integers:

The integer promotions are performed on each of the operands. The type of the result is that of the
promoted left operand. If the value of the right operand is negative or is greater than or equal to the
width of the promoted left operand, the behavior is undefined

Section 6.5.7 Bitwise shift operators of the latest C23 draft (and this is also valid in C99): https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf

Moreover, a lot of the results of these flags are stored in uint32_t fields.

This is part of being able to enable the -Wconversion warning.

Bitshifts are only well defined for unsigned integers
@Girgias Girgias force-pushed the fix-sign-conversions2 branch from 4e9166f to 7adb5c1 Compare June 3, 2024 06:34
@Girgias Girgias marked this pull request as ready for review June 3, 2024 07:06
@Girgias Girgias requested review from dstogov and iluuu1994 as code owners June 3, 2024 07:06
@dstogov
Copy link
Member

dstogov commented Jun 3, 2024

What does this fix?
The following C code doesn't cause conversion warnings (nor GCC neither CLANG with -Wsign-conversion)

void test() {
	unsigned x = 1 << 5;
}

@Girgias
Copy link
Member Author

Girgias commented Jun 4, 2024

The issue is if you enable the -Wconversion flag, you will get warnings such as:

/home/girgias/Dev/php-src/Zend/zend_hash.h:1615:19: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-convers>
 1615 |                 HT_FLAGS(ht) &= ~HASH_FLAG_STATIC_KEYS;
      |                              ~~ ^~~~~~~~~~~~~~~~~~~~~~

because the signed bitmask flag is being assigned to an unsigned struct field. And because virtually all fields in Zend that are bitmask flags are of type uint32_t each individual flag also be unsigned IMHO.

I'll fix the description of the PR as it is indeed the wrong compiler flag I mentioned.

@dstogov
Copy link
Member

dstogov commented Jun 5, 2024

The issue is if you enable the -Wconversion flag, you will get warnings such as:

/home/girgias/Dev/php-src/Zend/zend_hash.h:1615:19: warning: implicit conversion changes signedness: 'int' to 'uint32_t' (aka 'unsigned int') [-Wsign-convers>
 1615 |                 HT_FLAGS(ht) &= ~HASH_FLAG_STATIC_KEYS;
      |                              ~~ ^~~~~~~~~~~~~~~~~~~~~~

because the signed bitmask flag is being assigned to an unsigned struct field. And because virtually all fields in Zend that are bitmask flags are of type uint32_t each individual flag also be unsigned IMHO.

You are right. May be changing the left operand of the shift is enough?

void test(unsigned *p) {
	*p &= ~(1U << 5);
}

It looks like Rust changes the mind of C compilers developers and we have to bloat the source code with more and more qualifications... :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants