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

C translation issue with boolean expression #20005

Open
eknkc opened this issue May 19, 2024 · 5 comments
Open

C translation issue with boolean expression #20005

eknkc opened this issue May 19, 2024 · 5 comments
Labels
bug Observed behavior contradicts documented or intended behavior translate-c C to Zig source translation feature (@cImport) upstream An issue with a third party project that Zig uses.
Milestone

Comments

@eknkc
Copy link

eknkc commented May 19, 2024

Zig Version

0.12.0

Steps to Reproduce and Observed Behavior

Given the C header file:

typedef struct
{
  int a;
} bar;

bar test_bool(int b)
{
  return (bar){.a = b != 0};
}

Zig translates this to:

pub export fn test_bool(arg_b: c_int) bar {
    var b = arg_b;
    _ = &b;
    return bar{
        .a = b != @as(c_int, 0),
    };
}

Which in turn results in

cimport.zig:64:12: error: expected type 'c_int', found 'bool'
        .a = b != @as(c_int, 0),
        ~~~^~~~~~~~~~~~~~~~~~~~

Expected Behavior

Translation shold probably use @intFromBool while assigning the int variable.

@eknkc eknkc added the bug Observed behavior contradicts documented or intended behavior label May 19, 2024
@ProkopRandacek
Copy link
Contributor

Relevant quote from the c99 standard

Each of the operators < (less than), > (greater than), <= (less than or equal to), and >=
(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.92)
The result has type int

6.5.8.6

The translation to zig needs to depend on how the result is used, since in other situations the bool result is correct and int would be wrong:

_Bool test(int a)
{
  return a != 0 && a != 4;
}

translates correctly to

pub export fn t(arg_a: c_int) bool {
    var a = arg_a;
    _ = &a;
    return (a != @as(c_int, 0)) and (a != @as(c_int, 4));
}

@f-cozzocrea
Copy link
Contributor

I can successfully reproduce the issue on master. It looks like it's specifically a bug for implicit casting for a record field. The translation is correct for variables.

@eknkc
Copy link
Author

eknkc commented May 21, 2024

I can successfully reproduce the issue on master. It looks like it's specifically a bug for implicit casting for a record field. The translation is correct for variables.

Can confirm. I was trying to come up with the absolute minimal repro sample but could not trigger it on variables. Just with a struct field.

@f-cozzocrea
Copy link
Contributor

I've been testing this a bit, and I'm pretty sure this is a bug in Clang. Clang is identifying the init expression class as BinaryOperator instead of ImplicitCastExpr. The expression is correctly identified as an implicit cast in every other situation (such as struct field access). I'll file an upstream bug.

@f-cozzocrea
Copy link
Contributor

Upstream issue is here: llvm/llvm-project#93393

@Vexu Would you mind adding labels to this issue? Probably translate-c and upstream.

@Vexu Vexu added upstream An issue with a third party project that Zig uses. translate-c C to Zig source translation feature (@cImport) labels May 26, 2024
@Vexu Vexu added this to the 0.14.0 milestone May 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior translate-c C to Zig source translation feature (@cImport) upstream An issue with a third party project that Zig uses.
Projects
None yet
Development

No branches or pull requests

4 participants