authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-16 23:54:25-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-17 00:00:41-07:00
log87779cfd93fdcb525f386d693a099e4188a3fc44
treed5dab5dfbd5a5d93645996fde1c9c1199e2adf0b
parent79d3780fbda475a50d6e0ca53d51c9e7c7690ab1

stage2: prevent UB in the LLVM backend

* Sema: fix `zirTypeInfo` allocating with the wrong arenas for some stuff. * LLVM: split `airDbgInline` into two functions, one for each AIR tag. - remove the redundant copy to type_map_arena. This is the first thing that lowerDebugType does so this hack was probably just accidentally avoiding UB (which is still present prior to this commit). - don't store an inline fn inst into the di_map for the generic decl. - use a dummy function type for the debug info to avoid whatever UB is happening. - we are now ignoring the function type passed in with the dbg_inline_begin and dbg_inline_end. * behavior tests: prepare the vector tests to be enabled one at a time. Mitigates #11199.

4 files changed, 55 insertions(+), 30 deletions(-)

src/Sema.zig+4-4
......@@ -10907,9 +10907,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1090710907 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1090810908 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
1090910909 );
10910 break :v try Value.Tag.slice.create(sema.arena, .{
10910 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
1091110911 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),
10912 .len = try Value.Tag.int_u64.create(sema.arena, bytes.len),
10912 .len = try Value.Tag.int_u64.create(fields_anon_decl.arena(), bytes.len),
1091310913 });
1091410914 };
1091510915
......@@ -10950,9 +10950,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1095010950 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1095110951 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
1095210952 );
10953 break :v try Value.Tag.slice.create(sema.arena, .{
10953 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
1095410954 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),
10955 .len = try Value.Tag.int_u64.create(sema.arena, bytes.len),
10955 .len = try Value.Tag.int_u64.create(fields_anon_decl.arena(), bytes.len),
1095610956 });
1095710957 };
1095810958
src/codegen/llvm.zig+25-25
......@@ -3472,8 +3472,8 @@ pub const FuncGen = struct {
34723472 .const_ty => unreachable,
34733473 .unreach => self.airUnreach(inst),
34743474 .dbg_stmt => self.airDbgStmt(inst),
3475 .dbg_inline_begin => try self.airDbgInline(inst, true),
3476 .dbg_inline_end => try self.airDbgInline(inst, false),
3475 .dbg_inline_begin => try self.airDbgInlineBegin(inst),
3476 .dbg_inline_end => try self.airDbgInlineEnd(inst),
34773477 .dbg_var_ptr => try self.airDbgVarPtr(inst),
34783478 .dbg_var_val => try self.airDbgVarVal(inst),
34793479 // zig fmt: on
......@@ -4199,7 +4199,7 @@ pub const FuncGen = struct {
41994199 return null;
42004200 }
42014201
4202 fn airDbgInline(self: *FuncGen, inst: Air.Inst.Index, start: bool) !?*const llvm.Value {
4202 fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
42034203 const dib = self.dg.object.di_builder orelse return null;
42044204 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
42054205
......@@ -4209,52 +4209,52 @@ pub const FuncGen = struct {
42094209 self.di_file = di_file;
42104210 const line_number = decl.src_line + 1;
42114211 const cur_debug_location = self.builder.getCurrentDebugLocation2();
4212 if (start) {
4213 try self.dbg_inlined.append(self.gpa, .{
4214 .loc = @ptrCast(*llvm.DILocation, cur_debug_location),
4215 .scope = self.di_scope.?,
4216 .base_line = self.base_line,
4217 });
4218 } else {
4219 const old = self.dbg_inlined.pop();
4220 self.di_scope = old.scope;
4221 self.base_line = old.base_line;
4222 return null;
4223 }
42244212
4225 const fn_ty = try self.air.getRefType(ty_pl.ty).copy(self.dg.object.type_map_arena.allocator());
4213 try self.dbg_inlined.append(self.gpa, .{
4214 .loc = @ptrCast(*llvm.DILocation, cur_debug_location),
4215 .scope = self.di_scope.?,
4216 .base_line = self.base_line,
4217 });
4218
42264219 const fqn = try decl.getFullyQualifiedName(self.gpa);
42274220 defer self.gpa.free(fqn);
4228 const fn_info = fn_ty.fnInfo();
42294221
42304222 const is_internal_linkage = !self.dg.module.decl_exports.contains(decl);
4231 const noret_bit: c_uint = if (fn_info.return_type.isNoReturn())
4232 llvm.DIFlags.NoReturn
4233 else
4234 0;
42354223 const subprogram = dib.createFunction(
42364224 di_file.toScope(),
42374225 decl.name,
42384226 fqn,
42394227 di_file,
42404228 line_number,
4241 try self.dg.object.lowerDebugType(fn_ty, .full),
4229 try self.dg.object.lowerDebugType(Type.initTag(.fn_void_no_args), .full),
42424230 is_internal_linkage,
42434231 true, // is definition
42444232 line_number + func.lbrace_line, // scope line
4245 llvm.DIFlags.StaticMember | noret_bit,
4233 llvm.DIFlags.StaticMember,
42464234 self.dg.module.comp.bin_file.options.optimize_mode != .Debug,
42474235 null, // decl_subprogram
42484236 );
42494237
4250 try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode());
4251
42524238 const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file, line_number, 1);
42534239 self.di_scope = lexical_block.toScope();
42544240 self.base_line = decl.src_line;
42554241 return null;
42564242 }
42574243
4244 fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
4245 if (self.dg.object.di_builder == null) return null;
4246 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
4247
4248 const func = self.air.values[ty_pl.payload].castTag(.function).?.data;
4249 const decl = func.owner_decl;
4250 const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope);
4251 self.di_file = di_file;
4252 const old = self.dbg_inlined.pop();
4253 self.di_scope = old.scope;
4254 self.base_line = old.base_line;
4255 return null;
4256 }
4257
42584258 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
42594259 const dib = self.dg.object.di_builder orelse return null;
42604260 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
test/behavior.zig+1-1
......@@ -125,6 +125,7 @@ test {
125125 _ = @import("behavior/union.zig");
126126 _ = @import("behavior/usingnamespace.zig");
127127 _ = @import("behavior/var_args.zig");
128 _ = @import("behavior/vector.zig");
128129 _ = @import("behavior/void.zig");
129130 _ = @import("behavior/while.zig");
130131
......@@ -179,7 +180,6 @@ test {
179180 _ = @import("behavior/select.zig");
180181 _ = @import("behavior/struct_contains_slice_of_itself.zig");
181182 _ = @import("behavior/typename.zig");
182 _ = @import("behavior/vector.zig");
183183 }
184184 }
185185 }
test/behavior/vector.zig+25
......@@ -8,6 +8,7 @@ const expectApproxEqRel = std.testing.expectApproxEqRel;
88const Vector = std.meta.Vector;
99
1010test "implicit cast vector to array - bool" {
11 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
1112 const S = struct {
1213 fn doTheTest() !void {
1314 const a: Vector(4, bool) = [_]bool{ true, false, true, false };
......@@ -20,6 +21,7 @@ test "implicit cast vector to array - bool" {
2021}
2122
2223test "vector wrap operators" {
24 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
2325 const S = struct {
2426 fn doTheTest() !void {
2527 var v: Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
......@@ -36,6 +38,7 @@ test "vector wrap operators" {
3638}
3739
3840test "vector bin compares with mem.eql" {
41 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
3942 const S = struct {
4043 fn doTheTest() !void {
4144 var v: Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
......@@ -53,6 +56,7 @@ test "vector bin compares with mem.eql" {
5356}
5457
5558test "vector int operators" {
59 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
5660 const S = struct {
5761 fn doTheTest() !void {
5862 var v: Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };
......@@ -68,6 +72,7 @@ test "vector int operators" {
6872}
6973
7074test "vector float operators" {
75 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
7176 const S = struct {
7277 fn doTheTest() !void {
7378 var v: Vector(4, f32) = [4]f32{ 10, 20, 30, 40 };
......@@ -83,6 +88,7 @@ test "vector float operators" {
8388}
8489
8590test "vector bit operators" {
91 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
8692 const S = struct {
8793 fn doTheTest() !void {
8894 var v: Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 };
......@@ -97,6 +103,7 @@ test "vector bit operators" {
97103}
98104
99105test "implicit cast vector to array" {
106 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
100107 const S = struct {
101108 fn doTheTest() !void {
102109 var a: Vector(4, i32) = [_]i32{ 1, 2, 3, 4 };
......@@ -110,6 +117,7 @@ test "implicit cast vector to array" {
110117}
111118
112119test "array to vector" {
120 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
113121 var foo: f32 = 3.14;
114122 var arr = [4]f32{ foo, 1.5, 0.0, 0.0 };
115123 var vec: Vector(4, f32) = arr;
......@@ -117,6 +125,7 @@ test "array to vector" {
117125}
118126
119127test "vector casts of sizes not divisible by 8" {
128 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
120129 const S = struct {
121130 fn doTheTest() !void {
122131 {
......@@ -146,6 +155,7 @@ test "vector casts of sizes not divisible by 8" {
146155}
147156
148157test "vector @splat" {
158 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
149159 const S = struct {
150160 fn testForT(comptime N: comptime_int, v: anytype) !void {
151161 const T = @TypeOf(v);
......@@ -181,6 +191,7 @@ test "vector @splat" {
181191}
182192
183193test "load vector elements via comptime index" {
194 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
184195 const S = struct {
185196 fn doTheTest() !void {
186197 var v: Vector(4, i32) = [_]i32{ 1, 2, 3, undefined };
......@@ -198,6 +209,7 @@ test "load vector elements via comptime index" {
198209}
199210
200211test "store vector elements via comptime index" {
212 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
201213 const S = struct {
202214 fn doTheTest() !void {
203215 var v: Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
......@@ -221,6 +233,7 @@ test "store vector elements via comptime index" {
221233}
222234
223235test "load vector elements via runtime index" {
236 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
224237 const S = struct {
225238 fn doTheTest() !void {
226239 var v: Vector(4, i32) = [_]i32{ 1, 2, 3, undefined };
......@@ -238,6 +251,7 @@ test "load vector elements via runtime index" {
238251}
239252
240253test "store vector elements via runtime index" {
254 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
241255 const S = struct {
242256 fn doTheTest() !void {
243257 var v: Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
......@@ -256,6 +270,7 @@ test "store vector elements via runtime index" {
256270}
257271
258272test "initialize vector which is a struct field" {
273 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
259274 const Vec4Obj = struct {
260275 data: Vector(4, f32),
261276 };
......@@ -273,6 +288,7 @@ test "initialize vector which is a struct field" {
273288}
274289
275290test "vector comparison operators" {
291 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
276292 const S = struct {
277293 fn doTheTest() !void {
278294 {
......@@ -307,6 +323,7 @@ test "vector comparison operators" {
307323}
308324
309325test "vector division operators" {
326 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
310327 const S = struct {
311328 fn doTheTestDiv(comptime T: type, x: Vector(4, T), y: Vector(4, T)) !void {
312329 if (!comptime std.meta.trait.isSignedInt(T)) {
......@@ -389,6 +406,7 @@ test "vector division operators" {
389406}
390407
391408test "vector bitwise not operator" {
409 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
392410 const S = struct {
393411 fn doTheTestNot(comptime T: type, x: Vector(4, T)) !void {
394412 var y = ~x;
......@@ -414,6 +432,7 @@ test "vector bitwise not operator" {
414432}
415433
416434test "vector shift operators" {
435 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
417436 const S = struct {
418437 fn doTheTestShift(x: anytype, y: anytype) !void {
419438 const N = @typeInfo(@TypeOf(x)).Array.len;
......@@ -501,6 +520,7 @@ test "vector shift operators" {
501520}
502521
503522test "vector reduce operation" {
523 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
504524 const S = struct {
505525 fn doTheTestReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) !void {
506526 const N = @typeInfo(@TypeOf(x)).Array.len;
......@@ -636,6 +656,7 @@ test "vector reduce operation" {
636656}
637657
638658test "mask parameter of @shuffle is comptime scope" {
659 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
639660 const __v4hi = std.meta.Vector(4, i16);
640661 var v4_a = __v4hi{ 0, 0, 0, 0 };
641662 var v4_b = __v4hi{ 0, 0, 0, 0 };
......@@ -649,6 +670,7 @@ test "mask parameter of @shuffle is comptime scope" {
649670}
650671
651672test "saturating add" {
673 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
652674 const S = struct {
653675 fn doTheTest() !void {
654676 const u8x3 = std.meta.Vector(3, u8);
......@@ -662,6 +684,7 @@ test "saturating add" {
662684}
663685
664686test "saturating subtraction" {
687 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
665688 const S = struct {
666689 fn doTheTest() !void {
667690 const u8x3 = std.meta.Vector(3, u8);
......@@ -673,6 +696,7 @@ test "saturating subtraction" {
673696}
674697
675698test "saturating multiplication" {
699 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
676700 // TODO: once #9660 has been solved, remove this line
677701 if (builtin.target.cpu.arch == .wasm32) return error.SkipZigTest;
678702
......@@ -688,6 +712,7 @@ test "saturating multiplication" {
688712}
689713
690714test "saturating shift-left" {
715 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
691716 const S = struct {
692717 fn doTheTest() !void {
693718 const u8x3 = std.meta.Vector(3, u8);