Skip to content
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

Parser: Report a Warning if implicit integer conversion truncates value or sign conversion. #717

Merged
merged 6 commits into from
Jul 10, 2024

Conversation

Organ1sm
Copy link
Contributor

@Organ1sm Organ1sm commented Jul 3, 2024

When I wanted to learn how to write a C23 C language compiler, this project was extremely helpful to me, no less than having a rich big meal right after finishing a workout. I've been going through this project almost commit by commit, although I haven't finished looking through it all yet. This project not only taught me how to write a C compiler for the C23 standard, but also allowed me to learn a new language, Ziglang, which made me feel very happy. So I want to see if I can do something for this project. I looked at the issue section, and because I don't have experience contributing to open-source projects, I can only start with issues labeled as good first issue.

so I attempted to solve this issue. #701

Value.intCast` currently return a value that indicates whether truncation happens and then issue a diagnostic.

try res.val.intCast(int_ty, p.comp);
const old_val = res.val;
const value_change_kind = try res.val.intCast(int_ty, p.comp);
if (value_change_kind == .value_changed and !(res.ty.makeIntegerUnsigned().specifier == int_ty.makeIntegerUnsigned().specifier))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific scenario the !(res.ty.makeIntegerUnsigned().specifier == int_ty.makeIntegerUnsigned().specifier) part guards against (probably better expressed using != instead)?

@ehaas
Copy link
Collaborator

ehaas commented Jul 3, 2024

The windows binary expressions.c test is failing because long is only 4 bytes on windows, so 0xFFFFFFFFFF gets promoted to long long. Changing line 48 to int baz = 0xFFFFFFFFFFLL + 1u; and updating the error text to long long will make it have the same behavior on all platforms.

@ehaas
Copy link
Collaborator

ehaas commented Jul 3, 2024

For the 2 new warnings in enum overflow.c it looks like C and H really do have type int on windows (confirmed on godbolt https://godbolt.org/z/x4PdsKEcs) - so for those two it looks like we should be comparing against -1 in the windows static asserts

@ehaas
Copy link
Collaborator

ehaas commented Jul 3, 2024

BTW thank you for the kind words and contribution!

@Organ1sm Organ1sm force-pushed the implicit-integer-conversion branch from b375e1a to 2e55dfd Compare July 4, 2024 06:25
@Organ1sm
Copy link
Contributor Author

Organ1sm commented Jul 4, 2024

According to your advice, I revised the code and pushed it. Thank you for your code review. :)

@Organ1sm
Copy link
Contributor Author

Organ1sm commented Jul 6, 2024

Hello, it seems this PR hasn't shown any signs of being merged. I'd like to know if there are any parts of the code that aren't well written so I can continue to improve them.

@ehaas
Copy link
Collaborator

ehaas commented Jul 6, 2024

I had a question about the res.ty.makeIntegerUnsigned().specifier != int_ty.makeIntegerUnsigned().specifier condition - it's not clear to me why that's needed. Can you give an example that does the wrong thing if that condition is not included?

@Organ1sm
Copy link
Contributor Author

Organ1sm commented Jul 6, 2024

For example: unsigned int u = -1;

The left-hand side and right-hand side of this statement only differ in terms of being unsigned and signed. At the semantic level, there is an implicit conversion. So initially, my approach to solving this was not to add this extra condition, and I also wanted to add a warning for this implicit conversion. However, I later found that both Clang and GCC do not issue warnings for this statement by default.

I think we should add a new diagnostic option called sign-conversion to warn about this type of implicit conversion.

@ehaas
Copy link
Collaborator

ehaas commented Jul 6, 2024

I agree that adding a sign-conversion diagnostic option kind is the way to go. The bigint bitCountTwosComp function may be able to help with figuring out if the value changed due to truncation vs sign change.

@Organ1sm Organ1sm force-pushed the implicit-integer-conversion branch from 504e752 to a3560e3 Compare July 7, 2024 05:30
@Organ1sm Organ1sm changed the title Parser: Report a Warning if implicit integer conversion truncates value. Parser: Report a Warning if implicit integer conversion truncates value or sign conversion. Jul 7, 2024
@Organ1sm Organ1sm requested a review from ehaas July 7, 2024 05:36
const value_bits = big.bitCountTwosComp();

// if big is negative or zero, then is signed.
const src_signed = (!big.positive or big.limbs[0] == 0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const src_signed = (!big.positive or big.limbs[0] == 0);
const src_signed = (!big.positive or big.eqlZero());

@ehaas
Copy link
Collaborator

ehaas commented Jul 7, 2024

Looks good to me!

@Organ1sm Organ1sm force-pushed the implicit-integer-conversion branch from 795bae1 to 26d8718 Compare July 8, 2024 05:02
Copy link
Owner

@Vexu Vexu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the enhancement and I'm glad the project has been helpful to you!

Comment on lines 254 to 255
// if big is negative or zero, then is signed.
const src_signed = (!big.positive or big.eqlZero());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is zero considered signed? Clang and gcc don't do so.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes,I tested the behavior of clang and gcc. It was my oversight, so I wrote a new commit to correct this.

…when execute intcast.

This change matches the behavior of gcc/clang
@Organ1sm Organ1sm requested a review from Vexu July 9, 2024 02:28
@Vexu Vexu merged commit b61abd3 into Vexu:master Jul 10, 2024
3 checks passed
@Organ1sm Organ1sm deleted the implicit-integer-conversion branch July 12, 2024 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants