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...@@ -2120,6 +2120,20 @@ fn analyzeExport(self: *Module, scope: *Scope, src: usize, symbol_name: []const
2120 else => return self.fail(scope, src, "unable to export type '{}'", .{typed_value.ty}),2120 else => return self.fail(scope, src, "unable to export type '{}'", .{typed_value.ty}),
2121 }2121 }
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
2123 try self.decl_exports.ensureCapacity(self.decl_exports.size + 1);2137 try self.decl_exports.ensureCapacity(self.decl_exports.size + 1);
2124 try self.export_owners.ensureCapacity(self.export_owners.size + 1);2138 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...@@ -2155,19 +2169,29 @@ fn analyzeExport(self: *Module, scope: *Scope, src: usize, symbol_name: []const
2155 de_gop.kv.value[de_gop.kv.value.len - 1] = new_export;2169 de_gop.kv.value[de_gop.kv.value.len - 1] = new_export;
2156 errdefer de_gop.kv.value = self.allocator.shrink(de_gop.kv.value, de_gop.kv.value.len - 1);2170 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) {2172 if (already_exported) {
2159 error.OutOfMemory => return error.OutOfMemory,2173 try self.failed_exports.ensureCapacity(self.failed_exports.size + 1);
2160 else => {2174 self.failed_exports.putAssumeCapacityNoClobber(new_export, try ErrorMsg.create(
2161 try self.failed_exports.ensureCapacity(self.failed_exports.size + 1);2175 self.allocator,
2162 self.failed_exports.putAssumeCapacityNoClobber(new_export, try ErrorMsg.create(2176 src,
2163 self.allocator,2177 "exported symbol collision: {}",
2164 src,2178 .{symbol_name},
2165 "unable to export: {}",2179 ));
2166 .{@errorName(err)},2180 } else {
2167 ));2181 self.bin_file.updateDeclExports(self, exported_decl, de_gop.kv.value) catch |err| switch (err) {
2168 new_export.status = .failed_retryable;2182 error.OutOfMemory => return error.OutOfMemory,
2169 },2183 else => {
2170 };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 }
2171}2195}
21722196
2173fn addNewInstArgs(2197fn addNewInstArgs(
test/stage2/compile_errors.zig+28-4
...@@ -43,13 +43,37 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -43,13 +43,37 @@ pub fn addCases(ctx: *TestContext) !void {
43 \\@1 = export(@0, "start")43 \\@1 = export(@0, "start")
44 , &[_][]const u8{":4:9: error: unable to call function with naked calling convention"});44 , &[_][]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 }
46 // TODO: re-enable these tests.70 // TODO: re-enable these tests.
47 // https://github.com/ziglang/zig/issues/136471 // https://github.com/ziglang/zig/issues/1364
4872
49 // ctx.addError("Export same symbol twice", linux_x64, .Zig,73 // ctx.compileError("Export same symbol twice", linux_x64,
50 // \\export fn entry() void {}74 // \\export fn entry() void {}
51 // \\export fn entry() void {}75 // \\export fn entry() void {}
52 // , &[_][]const u8{":2:1: error: exported symbol collision"});76 // , &[_][]const u8{":2:1: error: exported symbol collision"});
5377
54 // ctx.addError("Missing function name", linux_x64, .Zig,78 // ctx.addError("Missing function name", linux_x64, .Zig,
55 // \\fn() void {}79 // \\fn() void {}