Commit 6c05f0949a

LemonBoy <thatlemon@gmail.com>
2020-02-11 15:48:35
ir: Fix erroneous error message for ptr casts
Don't blindly throw an error if two integer types are checked for compatibility. Bug reported in #4430
1 parent b81c5be
Changed files (2)
src
test
stage1
behavior
src/ir.cpp
@@ -11873,10 +11873,15 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
     }
 
     if (wanted_type->id == ZigTypeIdInt && actual_type->id == ZigTypeIdInt) {
-        result.id = ConstCastResultIdIntShorten;
-        result.data.int_shorten = heap::c_allocator.allocate_nonzero<ConstCastIntShorten>(1);
-        result.data.int_shorten->wanted_type = wanted_type;
-        result.data.int_shorten->actual_type = actual_type;
+        if (wanted_type->data.integral.is_signed != actual_type->data.integral.is_signed ||
+            wanted_type->data.integral.bit_count != actual_type->data.integral.bit_count)
+        {
+            result.id = ConstCastResultIdIntShorten;
+            result.data.int_shorten = heap::c_allocator.allocate_nonzero<ConstCastIntShorten>(1);
+            result.data.int_shorten->wanted_type = wanted_type;
+            result.data.int_shorten->actual_type = actual_type;
+            return result;
+        }
         return result;
     }
 
test/stage1/behavior/cast.zig
@@ -782,3 +782,16 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" {
     };
     S.doTheTest();
 }
+
+test "cast between C pointer with different but compatible types" {
+    const S = struct {
+        fn foo(arg: [*]c_ushort) u16 {
+            return arg[0];
+        }
+        fn doTheTest() void {
+            var x = [_]u16{ 4, 2, 1, 3 };
+            expect(foo(@ptrCast([*]u16, &x)) == 4);
+        }
+    };
+    S.doTheTest();
+}