Skip to content

Commit 0bdc0bb

Browse files
authored
translate-c: fix referencing extern locals from nested blocks
1 parent 0753af7 commit 0bdc0bb

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

lib/compiler/aro_translate_c.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1620,7 +1620,11 @@ pub fn ScopeExtra(comptime ScopeExtraContext: type, comptime ScopeExtraType: typ
16201620
.root => null,
16211621
.block => ret: {
16221622
const block = @as(*Block, @fieldParentPtr("base", scope));
1623-
break :ret block.getLocalExternAlias(name);
1623+
const alias_name = block.getLocalExternAlias(name);
1624+
if (alias_name) |_alias_name| {
1625+
break :ret _alias_name;
1626+
}
1627+
break :ret scope.parent.?.getLocalExternAlias(name);
16241628
},
16251629
.loop, .do_loop, .condition => scope.parent.?.getLocalExternAlias(name),
16261630
};

src/translate_c.zig

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1964,7 +1964,14 @@ fn transImplicitCastExpr(
19641964
return maybeSuppressResult(c, result_used, sub_expr_node);
19651965
}
19661966

1967-
const addr = try Tag.address_of.create(c.arena, sub_expr_node);
1967+
const index_val = try Tag.integer_literal.create(c.arena, "0");
1968+
const index = try Tag.as.create(c.arena, .{
1969+
.lhs = try Tag.type.create(c.arena, "usize"),
1970+
.rhs = try Tag.int_cast.create(c.arena, index_val),
1971+
});
1972+
const array0_node = try Tag.array_access.create(c.arena, .{ .lhs = sub_expr_node, .rhs = index });
1973+
// Convert array to pointer by expression: addr = &sub_expr[0]
1974+
const addr = try Tag.address_of.create(c.arena, array0_node);
19681975
const casted = try transCPtrCast(c, scope, expr.getBeginLoc(), dest_type, src_type, addr);
19691976
return maybeSuppressResult(c, result_used, casted);
19701977
},
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <stdlib.h>
2+
int a = 42;
3+
int foo(int bar) {
4+
extern int a;
5+
if (bar) {
6+
return a;
7+
}
8+
return 0;
9+
}
10+
int main() {
11+
int result1 = foo(0);
12+
if (result1 != 0) abort();
13+
int result2 = foo(1);
14+
if (result2 != 42) abort();
15+
a = 100;
16+
int result3 = foo(1);
17+
if (result3 != 100) abort();
18+
return 0;
19+
}
20+
21+
// run-translated-c
22+
// c_frontend=clang
23+
// link_libc=true

0 commit comments

Comments
 (0)