Skip to content

Incorrect long type representation causes wrong unsigned-to-long conversion #928

Description

@lynae99

c2go incorrectly translates C long as Go int32 on a platform where long is 64 bits.
In this program, unsigned int contains 4294967295U. On common LP64 platforms such as x86_64 Linux, C long is 64 bits, so converting this value to long should preserve the positive value. However, the generated Go code converts the uint32 value to int32, producing -1 and causing the branch result to differ from the original C program.
To Reproduce

#include <stdio.h>

int main(void) {
    unsigned int ui = 4294967295U;
    long x = (long)ui;

    if (x > 0) {
        printf("positive\n");
    } else {
        printf("non-positive\n");
    }

    return 0;
}

Generated Go Code

func main() {
        var ui uint32 = uint32(4294967295)
        var x int32 = int32(ui)
        if x > int32(0) {
                noarch.Printf((&[]byte("positive\n\x00")[0]))
        } else {
                noarch.Printf((&[]byte("non-positive\n\x00")[0]))
        }
        return
}

Observed Behavior
The original C program prints:

positive

The generated Go program prints:

non-positive

Additional Example:
The same incorrect long representation can also produce invalid Go code for 64-bit long constants:

#include <stdio.h>

int main(void) {
    long long_val = 0x123456789ABCDEF0L;
    printf("%ld\n", long_val);
    return 0;
}

This may be translated as:

var long_val int32 = 1311768467463790320

which fails to compile:

cannot use 1311768467463790320 (untyped int constant) as int32 value in variable declaration (overflows)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions