diff options
| author | Parker Liu <flyfish30@users.noreply.github.com> | 2025-04-01 01:22:03 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-31 20:22:03 +0300 |
| commit | 0bdc0bb534ed6d3cc787b5bca44173d2b49480da (patch) | |
| tree | 0344b4b07edca28ee5d306c04d46e7b442984684 | |
| parent | 0753af792a41645b6cac51d7bd29b2c526c3b81b (diff) | |
| download | zig-0bdc0bb534ed6d3cc787b5bca44173d2b49480da.tar.gz zig-0bdc0bb534ed6d3cc787b5bca44173d2b49480da.zip | |
translate-c: fix referencing extern locals from nested blocks
| -rw-r--r-- | lib/compiler/aro_translate_c.zig | 6 | ||||
| -rw-r--r-- | src/translate_c.zig | 9 | ||||
| -rw-r--r-- | test/cases/run_translated_c/sub_scope_extern_local_var_ref.c | 23 |
3 files changed, 36 insertions, 2 deletions
diff --git a/lib/compiler/aro_translate_c.zig b/lib/compiler/aro_translate_c.zig index ffb133dad5..5abc244c97 100644 --- a/lib/compiler/aro_translate_c.zig +++ b/lib/compiler/aro_translate_c.zig @@ -1620,7 +1620,11 @@ pub fn ScopeExtra(comptime ScopeExtraContext: type, comptime ScopeExtraType: typ .root => null, .block => ret: { const block = @as(*Block, @fieldParentPtr("base", scope)); - break :ret block.getLocalExternAlias(name); + const alias_name = block.getLocalExternAlias(name); + if (alias_name) |_alias_name| { + break :ret _alias_name; + } + break :ret scope.parent.?.getLocalExternAlias(name); }, .loop, .do_loop, .condition => scope.parent.?.getLocalExternAlias(name), }; diff --git a/src/translate_c.zig b/src/translate_c.zig index 19a2fde13c..20a5f75e21 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -1964,7 +1964,14 @@ fn transImplicitCastExpr( return maybeSuppressResult(c, result_used, sub_expr_node); } - const addr = try Tag.address_of.create(c.arena, sub_expr_node); + const index_val = try Tag.integer_literal.create(c.arena, "0"); + const index = try Tag.as.create(c.arena, .{ + .lhs = try Tag.type.create(c.arena, "usize"), + .rhs = try Tag.int_cast.create(c.arena, index_val), + }); + const array0_node = try Tag.array_access.create(c.arena, .{ .lhs = sub_expr_node, .rhs = index }); + // Convert array to pointer by expression: addr = &sub_expr[0] + const addr = try Tag.address_of.create(c.arena, array0_node); const casted = try transCPtrCast(c, scope, expr.getBeginLoc(), dest_type, src_type, addr); return maybeSuppressResult(c, result_used, casted); }, diff --git a/test/cases/run_translated_c/sub_scope_extern_local_var_ref.c b/test/cases/run_translated_c/sub_scope_extern_local_var_ref.c new file mode 100644 index 0000000000..f3461f8559 --- /dev/null +++ b/test/cases/run_translated_c/sub_scope_extern_local_var_ref.c @@ -0,0 +1,23 @@ +#include <stdlib.h> +int a = 42; +int foo(int bar) { + extern int a; + if (bar) { + return a; + } + return 0; +} +int main() { + int result1 = foo(0); + if (result1 != 0) abort(); + int result2 = foo(1); + if (result2 != 42) abort(); + a = 100; + int result3 = foo(1); + if (result3 != 100) abort(); + return 0; +} + +// run-translated-c +// c_frontend=clang +// link_libc=true |
