aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-09-16 21:43:01 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-09-16 21:43:01 -0700
commit091a98f524b41cac1fb299cdfdf911ae3b31c6ae (patch)
tree15ee8668a3e29e1ba4a978bebb4fb46583b3ac08
parentdbe9a5114e2d56f847b674539ffa0d28fc57ea78 (diff)
downloadzig-091a98f524b41cac1fb299cdfdf911ae3b31c6ae.tar.gz
zig-091a98f524b41cac1fb299cdfdf911ae3b31c6ae.zip
stage2: fix global variables with inferred type
Also, when a global variable does have a type, perform coercion on it.
-rw-r--r--src/Sema.zig21
-rw-r--r--test/behavior/atomics.zig7
-rw-r--r--test/behavior/atomics_stage1.zig7
3 files changed, 24 insertions, 11 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 58aa7ca1c0..645e68c6ef 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -7920,7 +7920,6 @@ fn zirVarExtended(
const mut_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at mut token
const init_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at init expr
const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
- const var_ty = try sema.resolveType(block, ty_src, extra.data.var_type);
var extra_index: usize = extra.end;
@@ -7940,11 +7939,25 @@ fn zirVarExtended(
// break :blk align_tv.val;
//} else Value.initTag(.null_value);
- const init_val: Value = if (small.has_init) blk: {
+ const uncasted_init: Air.Inst.Ref = if (small.has_init) blk: {
const init_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const init_air_inst = sema.resolveInst(init_ref);
- break :blk (try sema.resolveMaybeUndefVal(block, init_src, init_air_inst)) orelse
+ break :blk sema.resolveInst(init_ref);
+ } else .none;
+
+ const have_ty = extra.data.var_type != .none;
+ const var_ty = if (have_ty)
+ try sema.resolveType(block, ty_src, extra.data.var_type)
+ else
+ sema.typeOf(uncasted_init);
+
+ const init_val = if (uncasted_init != .none) blk: {
+ const init = if (have_ty)
+ try sema.coerce(block, var_ty, uncasted_init, init_src)
+ else
+ uncasted_init;
+
+ break :blk (try sema.resolveMaybeUndefVal(block, init_src, init)) orelse
return sema.failWithNeededComptime(block, init_src);
} else Value.initTag(.unreachable_value);
diff --git a/test/behavior/atomics.zig b/test/behavior/atomics.zig
index aae187739b..4e48913fef 100644
--- a/test/behavior/atomics.zig
+++ b/test/behavior/atomics.zig
@@ -111,3 +111,10 @@ fn test_u128_cmpxchg() !void {
try expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
try expect(x == 42);
}
+
+var a_global_variable = @as(u32, 1234);
+
+test "cmpxchg on a global variable" {
+ _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
+ try expect(a_global_variable == 42);
+}
diff --git a/test/behavior/atomics_stage1.zig b/test/behavior/atomics_stage1.zig
index c9e0ea1a60..86082825c7 100644
--- a/test/behavior/atomics_stage1.zig
+++ b/test/behavior/atomics_stage1.zig
@@ -3,13 +3,6 @@ const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
const builtin = @import("builtin");
-var a_global_variable = @as(u32, 1234);
-
-test "cmpxchg on a global variable" {
- _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
- try expectEqual(@as(u32, 42), a_global_variable);
-}
-
test "atomic load and rmw with enum" {
const Value = enum(u8) {
a,