Don't emit != 0 when a C comparison or logical operator is returned as bool - #823
Merged
tannergooding merged 3 commits intoJul 18, 2026
Merged
Conversation
tannergooding
force-pushed
the
fix-bool-return-comparison
branch
from
July 18, 2026 19:08
1622a8a to
4159184
Compare
…s bool In C, relational and logical operators yield `int`, so returning one from a `_Bool` function inserts an `IntegralToBoolean` cast. The equivalent C# operators already yield `bool`, making the `!= 0` coercion both redundant and non-compiling. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
tannergooding
force-pushed
the
fix-bool-return-comparison
branch
2 times, most recently
from
July 18, 2026 19:12
2633517 to
cc90807
Compare
…teger The inverse of the != 0 case: in C, relational and logical operators yield int, so their result can be stored in or returned as an integer without a cast. The equivalent C# operators yield bool, which has no implicit conversion to an integer, so a ? 1 : 0 coercion must be inserted where such a value is returned from or assigned to an integer. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
tannergooding
force-pushed
the
fix-bool-return-comparison
branch
from
July 18, 2026 19:15
cc90807 to
8ecc7a6
Compare
A C &&/|| yields int and promotes a _Bool operand to int, which the generator rendered as a ? 1 : 0 coercion. Since C#'s logical operators take bool operands directly, this produced invalid, mis-precedenced output like (a) ? 1 : 0 && (b) ? 1 : 0; emit the underlying bool instead. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
tannergooding
force-pushed
the
fix-bool-return-comparison
branch
from
July 18, 2026 19:21
8ecc7a6 to
21401fa
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #820.
In C, relational (
< > <= >= == !=) and logical (&& ||) operators yieldint, so returning one from a_Boolfunction inserts anImplicitCastExpr<IntegralToBoolean>. The generator emitted(<expr>) != 0for that cast, but the equivalent C# operators already yieldbool, so the!= 0is both redundant and non-compiling (bool != int). C++ never hits this because<etc. already yieldbool(no cast inserted).The
CX_CK_IntegralToBooleanhandling now omits the!= 0whenever the operand is already a C#-boolean-valued expression -- a comparison, a logical&&/||, or a!-- and otherwise keeps the existing!= 0coercion (e.g.return someInt;). Bitwise&/|are intentionally left untouched, since(x & mask) != 0is genuinely int-to-bool.Regression test added as
CTest.BooleanReturnFromComparisonTestcovering the comparison, logical, and plain-integer cases.Not addressed here: the operands of a logical
&&/||with non-booloperands (e.g.int a, b; return a && b;) still emit invalida && b-- that is a separate, pre-existing issue and out of scope for this fix.