diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-16 23:54:25 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-17 00:00:41 -0700 |
| commit | 87779cfd93fdcb525f386d693a099e4188a3fc44 (patch) | |
| tree | d5dab5dfbd5a5d93645996fde1c9c1199e2adf0b /src/codegen/llvm.zig | |
| parent | 79d3780fbda475a50d6e0ca53d51c9e7c7690ab1 (diff) | |
| download | zig-87779cfd93fdcb525f386d693a099e4188a3fc44.tar.gz zig-87779cfd93fdcb525f386d693a099e4188a3fc44.zip | |
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.
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index b41611813e..8fb2a171ef 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3472,8 +3472,8 @@ pub const FuncGen = struct { .const_ty => unreachable, .unreach => self.airUnreach(inst), .dbg_stmt => self.airDbgStmt(inst), - .dbg_inline_begin => try self.airDbgInline(inst, true), - .dbg_inline_end => try self.airDbgInline(inst, false), + .dbg_inline_begin => try self.airDbgInlineBegin(inst), + .dbg_inline_end => try self.airDbgInlineEnd(inst), .dbg_var_ptr => try self.airDbgVarPtr(inst), .dbg_var_val => try self.airDbgVarVal(inst), // zig fmt: on @@ -4199,7 +4199,7 @@ pub const FuncGen = struct { return null; } - fn airDbgInline(self: *FuncGen, inst: Air.Inst.Index, start: bool) !?*const llvm.Value { + fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { const dib = self.dg.object.di_builder orelse return null; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; @@ -4209,52 +4209,52 @@ pub const FuncGen = struct { self.di_file = di_file; const line_number = decl.src_line + 1; const cur_debug_location = self.builder.getCurrentDebugLocation2(); - if (start) { - try self.dbg_inlined.append(self.gpa, .{ - .loc = @ptrCast(*llvm.DILocation, cur_debug_location), - .scope = self.di_scope.?, - .base_line = self.base_line, - }); - } else { - const old = self.dbg_inlined.pop(); - self.di_scope = old.scope; - self.base_line = old.base_line; - return null; - } - const fn_ty = try self.air.getRefType(ty_pl.ty).copy(self.dg.object.type_map_arena.allocator()); + try self.dbg_inlined.append(self.gpa, .{ + .loc = @ptrCast(*llvm.DILocation, cur_debug_location), + .scope = self.di_scope.?, + .base_line = self.base_line, + }); + const fqn = try decl.getFullyQualifiedName(self.gpa); defer self.gpa.free(fqn); - const fn_info = fn_ty.fnInfo(); const is_internal_linkage = !self.dg.module.decl_exports.contains(decl); - const noret_bit: c_uint = if (fn_info.return_type.isNoReturn()) - llvm.DIFlags.NoReturn - else - 0; const subprogram = dib.createFunction( di_file.toScope(), decl.name, fqn, di_file, line_number, - try self.dg.object.lowerDebugType(fn_ty, .full), + try self.dg.object.lowerDebugType(Type.initTag(.fn_void_no_args), .full), is_internal_linkage, true, // is definition line_number + func.lbrace_line, // scope line - llvm.DIFlags.StaticMember | noret_bit, + llvm.DIFlags.StaticMember, self.dg.module.comp.bin_file.options.optimize_mode != .Debug, null, // decl_subprogram ); - try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode()); - const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file, line_number, 1); self.di_scope = lexical_block.toScope(); self.base_line = decl.src_line; return null; } + fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { + if (self.dg.object.di_builder == null) return null; + const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; + + const func = self.air.values[ty_pl.payload].castTag(.function).?.data; + const decl = func.owner_decl; + const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope); + self.di_file = di_file; + const old = self.dbg_inlined.pop(); + self.di_scope = old.scope; + self.base_line = old.base_line; + return null; + } + fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { const dib = self.dg.object.di_builder orelse return null; const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
