@@ -2880,35 +2880,57 @@ fn transCPtrCast(
2880
2880
) ! * ast.Node {
2881
2881
const ty = ZigClangQualType_getTypePtr (dst_type );
2882
2882
const child_type = ZigClangType_getPointeeType (ty );
2883
+ const src_ty = ZigClangQualType_getTypePtr (src_type );
2884
+ const src_child_type = ZigClangType_getPointeeType (src_ty );
2883
2885
2884
- // Implicit downcasting from higher to lower alignment values is forbidden,
2885
- // use @alignCast to side-step this problem
2886
- const ptrcast_node = try transCreateNodeBuiltinFnCall (rp .c , "@ptrCast" );
2887
- const dst_type_node = try transType (rp , ty , loc );
2888
- try ptrcast_node .params .push (dst_type_node );
2889
- _ = try appendToken (rp .c , .Comma , "," );
2886
+ if ((ZigClangQualType_isConstQualified (src_child_type ) and
2887
+ ! ZigClangQualType_isConstQualified (child_type )) or
2888
+ (ZigClangQualType_isVolatileQualified (src_child_type ) and
2889
+ ! ZigClangQualType_isVolatileQualified (child_type )))
2890
+ {
2891
+ // Casting away const or volatile requires us to use @intToPtr
2892
+ const inttoptr_node = try transCreateNodeBuiltinFnCall (rp .c , "@intToPtr" );
2893
+ const dst_type_node = try transType (rp , ty , loc );
2894
+ try inttoptr_node .params .push (dst_type_node );
2895
+ _ = try appendToken (rp .c , .Comma , "," );
2890
2896
2891
- if (ZigClangType_isVoidType (qualTypeCanon (child_type ))) {
2892
- // void has 1-byte alignment, so @alignCast is not needed
2893
- try ptrcast_node .params .push (expr );
2894
- } else if (typeIsOpaque (rp .c , qualTypeCanon (child_type ), loc )) {
2895
- // For opaque types a ptrCast is enough
2896
- try ptrcast_node .params .push (expr );
2897
+ const ptrtoint_node = try transCreateNodeBuiltinFnCall (rp .c , "@ptrToInt" );
2898
+ try ptrtoint_node .params .push (expr );
2899
+ ptrtoint_node .rparen_token = try appendToken (rp .c , .RParen , ")" );
2900
+
2901
+ try inttoptr_node .params .push (& ptrtoint_node .base );
2902
+ inttoptr_node .rparen_token = try appendToken (rp .c , .RParen , ")" );
2903
+ return & inttoptr_node .base ;
2897
2904
} else {
2898
- const aligncast_node = try transCreateNodeBuiltinFnCall (rp .c , "@alignCast" );
2899
- const alignof_node = try transCreateNodeBuiltinFnCall (rp .c , "@alignOf" );
2900
- const child_type_node = try transQualType (rp , child_type , loc );
2901
- try alignof_node .params .push (child_type_node );
2902
- alignof_node .rparen_token = try appendToken (rp .c , .RParen , ")" );
2903
- try aligncast_node .params .push (& alignof_node .base );
2905
+ // Implicit downcasting from higher to lower alignment values is forbidden,
2906
+ // use @alignCast to side-step this problem
2907
+ const ptrcast_node = try transCreateNodeBuiltinFnCall (rp .c , "@ptrCast" );
2908
+ const dst_type_node = try transType (rp , ty , loc );
2909
+ try ptrcast_node .params .push (dst_type_node );
2904
2910
_ = try appendToken (rp .c , .Comma , "," );
2905
- try aligncast_node .params .push (expr );
2906
- aligncast_node .rparen_token = try appendToken (rp .c , .RParen , ")" );
2907
- try ptrcast_node .params .push (& aligncast_node .base );
2908
- }
2909
- ptrcast_node .rparen_token = try appendToken (rp .c , .RParen , ")" );
2910
2911
2911
- return & ptrcast_node .base ;
2912
+ if (ZigClangType_isVoidType (qualTypeCanon (child_type ))) {
2913
+ // void has 1-byte alignment, so @alignCast is not needed
2914
+ try ptrcast_node .params .push (expr );
2915
+ } else if (typeIsOpaque (rp .c , qualTypeCanon (child_type ), loc )) {
2916
+ // For opaque types a ptrCast is enough
2917
+ try ptrcast_node .params .push (expr );
2918
+ } else {
2919
+ const aligncast_node = try transCreateNodeBuiltinFnCall (rp .c , "@alignCast" );
2920
+ const alignof_node = try transCreateNodeBuiltinFnCall (rp .c , "@alignOf" );
2921
+ const child_type_node = try transQualType (rp , child_type , loc );
2922
+ try alignof_node .params .push (child_type_node );
2923
+ alignof_node .rparen_token = try appendToken (rp .c , .RParen , ")" );
2924
+ try aligncast_node .params .push (& alignof_node .base );
2925
+ _ = try appendToken (rp .c , .Comma , "," );
2926
+ try aligncast_node .params .push (expr );
2927
+ aligncast_node .rparen_token = try appendToken (rp .c , .RParen , ")" );
2928
+ try ptrcast_node .params .push (& aligncast_node .base );
2929
+ }
2930
+ ptrcast_node .rparen_token = try appendToken (rp .c , .RParen , ")" );
2931
+
2932
+ return & ptrcast_node .base ;
2933
+ }
2912
2934
}
2913
2935
2914
2936
fn transBreak (rp : RestorePoint , scope : * Scope ) TransError ! * ast.Node {
0 commit comments