authorgravatar for noam@pixelhero.devNoam Preil <noam@pixelhero.dev> 2020-06-26 03:17:13-04:00
committergravatar for noam@pixelhero.devNoam Preil <noam@pixelhero.dev> 2020-06-26 03:17:13-04:00
log4a17e008daa90d5dbb0fc917d53e52c1ec990f2d
tree88ee5dcbcfe5c9d8ff1cac5923e21eb02b44eae2
parente5a3cb8d7134d7c4e4db03a609c5b7b6de00edfc
signature Commit is signed but in an unrecognized format.

Stage2: exported symbol collision detection


2 files changed, 65 insertions(+), 17 deletions(-)

src-self-hosted/Module.zig+37-13
......@@ -2120,6 +2120,20 @@ fn analyzeExport(self: *Module, scope: *Scope, src: usize, symbol_name: []const
21202120 else => return self.fail(scope, src, "unable to export type '{}'", .{typed_value.ty}),
21212121 }
21222122
2123 var already_exported = false;
2124 {
2125 var it = self.decl_exports.iterator();
2126 while (it.next()) |kv| {
2127 const export_list = kv.value;
2128 for (export_list) |e| {
2129 if (std.mem.eql(u8, e.options.name, symbol_name)) {
2130 already_exported = true;
2131 break;
2132 }
2133 }
2134 }
2135 }
2136
21232137 try self.decl_exports.ensureCapacity(self.decl_exports.size + 1);
21242138 try self.export_owners.ensureCapacity(self.export_owners.size + 1);
21252139
......@@ -2155,19 +2169,29 @@ fn analyzeExport(self: *Module, scope: *Scope, src: usize, symbol_name: []const
21552169 de_gop.kv.value[de_gop.kv.value.len - 1] = new_export;
21562170 errdefer de_gop.kv.value = self.allocator.shrink(de_gop.kv.value, de_gop.kv.value.len - 1);
21572171
2158 self.bin_file.updateDeclExports(self, exported_decl, de_gop.kv.value) catch |err| switch (err) {
2159 error.OutOfMemory => return error.OutOfMemory,
2160 else => {
2161 try self.failed_exports.ensureCapacity(self.failed_exports.size + 1);
2162 self.failed_exports.putAssumeCapacityNoClobber(new_export, try ErrorMsg.create(
2163 self.allocator,
2164 src,
2165 "unable to export: {}",
2166 .{@errorName(err)},
2167 ));
2168 new_export.status = .failed_retryable;
2169 },
2170 };
2172 if (already_exported) {
2173 try self.failed_exports.ensureCapacity(self.failed_exports.size + 1);
2174 self.failed_exports.putAssumeCapacityNoClobber(new_export, try ErrorMsg.create(
2175 self.allocator,
2176 src,
2177 "exported symbol collision: {}",
2178 .{symbol_name},
2179 ));
2180 } else {
2181 self.bin_file.updateDeclExports(self, exported_decl, de_gop.kv.value) catch |err| switch (err) {
2182 error.OutOfMemory => return error.OutOfMemory,
2183 else => {
2184 try self.failed_exports.ensureCapacity(self.failed_exports.size + 1);
2185 self.failed_exports.putAssumeCapacityNoClobber(new_export, try ErrorMsg.create(
2186 self.allocator,
2187 src,
2188 "unable to export: {}",
2189 .{@errorName(err)},
2190 ));
2191 new_export.status = .failed_retryable;
2192 },
2193 };
2194 }
21712195}
21722196
21732197fn addNewInstArgs(
test/stage2/compile_errors.zig+28-4
......@@ -43,13 +43,37 @@ pub fn addCases(ctx: *TestContext) !void {
4343 \\@1 = export(@0, "start")
4444 , &[_][]const u8{":4:9: error: unable to call function with naked calling convention"});
4545
46 {
47 var case = ctx.objZIR("exported symbol collision", linux_x64);
48 // First, ensure we receive the error correctly
49 case.addError(
50 \\@noreturn = primitive(noreturn)
51 \\
52 \\@start_fnty = fntype([], @noreturn)
53 \\@start = fn(@start_fnty, {})
54 \\
55 \\@0 = str("_start")
56 \\@1 = export(@0, "start")
57 \\@2 = export(@0, "start")
58 , &[_][]const u8{":8:13: error: exported symbol collision: _start"});
59 // Next, ensure everything works properly on the next compilation with the problem fixed
60 case.compiles(
61 \\@noreturn = primitive(noreturn)
62 \\
63 \\@start_fnty = fntype([], @noreturn)
64 \\@start = fn(@start_fnty, {})
65 \\
66 \\@0 = str("_start")
67 \\@1 = export(@0, "start")
68 );
69 }
4670 // TODO: re-enable these tests.
4771 // https://github.com/ziglang/zig/issues/1364
4872
49 // ctx.addError("Export same symbol twice", linux_x64, .Zig,
50 // \\export fn entry() void {}
51 // \\export fn entry() void {}
52 // , &[_][]const u8{":2:1: error: exported symbol collision"});
73 // ctx.compileError("Export same symbol twice", linux_x64,
74 // \\export fn entry() void {}
75 // \\export fn entry() void {}
76 // , &[_][]const u8{":2:1: error: exported symbol collision"});
5377
5478 // ctx.addError("Missing function name", linux_x64, .Zig,
5579 // \\fn() void {}