aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParker Liu <flyfish30@users.noreply.github.com>2025-04-01 01:22:03 +0800
committerGitHub <noreply@github.com>2025-03-31 20:22:03 +0300
commit0bdc0bb534ed6d3cc787b5bca44173d2b49480da (patch)
tree0344b4b07edca28ee5d306c04d46e7b442984684
parent0753af792a41645b6cac51d7bd29b2c526c3b81b (diff)
downloadzig-0bdc0bb534ed6d3cc787b5bca44173d2b49480da.tar.gz
zig-0bdc0bb534ed6d3cc787b5bca44173d2b49480da.zip
translate-c: fix referencing extern locals from nested blocks
-rw-r--r--lib/compiler/aro_translate_c.zig6
-rw-r--r--src/translate_c.zig9
-rw-r--r--test/cases/run_translated_c/sub_scope_extern_local_var_ref.c23
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