Commit 5ea79bfc4a

Andrew Kelley <andrew@ziglang.org>
2020-02-10 04:34:34
fix not checking type of return pointer
Thanks to Vexu for the test cases. Closes #3422 Closes #3646 Closes #3224 Closes #3327 Closes #3269
1 parent 04ee3b0
Changed files (2)
src/ir.cpp
@@ -19591,6 +19591,12 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
                 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
                     return result_loc;
                 }
+                IrInstGen *dummy_value = ir_const(ira, source_instr, impl_fn_type_id->return_type);
+                dummy_value->value->special = ConstValSpecialRuntime;
+                IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
+                        dummy_value, result_loc->value->type->data.pointer.child_type);
+                if (type_is_invalid(dummy_result->value->type))
+                    return ira->codegen->invalid_inst_gen;
                 ZigType *res_child_type = result_loc->value->type->data.pointer.child_type;
                 if (res_child_type == ira->codegen->builtin_types.entry_var) {
                     res_child_type = impl_fn_type_id->return_type;
@@ -19723,6 +19729,12 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
             if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
                 return result_loc;
             }
+            IrInstGen *dummy_value = ir_const(ira, source_instr, return_type);
+            dummy_value->value->special = ConstValSpecialRuntime;
+            IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
+                    dummy_value, result_loc->value->type->data.pointer.child_type);
+            if (type_is_invalid(dummy_result->value->type))
+                return ira->codegen->invalid_inst_gen;
             ZigType *res_child_type = result_loc->value->type->data.pointer.child_type;
             if (res_child_type == ira->codegen->builtin_types.entry_var) {
                 res_child_type = return_type;
test/compile_errors.zig
@@ -3,6 +3,30 @@ const builtin = @import("builtin");
 const Target = @import("std").Target;
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.add("function call assigned to incorrect type",
+        \\export fn entry() void {
+        \\    var arr: [4]f32 = undefined;
+        \\    arr = concat();
+        \\}
+        \\fn concat() [16]f32 {
+        \\    return [1]f32{0}**16;
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:3:17: error: expected type '[4]f32', found '[16]f32'",
+    });
+
+    cases.add("generic function call assigned to incorrect type",
+        \\pub export fn entry() void {
+        \\    var res: []i32 = undefined;
+        \\    res = myAlloc(i32);
+        \\}
+        \\fn myAlloc(comptime arg: type) anyerror!arg{
+        \\    unreachable;
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:3:18: error: expected type '[]i32', found 'anyerror!i32",
+    });
+
     cases.addTest("dependency loop in top-level decl with @TypeInfo",
         \\export const foo = @typeInfo(@This());
     , &[_][]const u8{