| author | |
| committer | |
| log | d25674a51ec09640b0140a541a156869b3e03f81 |
| tree | b83dfe45ade9704364c06624942a8b2bccf1c02e |
| parent | a553947a51bc5858ff40fb47dfe41daaa9ff75bf |
| signature |
8 files changed, 23 insertions(+), 11 deletions(-)
lib/std/c/darwin.zig+1-1| ... | ... | @@ -41,7 +41,7 @@ const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header; |
| 41 | 41 | /// on this operating system. However when building object files or libraries, |
| 42 | 42 | /// the system libc won't be linked until the final executable. So we |
| 43 | 43 | /// export a weak symbol here, to be overridden by the real one. |
| 44 | pub extern "c" var _mh_execute_header: mach_hdr = undefined; | |
| 44 | pub extern "c" var _mh_execute_header: mach_hdr; | |
| 45 | 45 | comptime { |
| 46 | 46 | if (std.Target.current.isDarwin()) { |
| 47 | 47 | @export(_mh_execute_header, .{ .name = "_mh_execute_header", .linkage = .Weak }); |
lib/std/special/c.zig+1-1| ... | ... | @@ -35,7 +35,7 @@ comptime { |
| 35 | 35 | } |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | extern var _fltused: c_int = 1; | |
| 38 | var _fltused: c_int = 1; | |
| 39 | 39 | |
| 40 | 40 | extern fn main(argc: c_int, argv: [*:null]?[*:0]u8) c_int; |
| 41 | 41 | fn wasm_start() callconv(.C) void { |
lib/std/special/compiler_rt.zig+1-1| ... | ... | @@ -335,7 +335,7 @@ fn __stack_chk_fail() callconv(.C) noreturn { |
| 335 | 335 | @panic("stack smashing detected"); |
| 336 | 336 | } |
| 337 | 337 | |
| 338 | extern var __stack_chk_guard: usize = blk: { | |
| 338 | var __stack_chk_guard: usize = blk: { | |
| 339 | 339 | var buf = [1]u8{0} ** @sizeOf(usize); |
| 340 | 340 | buf[@sizeOf(usize) - 1] = 255; |
| 341 | 341 | buf[@sizeOf(usize) - 2] = '\n'; |
src-self-hosted/Module.zig+7-4| ... | ... | @@ -324,10 +324,10 @@ pub const Fn = struct { |
| 324 | 324 | }; |
| 325 | 325 | |
| 326 | 326 | pub const Var = struct { |
| 327 | /// if is_extern == true this is undefined | |
| 327 | 328 | init: Value, |
| 328 | 329 | owner_decl: *Decl, |
| 329 | 330 | |
| 330 | has_init: bool, | |
| 331 | 331 | is_extern: bool, |
| 332 | 332 | is_mutable: bool, |
| 333 | 333 | is_threadlocal: bool, |
| ... | ... | @@ -1456,7 +1456,11 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { |
| 1456 | 1456 | const is_extern = blk: { |
| 1457 | 1457 | const maybe_extern_token = var_decl.getTrailer("extern_export_token") orelse |
| 1458 | 1458 | break :blk false; |
| 1459 | break :blk tree.token_ids[maybe_extern_token] == .Keyword_extern; | |
| 1459 | if (tree.token_ids[maybe_extern_token] != .Keyword_extern) break :blk false; | |
| 1460 | if (var_decl.getTrailer("init_node")) |some| { | |
| 1461 | return self.failNode(&block_scope.base, some, "extern variables have no initializers", .{}); | |
| 1462 | } | |
| 1463 | break :blk true; | |
| 1460 | 1464 | }; |
| 1461 | 1465 | if (var_decl.getTrailer("lib_name")) |lib_name| { |
| 1462 | 1466 | assert(is_extern); |
| ... | ... | @@ -1569,7 +1573,6 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { |
| 1569 | 1573 | new_variable.* = .{ |
| 1570 | 1574 | .owner_decl = decl, |
| 1571 | 1575 | .init = value orelse undefined, |
| 1572 | .has_init = value != null, | |
| 1573 | 1576 | .is_extern = is_extern, |
| 1574 | 1577 | .is_mutable = is_mutable, |
| 1575 | 1578 | .is_threadlocal = is_threadlocal, |
| ... | ... | @@ -2440,7 +2443,7 @@ fn analyzeVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) Inner |
| 2440 | 2443 | const variable = tv.val.cast(Value.Payload.Variable).?.variable; |
| 2441 | 2444 | |
| 2442 | 2445 | const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty); |
| 2443 | if (!variable.is_mutable and !variable.is_extern and variable.has_init) { | |
| 2446 | if (!variable.is_mutable and !variable.is_extern) { | |
| 2444 | 2447 | const val_payload = try scope.arena().create(Value.Payload.RefVal); |
| 2445 | 2448 | val_payload.* = .{ .val = variable.init }; |
| 2446 | 2449 | return self.constInst(scope, src, .{ |
src/parser.cpp+3| ... | ... | @@ -680,6 +680,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B |
| 680 | 680 | AstNode *var_decl = ast_parse_var_decl(pc); |
| 681 | 681 | if (var_decl != nullptr) { |
| 682 | 682 | assert(var_decl->type == NodeTypeVariableDeclaration); |
| 683 | if (first->id == TokenIdKeywordExtern && var_decl->data.variable_declaration.expr != nullptr) { | |
| 684 | ast_error(pc, first, "extern variables have no initializers"); | |
| 685 | } | |
| 683 | 686 | var_decl->line = first->start_line; |
| 684 | 687 | var_decl->column = first->start_column; |
| 685 | 688 | var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw; |
test/compile_errors.zig+6| ... | ... | @@ -2,6 +2,12 @@ const tests = @import("tests.zig"); |
| 2 | 2 | const std = @import("std"); |
| 3 | 3 | |
| 4 | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.addTest("reject extern variables with initializers", | |
| 6 | \\extern var foo: int = 2; | |
| 7 | , &[_][]const u8{ | |
| 8 | "tmp.zig:1:1: error: extern variables have no initializers", | |
| 9 | }); | |
| 10 | ||
| 5 | 11 | cases.addTest("duplicate/unused labels", |
| 6 | 12 | \\comptime { |
| 7 | 13 | \\ blk: { blk: while (false) {} } |
test/standalone/global_linkage/obj1.zig+2-2| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | extern var internal_integer: usize = 1; | |
| 2 | extern var obj1_integer: usize = 421; | |
| 1 | var internal_integer: usize = 1; | |
| 2 | var obj1_integer: usize = 421; | |
| 3 | 3 | |
| 4 | 4 | comptime { |
| 5 | 5 | @export(internal_integer, .{ .name = "internal_integer", .linkage = .Internal }); |
test/standalone/global_linkage/obj2.zig+2-2| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | extern var internal_integer: usize = 2; | |
| 2 | extern var obj2_integer: usize = 422; | |
| 1 | var internal_integer: usize = 2; | |
| 2 | var obj2_integer: usize = 422; | |
| 3 | 3 | |
| 4 | 4 | comptime { |
| 5 | 5 | @export(internal_integer, .{ .name = "internal_integer", .linkage = .Internal }); |