zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 0bdc0bb534ed6d3cc787b5bca44173d2b49480da (tree)
parent 0753af792a41645b6cac51d7bd29b2c526c3b81b
Author: Parker Liu <flyfish30@users.noreply.github.com>
Date:   Tue,  1 Apr 2025 01:22:03 +0800

translate-c: fix referencing extern locals from nested blocks


Diffstat:
Mlib/compiler/aro_translate_c.zig | 6+++++-
Msrc/translate_c.zig | 9++++++++-
Atest/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 @@ -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 @@ -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 @@ -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