explicitly return from blocks

instead of last statement being expression value

closes #629
This commit is contained in:
Andrew Kelley
2017-12-22 00:50:30 -05:00
parent 8bc523219c
commit d917815d81
114 changed files with 1203 additions and 1231 deletions

View File

@@ -32,7 +32,7 @@ fn getStderrStream() -> %&io.OutStream {
const st = &stderr_file_out_stream.stream;
stderr_stream = st;
return st;
};
}
}
/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
@@ -52,9 +52,9 @@ pub fn assert(ok: bool) {
// we insert an explicit call to @panic instead of unreachable.
// TODO we should use `assertOrPanic` in tests and remove this logic.
if (builtin.is_test) {
@panic("assertion failure")
@panic("assertion failure");
} else {
unreachable // assertion failure
unreachable; // assertion failure
}
}
}
@@ -175,7 +175,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
return_address, compile_unit_name);
},
else => return err,
};
}
}
},
builtin.ObjectFormat.coff => {
@@ -357,7 +357,7 @@ const Die = struct {
FormValue.String => |value| value,
FormValue.StrPtr => |offset| getString(st, offset),
else => error.InvalidDebugInfo,
}
};
}
};
@@ -403,7 +403,7 @@ const LineNumberProgram = struct {
pub fn init(is_stmt: bool, include_dirs: []const []const u8,
file_entries: &ArrayList(FileEntry), target_address: usize) -> LineNumberProgram
{
LineNumberProgram {
return LineNumberProgram {
.address = 0,
.file = 1,
.line = 1,
@@ -421,7 +421,7 @@ const LineNumberProgram = struct {
.prev_is_stmt = undefined,
.prev_basic_block = undefined,
.prev_end_sequence = undefined,
}
};
}
pub fn checkLineMatch(self: &LineNumberProgram) -> %?LineInfo {
@@ -430,14 +430,11 @@ const LineNumberProgram = struct {
return error.MissingDebugInfo;
} else if (self.prev_file - 1 >= self.file_entries.len) {
return error.InvalidDebugInfo;
} else {
&self.file_entries.items[self.prev_file - 1]
};
} else &self.file_entries.items[self.prev_file - 1];
const dir_name = if (file_entry.dir_index >= self.include_dirs.len) {
return error.InvalidDebugInfo;
} else {
self.include_dirs[file_entry.dir_index]
};
} else self.include_dirs[file_entry.dir_index];
const file_name = %return os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
%defer self.file_entries.allocator.free(file_name);
return LineInfo {
@@ -494,28 +491,21 @@ fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size:
}
fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue {
FormValue { .Const = Constant {
return FormValue { .Const = Constant {
.signed = signed,
.payload = %return readAllocBytes(allocator, in_stream, size),
}}
}};
}
fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 {
return if (is_64) {
%return in_stream.readIntLe(u64)
} else {
u64(%return in_stream.readIntLe(u32))
};
return if (is_64) %return in_stream.readIntLe(u64)
else u64(%return in_stream.readIntLe(u32)) ;
}
fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 {
return if (@sizeOf(usize) == 4) {
u64(%return in_stream.readIntLe(u32))
} else if (@sizeOf(usize) == 8) {
%return in_stream.readIntLe(u64)
} else {
unreachable;
};
return if (@sizeOf(usize) == 4) u64(%return in_stream.readIntLe(u32))
else if (@sizeOf(usize) == 8) %return in_stream.readIntLe(u64)
else unreachable;
}
fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
@@ -534,9 +524,9 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),
DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),
DW.FORM_block => {
DW.FORM_block => x: {
const block_len = %return readULeb128(in_stream);
parseFormValueBlockLen(allocator, in_stream, block_len)
return parseFormValueBlockLen(allocator, in_stream, block_len);
},
DW.FORM_data1 => parseFormValueConstant(allocator, in_stream, false, 1),
DW.FORM_data2 => parseFormValueConstant(allocator, in_stream, false, 2),
@@ -545,7 +535,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_udata, DW.FORM_sdata => {
const block_len = %return readULeb128(in_stream);
const signed = form_id == DW.FORM_sdata;
parseFormValueConstant(allocator, in_stream, signed, block_len)
return parseFormValueConstant(allocator, in_stream, signed, block_len);
},
DW.FORM_exprloc => {
const size = %return readULeb128(in_stream);
@@ -562,7 +552,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64),
DW.FORM_ref_udata => {
const ref_len = %return readULeb128(in_stream);
parseFormValueRefLen(allocator, in_stream, ref_len)
return parseFormValueRefLen(allocator, in_stream, ref_len);
},
DW.FORM_ref_addr => FormValue { .RefAddr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
@@ -572,10 +562,10 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_strp => FormValue { .StrPtr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
DW.FORM_indirect => {
const child_form_id = %return readULeb128(in_stream);
parseFormValue(allocator, in_stream, child_form_id, is_64)
return parseFormValue(allocator, in_stream, child_form_id, is_64);
},
else => error.InvalidDebugInfo,
}
};
}
fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {
@@ -852,11 +842,9 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
const version = %return in_stream.readInt(st.elf.endian, u16);
if (version < 2 or version > 5) return error.InvalidDebugInfo;
const debug_abbrev_offset = if (is_64) {
%return in_stream.readInt(st.elf.endian, u64)
} else {
%return in_stream.readInt(st.elf.endian, u32)
};
const debug_abbrev_offset =
if (is_64) %return in_stream.readInt(st.elf.endian, u64)
else %return in_stream.readInt(st.elf.endian, u32);
const address_size = %return in_stream.readByte();
if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
@@ -872,28 +860,28 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
if (compile_unit_die.tag_id != DW.TAG_compile_unit)
return error.InvalidDebugInfo;
const pc_range = {
const pc_range = x: {
if (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| {
if (compile_unit_die.getAttr(DW.AT_high_pc)) |high_pc_value| {
const pc_end = switch (*high_pc_value) {
FormValue.Address => |value| value,
FormValue.Const => |value| {
FormValue.Const => |value| b: {
const offset = %return value.asUnsignedLe();
low_pc + offset
break :b (low_pc + offset);
},
else => return error.InvalidDebugInfo,
};
PcRange {
break :x PcRange {
.start = low_pc,
.end = pc_end,
}
};
} else {
null
break :x null;
}
} else |err| {
if (err != error.MissingDebugInfo)
return err;
null
break :x null;
}
};
@@ -949,12 +937,12 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn
fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {
const first_32_bits = %return in_stream.readIntLe(u32);
*is_64 = (first_32_bits == 0xffffffff);
return if (*is_64) {
%return in_stream.readIntLe(u64)
if (*is_64) {
return in_stream.readIntLe(u64);
} else {
if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
u64(first_32_bits)
};
return u64(first_32_bits);
}
}
fn readULeb128(in_stream: &io.InStream) -> %u64 {