authorgravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2020-04-27 15:22:15+03:00
committergravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2020-04-27 15:22:15+03:00
log908b908481260322b60f479ccf4cabff72fcc5d5
tree56262a1724b716c182ea375ef3ab0a21f3faa352
parent179423ec2712956e04f188bf8b904e4fb9b48656

Added tests.


3 files changed, 43 insertions(+), 6 deletions(-)

src/ir.cpp+6-6
...@@ -19706,13 +19706,13 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -19706,13 +19706,13 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
19706 return ira->codegen->invalid_inst_gen;19706 return ira->codegen->invalid_inst_gen;
19707 }19707 }
1970819708
19709 bool extern_fn_in_typeof = false;
19710
19711 if (modifier == CallModifierCompileTime) {19709 if (modifier == CallModifierCompileTime) {
19710 bool extern_fn_in_typeof = false;
19711
19712 // No special handling is needed for compile time evaluation of generic functions.19712 // No special handling is needed for compile time evaluation of generic functions.
19713 if (!fn_entry || fn_entry->body_node == nullptr) {19713 if (!fn_entry || fn_entry->body_node == nullptr) {
19714 // We keep evaluating extern functions in TypeOfs19714 // We keep evaluating extern functions directly in TypeOfs
19715 if (get_scope_typeof(source_instr->scope) != nullptr && fn_entry) {19715 if (fn_entry && source_instr->scope->id == ScopeIdTypeOf) {
19716 extern_fn_in_typeof = true;19716 extern_fn_in_typeof = true;
19717 } else {19717 } else {
19718 ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression"));19718 ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression"));
...@@ -19724,7 +19724,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -19724,7 +19724,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
19724 return ira->codegen->invalid_inst_gen;19724 return ira->codegen->invalid_inst_gen;
1972519725
19726 // Fork a scope of the function with known values for the parameters.19726 // Fork a scope of the function with known values for the parameters.
19727 // If we are evaluating an extern function in a TypeOf, we use the TypeOf's scope instead.19727 // If we are evaluating an extern function in a TypeOf, we use the current scope instead.
19728 Scope *exec_scope = extern_fn_in_typeof ? source_instr->scope : &fn_entry->fndef_scope->base;19728 Scope *exec_scope = extern_fn_in_typeof ? source_instr->scope : &fn_entry->fndef_scope->base;
1972919729
19730 size_t next_proto_i = 0;19730 size_t next_proto_i = 0;
...@@ -19752,7 +19752,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -19752,7 +19752,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
19752 return ira->codegen->invalid_inst_gen;19752 return ira->codegen->invalid_inst_gen;
19753 }19753 }
1975419754
19755 for (size_t call_i = 0; call_i < args_len; call_i += 1) {19755 if (!extern_fn_in_typeof) for (size_t call_i = 0; call_i < args_len; call_i += 1) {
19756 IrInstGen *old_arg = args_ptr[call_i];19756 IrInstGen *old_arg = args_ptr[call_i];
1975719757
19758 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i))19758 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i))
test/stage1/behavior.zig+1
...@@ -40,6 +40,7 @@ comptime {...@@ -40,6 +40,7 @@ comptime {
40 _ = @import("behavior/bugs/3384.zig");40 _ = @import("behavior/bugs/3384.zig");
41 _ = @import("behavior/bugs/3586.zig");41 _ = @import("behavior/bugs/3586.zig");
42 _ = @import("behavior/bugs/3742.zig");42 _ = @import("behavior/bugs/3742.zig");
43 _ = @import("behavior/bugs/4328.zig");
43 _ = @import("behavior/bugs/4560.zig");44 _ = @import("behavior/bugs/4560.zig");
44 _ = @import("behavior/bugs/4769_a.zig");45 _ = @import("behavior/bugs/4769_a.zig");
45 _ = @import("behavior/bugs/4769_b.zig");46 _ = @import("behavior/bugs/4769_b.zig");
test/stage1/behavior/bugs/4328.zig created+36
...@@ -0,0 +1,36 @@
1const expectEqual = @import("std").testing.expectEqual;
2
3const FILE = extern struct { dummy_field: u8, };
4extern fn printf([*c]const u8, ...) c_int;
5extern fn fputs([*c]const u8, noalias [*c]FILE) c_int;
6extern fn ftell([*c]FILE) c_long;
7
8test "Extern function call in @TypeOf" {
9 const Test = struct {
10 fn test_fn(a: var, b: var) @TypeOf(printf("%d %s\n", a, b)) {
11 return 0;
12 }
13
14 fn doTheTest() void {
15 expectEqual(c_int, @TypeOf(test_fn(0, 42)));
16 }
17 };
18
19 Test.doTheTest();
20 comptime Test.doTheTest();
21}
22
23test "Peer resolution of extern function calls in @TypeOf" {
24 const Test = struct {
25 fn test_fn() @TypeOf(ftell(null), fputs(null, null)) {
26 return 0;
27 }
28
29 fn doTheTest() void {
30 expectEqual(c_long, @TypeOf(test_fn()));
31 }
32 };
33
34 Test.doTheTest();
35 comptime Test.doTheTest();
36}