Skip to content

Commit a665872

Browse files
committed
add compile error for ignoring return value
also introduce the _ identifier which you can assign to to discard a return value closes #219
1 parent 3b40aaa commit a665872

File tree

10 files changed

+102
-53
lines changed

10 files changed

+102
-53
lines changed

src/all_types.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ enum ConstPtrSpecial {
117117
// emit a binary with a compile time known address.
118118
// In this case index is the numeric address value.
119119
ConstPtrSpecialHardCodedAddr,
120+
// This means that the pointer represents memory of assigning to _.
121+
// That is, storing discards the data, and loading is invalid.
122+
ConstPtrSpecialDiscard,
120123
};
121124

122125
enum ConstPtrMut {

src/analyze.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3091,6 +3091,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
30913091
hash_val += 4048518294;
30923092
hash_val += hash_size(const_val->data.x_ptr.data.hard_coded_addr.addr);
30933093
return hash_val;
3094+
case ConstPtrSpecialDiscard:
3095+
hash_val += 2010123162;
3096+
return hash_val;
30943097
}
30953098
zig_unreachable();
30963099
}
@@ -3601,6 +3604,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
36013604
if (a->data.x_ptr.data.hard_coded_addr.addr != b->data.x_ptr.data.hard_coded_addr.addr)
36023605
return false;
36033606
return true;
3607+
case ConstPtrSpecialDiscard:
3608+
return true;
36043609
}
36053610
zig_unreachable();
36063611
case TypeTableEntryIdArray:
@@ -3785,6 +3790,9 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
37853790
buf_appendf(buf, "(&%s)(%" PRIx64 ")", buf_ptr(&canon_type->data.pointer.child_type->name),
37863791
const_val->data.x_ptr.data.hard_coded_addr.addr);
37873792
return;
3793+
case ConstPtrSpecialDiscard:
3794+
buf_append_str(buf, "&_");
3795+
return;
37883796
}
37893797
zig_unreachable();
37903798
case TypeTableEntryIdFn:

src/codegen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2928,6 +2928,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
29282928
render_const_val_global(g, const_val, "");
29292929
switch (const_val->data.x_ptr.special) {
29302930
case ConstPtrSpecialInvalid:
2931+
case ConstPtrSpecialDiscard:
29312932
zig_unreachable();
29322933
case ConstPtrSpecialRef:
29332934
{

src/ir.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {
7777
const_val->data.x_ptr.data.base_struct.field_index];
7878
case ConstPtrSpecialHardCodedAddr:
7979
zig_unreachable();
80+
case ConstPtrSpecialDiscard:
81+
zig_unreachable();
8082
}
8183
zig_unreachable();
8284
}
@@ -3656,6 +3658,15 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
36563658

36573659
Buf *variable_name = node->data.symbol_expr.symbol;
36583660

3661+
if (buf_eql_str(variable_name, "_") && lval.is_ptr) {
3662+
IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);
3663+
const_instruction->base.value.type = get_pointer_to_type(irb->codegen,
3664+
irb->codegen->builtin_types.entry_void, false);
3665+
const_instruction->base.value.special = ConstValSpecialStatic;
3666+
const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard;
3667+
return &const_instruction->base;
3668+
}
3669+
36593670
auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
36603671
if (primitive_table_entry) {
36613672
IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value);
@@ -8927,6 +8938,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
89278938
size_t old_size;
89288939
switch (array_ptr_val->data.x_ptr.special) {
89298940
case ConstPtrSpecialInvalid:
8941+
case ConstPtrSpecialDiscard:
89308942
zig_unreachable();
89318943
case ConstPtrSpecialRef:
89328944
mem_size = 1;
@@ -8977,6 +8989,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
89778989
out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut;
89788990
switch (ptr_field->data.x_ptr.special) {
89798991
case ConstPtrSpecialInvalid:
8992+
case ConstPtrSpecialDiscard:
89808993
zig_unreachable();
89818994
case ConstPtrSpecialRef:
89828995
out_val->data.x_ptr.special = ConstPtrSpecialRef;
@@ -9384,6 +9397,10 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru
93849397
return value->value.type;
93859398

93869399
assert(ptr->value.type->id == TypeTableEntryIdPointer);
9400+
if (ptr->value.data.x_ptr.special == ConstPtrSpecialDiscard) {
9401+
return ir_analyze_void(ira, &store_ptr_instruction->base);
9402+
}
9403+
93879404
if (ptr->value.type->data.pointer.is_const && !store_ptr_instruction->base.is_gen) {
93889405
ir_add_error(ira, &store_ptr_instruction->base, buf_sprintf("cannot assign to constant"));
93899406
return ira->codegen->builtin_types.entry_invalid;
@@ -11365,6 +11382,7 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi
1136511382
size_t bound_end;
1136611383
switch (dest_ptr_val->data.x_ptr.special) {
1136711384
case ConstPtrSpecialInvalid:
11385+
case ConstPtrSpecialDiscard:
1136811386
zig_unreachable();
1136911387
case ConstPtrSpecialRef:
1137011388
dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee;
@@ -11455,6 +11473,7 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
1145511473
size_t dest_end;
1145611474
switch (dest_ptr_val->data.x_ptr.special) {
1145711475
case ConstPtrSpecialInvalid:
11476+
case ConstPtrSpecialDiscard:
1145811477
zig_unreachable();
1145911478
case ConstPtrSpecialRef:
1146011479
dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee;
@@ -11487,6 +11506,7 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
1148711506

1148811507
switch (src_ptr_val->data.x_ptr.special) {
1148911508
case ConstPtrSpecialInvalid:
11509+
case ConstPtrSpecialDiscard:
1149011510
zig_unreachable();
1149111511
case ConstPtrSpecialRef:
1149211512
src_elements = src_ptr_val->data.x_ptr.data.ref.pointee;
@@ -11595,6 +11615,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1159511615
parent_ptr = const_ptr_pointee(&ptr_ptr->value);
1159611616
switch (parent_ptr->data.x_ptr.special) {
1159711617
case ConstPtrSpecialInvalid:
11618+
case ConstPtrSpecialDiscard:
1159811619
zig_unreachable();
1159911620
case ConstPtrSpecialRef:
1160011621
array_val = nullptr;
@@ -11619,6 +11640,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1161911640

1162011641
switch (parent_ptr->data.x_ptr.special) {
1162111642
case ConstPtrSpecialInvalid:
11643+
case ConstPtrSpecialDiscard:
1162211644
zig_unreachable();
1162311645
case ConstPtrSpecialRef:
1162411646
array_val = nullptr;
@@ -11676,6 +11698,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1167611698
} else {
1167711699
switch (parent_ptr->data.x_ptr.special) {
1167811700
case ConstPtrSpecialInvalid:
11701+
case ConstPtrSpecialDiscard:
1167911702
zig_unreachable();
1168011703
case ConstPtrSpecialRef:
1168111704
init_const_ptr_ref(ira->codegen, ptr_val,
@@ -12302,6 +12325,14 @@ static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *ins
1230212325
instruction_type->id == TypeTableEntryIdUnreachable);
1230312326
instruction->other = instruction;
1230412327
}
12328+
if (instruction_type->id != TypeTableEntryIdInvalid &&
12329+
instruction_type->id != TypeTableEntryIdVoid &&
12330+
instruction_type->id != TypeTableEntryIdUnreachable &&
12331+
instruction->ref_count == 0)
12332+
{
12333+
ir_add_error(ira, instruction, buf_sprintf("return value ignored"));
12334+
}
12335+
1230512336
return instruction_type;
1230612337
}
1230712338

std/compiler_rt.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ export fn __umoddi3(a: du_int, b: du_int) -> du_int {
218218
@setDebugSafety(this, false);
219219

220220
var r: du_int = undefined;
221-
__udivmoddi4(a, b, &r);
221+
_ = __udivmoddi4(a, b, &r);
222222
return r;
223223
}
224224

std/io.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ pub const OutStream = struct {
170170
},
171171
State.Integer => switch (c) {
172172
'}' => {
173-
self.printInt(args[next_arg], radix, uppercase, width);
173+
%return self.printInt(args[next_arg], radix, uppercase, width);
174174
next_arg += 1;
175175
state = State.Start;
176176
start_index = i + 1;
@@ -184,7 +184,7 @@ pub const OutStream = struct {
184184
State.IntegerWidth => switch (c) {
185185
'}' => {
186186
width = comptime %%parseUnsigned(usize, format[width_start...i], 10);
187-
self.printInt(args[next_arg], radix, uppercase, width);
187+
%return self.printInt(args[next_arg], radix, uppercase, width);
188188
next_arg += 1;
189189
state = State.Start;
190190
start_index = i + 1;
@@ -194,7 +194,7 @@ pub const OutStream = struct {
194194
},
195195
State.Character => switch (c) {
196196
'}' => {
197-
self.printAsciiChar(args[next_arg]);
197+
%return self.printAsciiChar(args[next_arg]);
198198
next_arg += 1;
199199
state = State.Start;
200200
start_index = i + 1;

std/linux.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize {
298298
}
299299

300300
pub fn exit(status: i32) -> unreachable {
301-
arch.syscall1(arch.SYS_exit, usize(status));
301+
_ = arch.syscall1(arch.SYS_exit, usize(status));
302302
@unreachable()
303303
}
304304

@@ -325,15 +325,15 @@ pub fn raise(sig: i32) -> i32 {
325325
}
326326

327327
fn blockAllSignals(set: &sigset_t) {
328-
arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, usize(&all_mask), usize(set), NSIG/8);
328+
_ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, usize(&all_mask), usize(set), NSIG/8);
329329
}
330330

331331
fn blockAppSignals(set: &sigset_t) {
332-
arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, usize(&app_mask), usize(set), NSIG/8);
332+
_ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, usize(&app_mask), usize(set), NSIG/8);
333333
}
334334

335335
fn restoreSignals(set: &sigset_t) {
336-
arch.syscall4(arch.SYS_rt_sigprocmask, SIG_SETMASK, usize(set), 0, NSIG/8);
336+
_ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_SETMASK, usize(set), 0, NSIG/8);
337337
}
338338

339339

@@ -432,8 +432,8 @@ pub fn shutdown(fd: i32, how: i32) -> usize {
432432
arch.syscall2(arch.SYS_shutdown, usize(fd), usize(how))
433433
}
434434

435-
pub fn bind(fd: i32, addr: &const sockaddr, len: socklen_t) {
436-
arch.syscall3(arch.SYS_bind, usize(fd), usize(addr), usize(len));
435+
pub fn bind(fd: i32, addr: &const sockaddr, len: socklen_t) -> usize {
436+
arch.syscall3(arch.SYS_bind, usize(fd), usize(addr), usize(len))
437437
}
438438

439439
pub fn listen(fd: i32, backlog: i32) -> usize {

std/os.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ pub fn getRandomBytes(buf: []u8) -> %void {
3030
pub coldcc fn abort() -> unreachable {
3131
switch (@compileVar("os")) {
3232
Os.linux, Os.darwin => {
33-
system.raise(system.SIGABRT);
34-
system.raise(system.SIGKILL);
33+
_ = system.raise(system.SIGABRT);
34+
_ = system.raise(system.SIGKILL);
3535
while (true) {}
3636
},
3737
else => @compileError("unsupported os"),

test/cases/struct.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ const EmptyStruct = struct {
193193
fn returnEmptyStructFromFn() {
194194
@setFnTest(this);
195195

196-
testReturnEmptyStructFromFn();
196+
_ = testReturnEmptyStructFromFn();
197197
}
198198
const EmptyStruct2 = struct {};
199199
fn testReturnEmptyStructFromFn() -> EmptyStruct2 {

0 commit comments

Comments
 (0)