authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-08 22:25:38-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-08 22:25:38-05:00
log6caf32195af7aab084f3f2fee37239de0eb67adb
treee9d8fb542726bbf503b01627c1841181f93610c4
parent76d0e49e612d661b57b795cd81f5ba06dc26ceca

pass unnecessary if statement test


9 files changed, 181 insertions(+), 54 deletions(-)

doc/langref.md+16-3
......@@ -540,9 +540,9 @@ variables:
540540 * "is_big_endian" `bool` - either `true` for big endian or `false` for little endian.
541541 * "is_release" `bool`- either `true` for release mode builds or `false` for debug mode builds.
542542 * "is_test" `bool`- either `true` for test builds or `false` otherwise.
543 * "os" `@OS` - use `zig targets` to see what enum values are possible here.
544 * "arch" `@Arch` - use `zig targets` to see what enum values are possible here.
545 * "environ" `@Environ` - use `zig targets` to see what enum values are possible here.
543 * "os" `Os` - use `zig targets` to see what enum values are possible here.
544 * "arch" `Arch` - use `zig targets` to see what enum values are possible here.
545 * "environ" `Environ` - use `zig targets` to see what enum values are possible here.
546546
547547Build scripts can set additional compile variables of any name and type.
548548
......@@ -556,6 +556,18 @@ expression is not known at compile time.
556556
557557The result of the function is the result of the expression.
558558
559### @generatedCode(expression) -> @typeOf(expression)
560
561This function wraps an expression and returns the result of the expression
562unmodified.
563
564Inside the expression, code is considered generated, which means that the
565following compile errors are disabled:
566
567 * unnecessary if statement error
568
569The result of the expression is marked as depending on a compile variable.
570
559571### @ctz(x: T) -> T
560572
561573This function counts the number of trailing zeroes in x which is an integer
......@@ -638,3 +650,4 @@ This function returns an integer type with the given signness and bit count.
638650### @setFnTest(func)
639651
640652Makes the target function a test function.
653
src/all_types.hpp+9
......@@ -942,6 +942,7 @@ struct TypeTableEntry {
942942 ZigLLVMDIType *di_type;
943943
944944 bool zero_bits;
945 bool size_depends_on_compile_var;
945946
946947 union {
947948 TypeTableEntryPointer pointer;
......@@ -1053,6 +1054,7 @@ enum BuiltinFnId {
10531054 BuiltinFnIdCompileVar,
10541055 BuiltinFnIdCompileErr,
10551056 BuiltinFnIdStaticEval,
1057 BuiltinFnIdGeneratedCode,
10561058 BuiltinFnIdCtz,
10571059 BuiltinFnIdClz,
10581060 BuiltinFnIdImport,
......@@ -1440,6 +1442,7 @@ enum IrInstructionId {
14401442 IrInstructionIdClz,
14411443 IrInstructionIdCtz,
14421444 IrInstructionIdStaticEval,
1445 IrInstructionIdGeneratedCode,
14431446 IrInstructionIdImport,
14441447 IrInstructionIdCImport,
14451448 IrInstructionIdCInclude,
......@@ -1856,6 +1859,12 @@ struct IrInstructionStaticEval {
18561859 IrInstruction *value;
18571860};
18581861
1862struct IrInstructionGeneratedCode {
1863 IrInstruction base;
1864
1865 IrInstruction *value;
1866};
1867
18591868struct IrInstructionImport {
18601869 IrInstruction base;
18611870
src/analyze.cpp+6
......@@ -1148,6 +1148,9 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
11481148 continue;
11491149 }
11501150
1151 enum_type->size_depends_on_compile_var = enum_type->size_depends_on_compile_var ||
1152 field_type->size_depends_on_compile_var;
1153
11511154 if (!type_has_bits(field_type))
11521155 continue;
11531156
......@@ -1316,6 +1319,9 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
13161319 continue;
13171320 }
13181321
1322 struct_type->size_depends_on_compile_var = struct_type->size_depends_on_compile_var ||
1323 field_type->size_depends_on_compile_var;
1324
13191325 if (!type_has_bits(field_type))
13201326 continue;
13211327
src/codegen.cpp+5
......@@ -2273,6 +2273,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
22732273 case IrInstructionIdAlignOf:
22742274 case IrInstructionIdFnProto:
22752275 case IrInstructionIdTestComptime:
2276 case IrInstructionIdGeneratedCode:
22762277 zig_unreachable();
22772278 case IrInstructionIdReturn:
22782279 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -3201,6 +3202,7 @@ static void define_builtin_types(CodeGen *g) {
32013202 bool is_signed = info->is_signed;
32023203
32033204 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3205 entry->size_depends_on_compile_var = true;
32043206 entry->type_ref = LLVMIntType(size_in_bits);
32053207
32063208 buf_init_from_str(&entry->name, info->name);
......@@ -3237,6 +3239,7 @@ static void define_builtin_types(CodeGen *g) {
32373239
32383240 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
32393241 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
3242 entry->size_depends_on_compile_var = true;
32403243
32413244 const char u_or_i = is_signed ? 'i' : 'u';
32423245 buf_resize(&entry->name, 0);
......@@ -3292,6 +3295,7 @@ static void define_builtin_types(CodeGen *g) {
32923295 {
32933296 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
32943297 entry->type_ref = LLVMX86FP80Type();
3298 entry->size_depends_on_compile_var = true;
32953299 buf_init_from_str(&entry->name, "c_long_double");
32963300 entry->data.floating.bit_count = 80;
32973301
......@@ -3613,6 +3617,7 @@ static void define_builtin_fns(CodeGen *g) {
36133617 create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1);
36143618 create_builtin_fn(g, BuiltinFnIdCompileVar, "compileVar", 1);
36153619 create_builtin_fn(g, BuiltinFnIdStaticEval, "staticEval", 1);
3620 create_builtin_fn(g, BuiltinFnIdGeneratedCode, "generatedCode", 1);
36163621 create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1);
36173622 create_builtin_fn(g, BuiltinFnIdClz, "clz", 1);
36183623 create_builtin_fn(g, BuiltinFnIdImport, "import", 1);
src/ir.cpp+110-31
......@@ -307,6 +307,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) {
307307 return IrInstructionIdStaticEval;
308308}
309309
310static constexpr IrInstructionId ir_instruction_id(IrInstructionGeneratedCode *) {
311 return IrInstructionIdGeneratedCode;
312}
313
310314static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) {
311315 return IrInstructionIdImport;
312316}
......@@ -616,19 +620,20 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode
616620}
617621
618622static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
619 TypeTableEntry *type_entry)
623 TypeTableEntry *type_entry, bool depends_on_compile_var)
620624{
621625 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node);
622626 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type;
623627 const_instruction->base.value.special = ConstValSpecialStatic;
628 const_instruction->base.value.depends_on_compile_var = depends_on_compile_var;
624629 const_instruction->base.value.data.x_type = type_entry;
625630 return &const_instruction->base;
626631}
627632
628633static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
629 TypeTableEntry *type_entry)
634 TypeTableEntry *type_entry, bool depends_on_compile_var)
630635{
631 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry);
636 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry, depends_on_compile_var);
632637 ir_instruction_append(irb->current_basic_block, instruction);
633638 return instruction;
634639}
......@@ -1392,6 +1397,17 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, Scope *scope, AstNode
13921397 return &instruction->base;
13931398}
13941399
1400static IrInstruction *ir_build_generated_code(IrBuilder *irb, Scope *scope, AstNode *source_node,
1401 IrInstruction *value)
1402{
1403 IrInstructionGeneratedCode *instruction = ir_build_instruction<IrInstructionGeneratedCode>(irb, scope, source_node);
1404 instruction->value = value;
1405
1406 ir_ref_instruction(value, irb->current_basic_block);
1407
1408 return &instruction->base;
1409}
1410
13951411static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) {
13961412 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node);
13971413 instruction->name = name;
......@@ -2258,6 +2274,13 @@ static IrInstruction *ir_instruction_staticeval_get_dep(IrInstructionStaticEval
22582274 }
22592275}
22602276
2277static IrInstruction *ir_instruction_generatedcode_get_dep(IrInstructionGeneratedCode *instruction, size_t index) {
2278 switch (index) {
2279 case 0: return instruction->value;
2280 default: return nullptr;
2281 }
2282}
2283
22612284static IrInstruction *ir_instruction_import_get_dep(IrInstructionImport *instruction, size_t index) {
22622285 switch (index) {
22632286 case 0: return instruction->name;
......@@ -2645,6 +2668,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
26452668 return ir_instruction_ctz_get_dep((IrInstructionCtz *) instruction, index);
26462669 case IrInstructionIdStaticEval:
26472670 return ir_instruction_staticeval_get_dep((IrInstructionStaticEval *) instruction, index);
2671 case IrInstructionIdGeneratedCode:
2672 return ir_instruction_generatedcode_get_dep((IrInstructionGeneratedCode *) instruction, index);
26482673 case IrInstructionIdImport:
26492674 return ir_instruction_import_get_dep((IrInstructionImport *) instruction, index);
26502675 case IrInstructionIdCImport:
......@@ -2846,7 +2871,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
28462871 is_comptime = ir_build_test_comptime(irb, scope, node, is_err);
28472872 }
28482873
2849 ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime);
2874 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime));
28502875
28512876 ir_set_cursor_at_end(irb, err_block);
28522877 ir_gen_defers_for_block(irb, scope, outer_scope, true, false);
......@@ -2868,7 +2893,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
28682893 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null);
28692894 }
28702895
2871 ir_build_cond_br(irb, scope, node, is_non_null, ok_block, null_block, is_comptime);
2896 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_non_null, ok_block, null_block, is_comptime));
28722897
28732898 ir_set_cursor_at_end(irb, null_block);
28742899 ir_gen_defers_for_block(irb, scope, outer_scope, false, true);
......@@ -2895,7 +2920,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
28952920 IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "ErrRetReturn");
28962921 IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "ErrRetContinue");
28972922 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb));
2898 ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime);
2923 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime));
28992924
29002925 ir_set_cursor_at_end(irb, return_block);
29012926 ir_gen_defers_for_block(irb, scope, outer_scope, true, false);
......@@ -2921,7 +2946,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
29212946 IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "MaybeRetReturn");
29222947 IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "MaybeRetContinue");
29232948 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb));
2924 ir_build_cond_br(irb, scope, node, is_non_null, continue_block, return_block, is_comptime);
2949 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_non_null, continue_block, return_block, is_comptime));
29252950
29262951 ir_set_cursor_at_end(irb, return_block);
29272952 ir_gen_defers_for_block(irb, scope, outer_scope, false, true);
......@@ -3388,7 +3413,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode
33883413static IrInstruction *ir_gen_var_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
33893414 assert(node->type == NodeTypeVarLiteral);
33903415
3391 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var);
3416 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var, false);
33923417}
33933418
33943419static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld *tld,
......@@ -3426,7 +3451,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld
34263451 {
34273452 TldTypeDef *tld_typedef = (TldTypeDef *)tld;
34283453 TypeTableEntry *typedef_type = tld_typedef->type_entry;
3429 IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, typedef_type);
3454 IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, typedef_type, false);
34303455 if (lval != LValPurposeNone)
34313456 return ir_build_ref(irb, scope, source_node, ref_instruction, true);
34323457 else
......@@ -3443,7 +3468,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
34433468
34443469 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
34453470 if (primitive_table_entry) {
3446 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value);
3471 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value, false);
34473472 if (lval != LValPurposeNone) {
34483473 return ir_build_ref(irb, scope, node, value, lval == LValPurposeAddressOfConst);
34493474 } else {
......@@ -3664,6 +3689,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36643689
36653690 return ir_build_static_eval(irb, scope, node, arg0_value);
36663691 }
3692 case BuiltinFnIdGeneratedCode:
3693 {
3694 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
3695 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
3696 if (arg0_value == irb->codegen->invalid_instruction)
3697 return arg0_value;
3698
3699 return ir_build_generated_code(irb, scope, node, arg0_value);
3700 }
36673701 case BuiltinFnIdImport:
36683702 {
36693703 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4327,7 +4361,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
43274361 }
43284362 child_scope = index_var->child_scope;
43294363
4330 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize);
4364 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize, false);
43314365 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);
43324366 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);
43334367 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero);
......@@ -4345,7 +4379,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
43454379 ir_set_cursor_at_end(irb, cond_block);
43464380 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr);
43474381 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
4348 ir_build_cond_br(irb, child_scope, node, cond, body_block, end_block, is_comptime);
4382 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, end_block, is_comptime));
43494383
43504384 ir_set_cursor_at_end(irb, body_block);
43514385 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false);
......@@ -4391,7 +4425,7 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode
43914425 ScopeDecls *decls_scope = (ScopeDecls *)scope;
43924426 TypeTableEntry *container_type = decls_scope->container_type;
43934427 assert(container_type);
4394 return ir_build_const_type(irb, scope, node, container_type);
4428 return ir_build_const_type(irb, scope, node, container_type, false);
43954429 }
43964430
43974431 if (scope->id == ScopeIdBlock)
......@@ -4719,7 +4753,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
47194753
47204754 assert(ok_bit);
47214755 assert(last_item_node);
4722 ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, range_block_no, is_comptime);
4756 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes,
4757 range_block_no, is_comptime));
47234758
47244759 ir_set_cursor_at_end(irb, range_block_yes);
47254760 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
......@@ -4843,12 +4878,12 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod
48434878
48444879static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
48454880 assert(node->type == NodeTypeTypeLiteral);
4846 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type);
4881 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type, false);
48474882}
48484883
48494884static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) {
48504885 assert(node->type == NodeTypeErrorType);
4851 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_pure_error);
4886 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_pure_error, false);
48524887}
48534888
48544889static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
......@@ -4922,7 +4957,7 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
49224957 if (var_node) {
49234958 assert(var_node->type == NodeTypeSymbol);
49244959 IrInstruction *var_type = ir_build_const_type(irb, parent_scope, node,
4925 irb->codegen->builtin_types.entry_pure_error);
4960 irb->codegen->builtin_types.entry_pure_error, false);
49264961 Buf *var_name = var_node->data.symbol_expr.symbol;
49274962 bool is_const = true;
49284963 bool is_shadowable = false;
......@@ -5008,7 +5043,7 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,
50085043 }
50095044 irb->codegen->resolve_queue.append(&tld_container->base);
50105045
5011 return ir_build_const_type(irb, parent_scope, node, container_type);
5046 return ir_build_const_type(irb, parent_scope, node, container_type, false);
50125047}
50135048
50145049static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
......@@ -6530,8 +6565,10 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
65306565 ConstExprValue *pointee = const_ptr_pointee(&ptr->value);
65316566 if (pointee->special != ConstValSpecialRuntime) {
65326567 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,
6533 source_instruction->source_node, child_type, pointee->depends_on_compile_var);
6568 source_instruction->source_node, child_type, false);
65346569 result->value = *pointee;
6570 result->value.depends_on_compile_var = pointee->depends_on_compile_var ||
6571 ptr->value.depends_on_compile_var;
65356572 return result;
65366573 }
65376574 }
......@@ -6547,7 +6584,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
65476584 TypeTableEntry *ptr_type = ptr_val->data.x_type;
65486585 if (ptr_type->id == TypeTableEntryIdPointer) {
65496586 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
6550 return ir_create_const_type(&ira->new_irb, source_instruction->scope, source_instruction->source_node, child_type);
6587 return ir_create_const_type(&ira->new_irb, source_instruction->scope,
6588 source_instruction->source_node, child_type, ptr_val->depends_on_compile_var);
65516589 } else {
65526590 ir_add_error(ira, source_instruction,
65536591 buf_sprintf("attempt to dereference non pointer type '%s'", buf_ptr(&ptr_type->name)));
......@@ -6572,7 +6610,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst
65726610 if (!val)
65736611 return ira->codegen->builtin_types.entry_invalid;
65746612 return ir_analyze_const_ptr(ira, source_instruction, val, value->value.type,
6575 false, ConstPtrSpecialNone, is_const);
6613 value->value.depends_on_compile_var, ConstPtrSpecialNone, is_const);
65766614 }
65776615
65786616 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->value.type, true);
......@@ -7367,6 +7405,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
73677405 Buf *param_name = param_decl_node->data.param_decl.name;
73687406 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,
73697407 *exec_scope, param_name, true, arg_val);
7408 var->value.depends_on_compile_var = true;
73707409 *exec_scope = var->child_scope;
73717410 *next_proto_i += 1;
73727411
......@@ -7408,6 +7447,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
74087447 Buf *param_name = param_decl_node->data.param_decl.name;
74097448 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,
74107449 *child_scope, param_name, true, arg_val);
7450 var->value.depends_on_compile_var = true;
74117451 *child_scope = var->child_scope;
74127452
74137453 if (inline_arg || is_var_type) {
......@@ -7986,6 +8026,14 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct
79868026 if (!ir_resolve_bool(ira, condition, &cond_is_true))
79878027 return ir_unreach_error(ira);
79888028
8029 if (!cond_br_instruction->base.is_gen && !condition->value.depends_on_compile_var &&
8030 !ir_should_inline(&ira->new_irb))
8031 {
8032 const char *true_or_false = cond_is_true ? "true" : "false";
8033 ir_add_error(ira, &cond_br_instruction->base,
8034 buf_sprintf("condition is always %s; unnecessary if statement", true_or_false));
8035 }
8036
79898037 IrBasicBlock *old_dest_block = cond_is_true ?
79908038 cond_br_instruction->then_block : cond_br_instruction->else_block;
79918039
......@@ -8028,9 +8076,9 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
80288076 return ira->codegen->builtin_types.entry_invalid;
80298077
80308078 if (value->value.special != ConstValSpecialRuntime) {
8031 ConstExprValue *out_val = ir_build_const_from(ira, &phi_instruction->base,
8032 value->value.depends_on_compile_var);
8079 ConstExprValue *out_val = ir_build_const_from(ira, &phi_instruction->base, true);
80338080 *out_val = value->value;
8081 out_val->depends_on_compile_var = true;
80348082 } else {
80358083 phi_instruction->base.other = value;
80368084 }
......@@ -8064,7 +8112,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
80648112 }
80658113
80668114 if (new_incoming_blocks.length == 0) {
8067 ir_build_const_from(ira, &phi_instruction->base, false);
8115 ir_build_const_from(ira, &phi_instruction->base, true);
80688116 return ira->codegen->builtin_types.entry_void;
80698117 }
80708118
......@@ -8080,7 +8128,9 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
80808128 return resolved_type;
80818129
80828130 if (resolved_type->id == TypeTableEntryIdNumLitFloat ||
8083 resolved_type->id == TypeTableEntryIdNumLitInt)
8131 resolved_type->id == TypeTableEntryIdNumLitInt ||
8132 resolved_type->id == TypeTableEntryIdNullLit ||
8133 resolved_type->id == TypeTableEntryIdUndefLit)
80848134 {
80858135 ir_add_error_node(ira, phi_instruction->base.source_node,
80868136 buf_sprintf("unable to infer expression type"));
......@@ -8109,7 +8159,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
81098159}
81108160
81118161static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
8112 VariableTableEntry *var, bool is_const_ptr)
8162 VariableTableEntry *var, bool is_const_ptr, bool depends_on_compile_var)
81138163{
81148164 assert(var->value.type);
81158165 if (var->value.type->id == TypeTableEntryIdInvalid)
......@@ -8131,7 +8181,8 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
81318181 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
81328182 ConstPtrSpecial ptr_special = is_comptime ? ConstPtrSpecialInline : ConstPtrSpecialNone;
81338183 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
8134 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type, false, ptr_special, is_const);
8184 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type,
8185 mem_slot->depends_on_compile_var || depends_on_compile_var, ptr_special, is_const);
81358186 } else {
81368187 ir_build_var_ptr_from(&ira->new_irb, instruction, var, false);
81378188 type_ensure_zero_bits_known(ira->codegen, var->value.type);
......@@ -8141,7 +8192,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
81418192
81428193static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {
81438194 VariableTableEntry *var = var_ptr_instruction->var;
8144 return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var, var_ptr_instruction->is_const);
8195 return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var, var_ptr_instruction->is_const, false);
81458196}
81468197
81478198static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {
......@@ -8295,6 +8346,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
82958346 ensure_complete_type(ira->codegen, bare_type);
82968347
82978348 if (bare_type->id == TypeTableEntryIdStruct) {
8349 if (bare_type->data.structure.is_invalid)
8350 return ira->codegen->builtin_types.entry_invalid;
8351
82988352 TypeStructField *field = find_struct_type_field(bare_type, field_name);
82998353 if (field) {
83008354 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
......@@ -8304,6 +8358,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
83048358 field_ptr_instruction, container_ptr, container_type);
83058359 }
83068360 } else if (bare_type->id == TypeTableEntryIdEnum) {
8361 if (bare_type->data.enumeration.is_invalid)
8362 return ira->codegen->builtin_types.entry_invalid;
8363
83078364 TypeEnumField *field = find_enum_type_field(bare_type, field_name);
83088365 if (field) {
83098366 ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
......@@ -8334,7 +8391,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
83348391 {
83358392 TldVar *tld_var = (TldVar *)tld;
83368393 VariableTableEntry *var = tld_var->var;
8337 return ir_analyze_var_ptr(ira, source_instruction, var, false);
8394 return ir_analyze_var_ptr(ira, source_instruction, var, false, depends_on_compile_var);
83388395 }
83398396 case TldIdFn:
83408397 {
......@@ -9065,9 +9122,8 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
90659122 case TypeTableEntryIdEnumTag:
90669123 {
90679124 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
9068 bool depends_on_compile_var = false; // TODO types should be able to depend on compile var
90699125 ConstExprValue *out_val = ir_build_const_from(ira, &size_of_instruction->base,
9070 depends_on_compile_var);
9126 type_entry->size_depends_on_compile_var);
90719127 bignum_init_unsigned(&out_val->data.x_bignum, size_in_bytes);
90729128 return ira->codegen->builtin_types.entry_num_lit_int;
90739129 }
......@@ -9463,6 +9519,26 @@ static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira,
94639519 return value->value.type;
94649520}
94659521
9522static TypeTableEntry *ir_analyze_instruction_generated_code(IrAnalyze *ira, IrInstructionGeneratedCode *instruction) {
9523 IrInstruction *value = instruction->value->other;
9524 if (value->value.type->id == TypeTableEntryIdInvalid)
9525 return ira->codegen->builtin_types.entry_invalid;
9526
9527 if (instr_is_comptime(value)) {
9528 ConstExprValue *val = ir_resolve_const(ira, value, UndefOk);
9529 if (!val)
9530 return ira->codegen->builtin_types.entry_invalid;
9531
9532 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, false);
9533 *out_val = *val;
9534 out_val->depends_on_compile_var = true;
9535 return value->value.type;
9536 }
9537
9538 instruction->base.other = value;
9539 return value->value.type;
9540}
9541
94669542static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) {
94679543 IrInstruction *name_value = import_instruction->name->other;
94689544 Buf *import_target_str = ir_resolve_str(ira, name_value);
......@@ -11078,6 +11154,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1107811154 return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction);
1107911155 case IrInstructionIdStaticEval:
1108011156 return ir_analyze_instruction_static_eval(ira, (IrInstructionStaticEval *)instruction);
11157 case IrInstructionIdGeneratedCode:
11158 return ir_analyze_instruction_generated_code(ira, (IrInstructionGeneratedCode *)instruction);
1108111159 case IrInstructionIdImport:
1108211160 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction);
1108311161 case IrInstructionIdArrayLen:
......@@ -11284,6 +11362,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1128411362 case IrInstructionIdSwitchTarget:
1128511363 case IrInstructionIdEnumTag:
1128611364 case IrInstructionIdStaticEval:
11365 case IrInstructionIdGeneratedCode:
1128711366 case IrInstructionIdRef:
1128811367 case IrInstructionIdMinValue:
1128911368 case IrInstructionIdMaxValue:
src/ir_print.cpp+9
......@@ -492,6 +492,12 @@ static void ir_print_static_eval(IrPrint *irp, IrInstructionStaticEval *instruct
492492 fprintf(irp->f, ")");
493493}
494494
495static void ir_print_generated_code(IrPrint *irp, IrInstructionGeneratedCode *instruction) {
496 fprintf(irp->f, "@generatedCode(");
497 ir_print_other_instruction(irp, instruction->value);
498 fprintf(irp->f, ")");
499}
500
495501static void ir_print_import(IrPrint *irp, IrInstructionImport *instruction) {
496502 fprintf(irp->f, "@import(");
497503 ir_print_other_instruction(irp, instruction->name);
......@@ -921,6 +927,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
921927 case IrInstructionIdStaticEval:
922928 ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);
923929 break;
930 case IrInstructionIdGeneratedCode:
931 ir_print_generated_code(irp, (IrInstructionGeneratedCode *)instruction);
932 break;
924933 case IrInstructionIdImport:
925934 ir_print_import(irp, (IrInstructionImport *)instruction);
926935 break;
test/cases/math.zig+6-3
......@@ -72,9 +72,11 @@ fn modifyOperators() {
7272
7373fn threeExprInARow() {
7474 @setFnTest(this);
75
76 assertFalse(false || false || false);
77 assertFalse(true && true && false);
75 testThreeExprInARow(false, true);
76}
77fn testThreeExprInARow(f: bool, t: bool) {
78 assertFalse(f || f || f);
79 assertFalse(t && t && f);
7880 assertFalse(1 | 2 | 4 != 7);
7981 assertFalse(3 ^ 6 ^ 8 != 13);
8082 assertFalse(7 & 14 & 28 != 4);
......@@ -86,6 +88,7 @@ fn threeExprInARow() {
8688 assertFalse(!!false);
8789 assertFalse(i32(7) != --(i32(7)));
8890}
91
8992fn assertFalse(b: bool) {
9093 assert(!b);
9194}
test/cases/misc.zig+16-13
......@@ -86,26 +86,29 @@ fn maxValueType() {
8686
8787fn shortCircuit() {
8888 @setFnTest(this);
89 testShortCircuit(false, true);
90}
8991
90 var hit_1 = false;
91 var hit_2 = false;
92 var hit_3 = false;
93 var hit_4 = false;
92fn testShortCircuit(f: bool, t: bool) {
93 var hit_1 = f;
94 var hit_2 = f;
95 var hit_3 = f;
96 var hit_4 = f;
9497
95 if (true || {assert(false); false}) {
96 hit_1 = true;
98 if (t || {assert(f); f}) {
99 hit_1 = t;
97100 }
98 if (false || { hit_2 = true; false }) {
99 assert(false);
101 if (f || { hit_2 = t; f }) {
102 assert(f);
100103 }
101104
102 if (true && { hit_3 = true; false }) {
103 assert(false);
105 if (t && { hit_3 = t; f }) {
106 assert(f);
104107 }
105 if (false && {assert(false); false}) {
106 assert(false);
108 if (f && {assert(f); f}) {
109 assert(f);
107110 } else {
108 hit_4 = true;
111 hit_4 = t;
109112 }
110113 assert(hit_1);
111114 assert(hit_2);
test/cases/null.zig+4-4
......@@ -3,7 +3,7 @@ const assert = @import("std").debug.assert;
33fn nullableType() {
44 @setFnTest(this);
55
6 const x : ?bool = true;
6 const x : ?bool = @generatedCode(true);
77
88 if (const y ?= x) {
99 if (y) {
......@@ -15,13 +15,13 @@ fn nullableType() {
1515 @unreachable();
1616 }
1717
18 const next_x : ?i32 = null;
18 const next_x : ?i32 = @generatedCode(null);
1919
2020 const z = next_x ?? 1234;
2121
2222 assert(z == 1234);
2323
24 const final_x : ?i32 = 13;
24 const final_x : ?i32 = @generatedCode(13);
2525
2626 const num = final_x ?? @unreachable();
2727
......@@ -43,7 +43,7 @@ fn assignToIfVarPtr() {
4343fn rhsMaybeUnwrapReturn() {
4444 @setFnTest(this);
4545
46 const x: ?bool = true;
46 const x: ?bool = @generatedCode(true);
4747 const y = x ?? return;
4848}
4949