Skip to content

translate-c doesn't cast signed array index #4075

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

Closed
travisstaloch opened this issue Jan 4, 2020 · 3 comments · Fixed by #4113
Closed

translate-c doesn't cast signed array index #4075

travisstaloch opened this issue Jan 4, 2020 · 3 comments · Fixed by #4113
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals. frontend Tokenization, parsing, AstGen, Sema, and Liveness. translate-c C to Zig source translation feature (@cImport)
Milestone

Comments

@travisstaloch
Copy link
Contributor

currently (0.5.0+b3dbdf2ad) this

void foo() {
  int a[10], i = 0;
  a[i] = 0;
}

gets translated to:

pub export fn foo() void {
    var a: [10]c_int = undefined;
    var i: c_int = 0;
    a[i] = 0;
}

which results in the zig compilation error:

error: expected type 'usize', found 'c_int'
    a[i] = 0;
      ^

I'm not sure exactly what type this should be cast to, but here is one working option, casting to c_uint.

diff --git a/test/translate_c.zig b/test/translate_c.zig
index 34d6bb3a0..73e14ee5a 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -1300,6 +1300,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
     });
 
+    cases.add("cast signed array index to unsigned",
+        \\void foo() {
+        \\  int a[10], i = 0;
+        \\  a[i] = 0;
+        \\}
+    , &[_][]const u8{
+        \\pub export fn foo() void {
+        \\    var a: [10]c_int = undefined;
+        \\    var i: c_int = 0;
+        \\    a[@intCast(c_uint, i)] = 0;
+        \\}
+    });
+
     cases.add("for loops",
         \\int foo() {
         \\    for (int i = 2, b = 4; i + 2; i = 2) {
@LemonBoy
Copy link
Contributor

LemonBoy commented Jan 5, 2020

This should be easy to fix :)
Have a look at transArrayAccess in translate_c.zig, the idea here is to convert whatever the index type is to usize.

@daurnimator daurnimator added the translate-c C to Zig source translation feature (@cImport) label Jan 5, 2020
@travisstaloch
Copy link
Contributor Author

Thanks. I'm working on it now and might actually be close 👍 ...

@travisstaloch
Copy link
Contributor Author

I did a thing!

========= Expected this output: ================
pub export var array: [100]c_int = .{0} ** 100;
pub export fn foo(arg_index: c_int) c_int {
    var index = arg_index;
    return array[index];
}
========= But found: ===========================
pub export var array: [100]c_int = .{0} ** 100;
pub export fn foo(arg_index: c_int) c_int {
    var index = arg_index;
    return array[@intCast(c_uint, index)];
}

Now to update the failing tests :)

@andrewrk andrewrk added this to the 0.7.0 milestone Jan 5, 2020
@andrewrk andrewrk added contributor friendly This issue is limited in scope and/or knowledge of Zig internals. frontend Tokenization, parsing, AstGen, Sema, and Liveness. labels Jan 5, 2020
andrewrk pushed a commit that referenced this issue Jan 10, 2020
* cast only if the index is long long or signed
* cast long long to usize rather than c_uint

closes #4075
@andrewrk andrewrk modified the milestones: 0.7.0, 0.6.0 Feb 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals. frontend Tokenization, parsing, AstGen, Sema, and Liveness. translate-c C to Zig source translation feature (@cImport)
Projects
None yet
4 participants