1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//! DECY-112: Array Initialization Bug Tests
//!
//! **Bug**: Array size is being incorrectly captured as initializer
//!
//! **Symptom**: `int nums[5];` transpiles to `let mut nums: [i32; 5] = 5;`
//! **Expected**: `int nums[5];` transpiles to `let mut nums: [i32; 5] = [0; 5];`
//!
//! **Root Cause**: The parser's visit_expression callback captures the array
//! size literal (5) as the initializer expression when visiting children
//! of variable declarations.
//!
//! **Fix**: Skip integer literals that are array size expressions when
//! the variable type is an array.
use decy_core::transpile;
/// Test that uninitialized arrays do NOT use size as initializer.
///
/// C: `int nums[5];`
/// WRONG: `let mut nums: [i32; 5] = 5;`
/// CORRECT: `let mut nums: [i32; 5] = [0; 5];`
#[test]
fn test_uninitialized_array_correct_init() {
let c_code = r#"
int main() {
int nums[5];
nums[0] = 1;
return 0;
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
// CRITICAL: Should NOT have `= 5;` (array size as init)
assert!(
!rust_code.contains(": [i32; 5] = 5;"),
"BUG: Array size (5) was incorrectly used as initializer!\nGot:\n{}",
rust_code
);
// Should have proper array initialization syntax
assert!(
rust_code.contains("[0; 5]") || rust_code.contains("[i32; 5]"),
"Expected proper array initialization syntax\nGot:\n{}",
rust_code
);
}
/// Test that arrays with actual initializers work correctly.
///
/// C: `int arr[3] = {1, 2, 3};`
/// Expected: `let arr: [i32; 3] = [1, 2, 3];`
#[test]
fn test_initialized_array_with_values() {
let c_code = r#"
int main() {
int arr[3] = {1, 2, 3};
return arr[0];
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
// Should NOT have `= 3;` (array size as init)
assert!(
!rust_code.contains(": [i32; 3] = 3;"),
"BUG: Array size (3) was incorrectly used as initializer!\nGot:\n{}",
rust_code
);
}
/// Test array sum pattern from training corpus.
///
/// This is the exact pattern from reprorusted-c-cli/training_corpus/array_sum.c
/// that was failing during oracle trace generation.
#[test]
fn test_array_sum_corpus_pattern() {
let c_code = r#"
int sum_array(int *arr, int len) {
int sum = 0;
int i = 0;
while (i < len) {
sum = sum + *(arr + i);
i = i + 1;
}
return sum;
}
int main() {
int nums[5];
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 4;
nums[4] = 5;
return sum_array(nums, 5);
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
// CRITICAL: nums array should NOT be initialized with size value
assert!(
!rust_code.contains(": [i32; 5] = 5;"),
"BUG: Array size (5) was incorrectly used as initializer!\nGot:\n{}",
rust_code
);
// Should compile without E0308 type mismatch
// The generated code should have proper array initialization
}
/// Test that char arrays also work correctly.
#[test]
fn test_char_array_uninit() {
let c_code = r#"
int main() {
char buf[100];
buf[0] = 'H';
return 0;
}
"#;
let result = transpile(c_code);
assert!(result.is_ok(), "Transpilation failed: {:?}", result.err());
let rust_code = result.unwrap();
// Should NOT have `= 100;` (array size as init)
assert!(
!rust_code.contains("= 100;"),
"BUG: Char array size (100) was incorrectly used as initializer!\nGot:\n{}",
rust_code
);
}
/// Test multi-dimensional arrays.
#[test]
fn test_multidim_array_uninit() {
let c_code = r#"
int main() {
int matrix[3][4];
matrix[0][0] = 1;
return 0;
}
"#;
let result = transpile(c_code);
// Multi-dim arrays may not be fully supported yet, but should not panic
// and should not use the size as initializer
if let Ok(rust_code) = result {
// Should NOT have `= 3;` or `= 4;` as initializers
assert!(
!rust_code.contains("matrix") || !rust_code.contains("= 3;"),
"BUG: Multi-dim array size was incorrectly used as initializer!\nGot:\n{}",
rust_code
);
}
}