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

Failure at Converting Boolean Expression to Integer in Struct Initialization #516

Open
Yeaseen opened this issue Aug 24, 2024 · 2 comments

Comments

@Yeaseen
Copy link

Yeaseen commented Aug 24, 2024

Source C code

#include <stdio.h>
typedef struct{
  int intM;
} mystruct;
mystruct test_bool(int inp){
  return (mystruct){.intM = inp != 0};
}
int main(){
  int b = 5;
  mystruct result = test_bool(b);
  printf("The value of 'a' in the returned struct is: %d\n", result.intM);
  b = 0;
  result = test_bool(b);
  printf("The value of 'a' in the returned struct when b = 0 is: %d\n", result.intM);
  return 0;
}

C code's output

Screenshot 2024-08-24 at 2 57 59 AM

Translated Go code by c4go

//
//	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"

// _struct_at_mnt_bigdata_YEASEEN_FuzzTranspilers_main_fuzzers_TFuzz_pre_post_works_c4go_transpile_runner_c_2 - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:2
type _struct_at_mnt_bigdata_YEASEEN_FuzzTranspilers_main_fuzzers_TFuzz_pre_post_works_c4go_transpile_runner_c_2 struct {
	intM int32
}

// mystruct - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:2
type mystruct = _struct_at_mnt_bigdata_YEASEEN_FuzzTranspilers_main_fuzzers_TFuzz_pre_post_works_c4go_transpile_runner_c_2

// test_bool - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:5
func test_bool(inp int32) mystruct {
	return mystruct{inp != 0}
}

// main - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:8
func main() {
	var b int32 = 5
	var result mystruct = test_bool(b)
	noarch.Printf([]byte("The value of 'a' in the returned struct is: %d\n\x00"), result.intM)
	b = 0
	result = test_bool(b)
	noarch.Printf([]byte("The value of 'a' in the returned struct when b = 0 is: %d\n\x00"), result.intM)
	return
}

Go compiler build error

Screenshot 2024-08-24 at 3 01 38 AM

Root Cause

c4go fails to convert boolean expression to Integer in Struct initialization

Modified Go code that works

I modified the initialization so that it could use noarch.BoolToInt function. And it gives the outputs as the source C code does.

Instead of return mystruct{inp != 0}, my modification is return mystruct{noarch.BoolToInt(inp != 0)}

//
//	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"

// _struct_at_mnt_bigdata_YEASEEN_FuzzTranspilers_main_fuzzers_TFuzz_pre_post_works_c4go_transpile_runner_c_2 - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:2
type _struct_at_mnt_bigdata_YEASEEN_FuzzTranspilers_main_fuzzers_TFuzz_pre_post_works_c4go_transpile_runner_c_2 struct {
	intM int32
}

// mystruct - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:2
type mystruct = _struct_at_mnt_bigdata_YEASEEN_FuzzTranspilers_main_fuzzers_TFuzz_pre_post_works_c4go_transpile_runner_c_2

// test_bool - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:5
func test_bool(inp int32) mystruct {
	return mystruct{noarch.BoolToInt(inp != 0)}
}

// main - transpiled function from  /mnt/bigdata/YEASEEN/FuzzTranspilers-main/fuzzers/TFuzz/pre_post_works/c4go_transpile/runner.c:8
func main() {
	var b int32 = 5
	var result mystruct = test_bool(b)
	noarch.Printf([]byte("The value of 'a' in the returned struct is: %d\n\x00"), result.intM)
	b = 0
	result = test_bool(b)
	noarch.Printf([]byte("The value of 'a' in the returned struct when b = 0 is: %d\n\x00"), result.intM)
	return
}

Output after modification

Screenshot 2024-08-24 at 3 06 51 AM

@Konstantin8105
Copy link
Owner

Thank you for example.
Not every C features are implemented in C4Go, because (I hope) it is not popular programming writing approach:

mystruct test_bool(int inp){
  return (mystruct){.intM = inp != 0};
}

@Yeaseen
Copy link
Author

Yeaseen commented Aug 24, 2024

The legacy C codebase includes this feature. However, if a transpiler like c4go is used to translate the C code to Go, it will fail. After all, this is the task of a transpiler to convert legacy code to memory-safe modern languages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants