aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-03-16 23:54:25 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-03-17 00:00:41 -0700
commit87779cfd93fdcb525f386d693a099e4188a3fc44 (patch)
treed5dab5dfbd5a5d93645996fde1c9c1199e2adf0b /src/codegen/llvm.zig
parent79d3780fbda475a50d6e0ca53d51c9e7c7690ab1 (diff)
downloadzig-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.zig50
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;