Konstantin8105 / c4go

Transpiling C code to Go code
MIT License
365 stars 38 forks source link

Failure at Union Initialization in the converted Go code #515

Open Yeaseen opened 3 months ago

Yeaseen commented 3 months ago

Source C code

#include <stdio.h>
union Data {
   int p_p;
};
union Data data1 = { 100 };
int main() {
    printf("Value at the start of main: %d\n", data1.p_p);
    data1.p_p = 200;
    printf("Value after modification: %d\n", data1.p_p);
    return 0;
}

C code's output

Value at the start of main: 100 Value after modification: 200

Output Go code

//
//  Package - transpiled by c4go
//
//  If you have found any issues, please raise an issue at:
//  https://github.com/Konstantin8105/c4go/
//

package main

import "github.com/Konstantin8105/c4go/noarch"
import "unsafe"

type Data struct{ memory unsafe.Pointer }

func (unionVar *Data) copy() Data {
    var buffer [8]byte
    for i := range // Data - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:2
    buffer {
        buffer[i] = (*((*[8]byte)(unionVar.memory)))[i]
    }
    var newUnion Data
    newUnion.memory = unsafe.Pointer(&buffer)
    return newUnion
}
func (unionVar *Data) p_p() *int32 {
    if unionVar.memory == nil {
        var buffer [8]byte
        unionVar.memory = unsafe.Pointer(&buffer)
    }
    return (*int32)(unionVar.memory)
}

// data1 - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:5
var data1 Data = Data{100}

// main - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:6
func main() {
    noarch.Printf([]byte("Value at the start of main: %d\n\x00"), (*data1.p_p()))
    (*data1.p_p()) = 200
    noarch.Printf([]byte("Value after modification: %d\n\x00"), (*data1.p_p()))
    return
}

Go compiler build error after the translated code is built

# command-line-arguments
./runner.go:34:23: cannot use 100 (untyped int constant) as unsafe.Pointer value in struct literal

Root Cause

The initialization of variable data1 is of type struct Data. First of all, this global initialization should be inside

Modified Go code that works

I fixed the go code manually, and the fix works.

//
//  Package - transpiled by c4go
//
//  If you have found any issues, please raise an issue at:
//  https://github.com/Konstantin8105/c4go/
//

package main

import "github.com/Konstantin8105/c4go/noarch"
import "unsafe"

type Data struct{ memory unsafe.Pointer }

func (unionVar *Data) copy() Data {
    var buffer [8]byte
    for i := range // Data - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:2
    buffer {
        buffer[i] = (*((*[8]byte)(unionVar.memory)))[i]
    }
    var newUnion Data
    newUnion.memory = unsafe.Pointer(&buffer)
    return newUnion
}
func (unionVar *Data) p_p() *int32 {
    if unionVar.memory == nil {
        var buffer [8]byte
        unionVar.memory = unsafe.Pointer(&buffer)
    }
    return (*int32)(unionVar.memory)
}

// data1 - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:5

// Declare a global variable
var data1 Data

// Initialize the global variable in the init function
func init() {
    *data1.p_p() = 100
}

// main - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:6
func main() {
    noarch.Printf([]byte("Value at the start of main: %d\n\x00"), (*data1.p_p()))
    (*data1.p_p()) = 200
    noarch.Printf([]byte("Value after modification: %d\n\x00"), (*data1.p_p()))
    return
}

So, instead of var data1 Data = Data{100}, my modification

// Declare a global variable
var data1 Data

// Initialize the global variable in the init function
func init() {
    *data1.p_p() = 100
}

Output after modification: Value at the start of main: 100 Value after modification: 200

Konstantin8105 commented 3 months ago

Thank you for your clean test case. If you want to implement, then feel free for create PR. If you do not want prepare PR, then I will implement by myself.