@@ -6078,6 +6078,16 @@ let mkDerefAddrExpr mAddrGet expr mExpr exprTy =
6078
6078
/// have intended effect (i.e. is a readonly pointer and/or a defensive copy).
6079
6079
let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut expr addrExprVal m =
6080
6080
if mustTakeAddress then
6081
+ let isNativePtr =
6082
+ match addrExprVal with
6083
+ | Some vf -> valRefEq g vf g.addrof2_ vref
6084
+ | _ -> false
6085
+
6086
+ // If we are taking the native address using "&&" to get a nativeptr, disallow if it's readonly.
6087
+ let checkTakeNativeAddress readonly =
6088
+ if isNativePtr && readonly then
6089
+ error( Error( FSComp.SR.tastValueMustBeMutable(), m))
6090
+
6081
6091
match expr with
6082
6092
// LVALUE of "*x" where "x" is byref is just the byref itself
6083
6093
| Expr.Op ( TOp.LValueOp ( LByrefGet, vref), _, [], m) when MustTakeAddressOfByrefGet g vref || CanTakeAddressOfByrefGet g vref mut ->
@@ -6090,6 +6100,7 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress
6090
6100
| Expr.Val ( vref, _, m) when MustTakeAddressOfVal g vref || CanTakeAddressOfImmutableVal g m vref mut ->
6091
6101
let readonly = not ( MustTakeAddressOfVal g vref)
6092
6102
let writeonly = false
6103
+ checkTakeNativeAddress readonly
6093
6104
None, mkValAddr m readonly vref, readonly, writeonly
6094
6105
6095
6106
// LVALUE of "e.f" where "f" is an instance F# field or record field.
@@ -6134,15 +6145,11 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress
6134
6145
6135
6146
// LVALUE of "e.[n]" where e is an array of structs
6136
6147
| Expr.App ( Expr.Val ( vf, _, _), _, [ elemTy], [ aexpr; nexpr], _) when ( valRefEq g vf g.array_ get_ vref) ->
6137
-
6148
+
6138
6149
let readonly = false // array address is never forced to be readonly
6139
6150
let writeonly = false
6140
6151
let shape = ILArrayShape.SingleDimensional
6141
6152
let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress
6142
- let isNativePtr =
6143
- match addrExprVal with
6144
- | Some vf -> valRefEq g vf g.addrof2_ vref
6145
- | _ -> false
6146
6153
None, mkArrayElemAddress g ( readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, [ aexpr; nexpr], m), readonly, writeonly
6147
6154
6148
6155
// LVALUE of "e.[n1, n2]", "e.[n1, n2, n3]", "e.[n1, n2, n3, n4]" where e is an array of structs
@@ -6153,11 +6160,6 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress
6153
6160
let writeonly = false
6154
6161
let shape = ILArrayShape.FromRank args.Length
6155
6162
let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress
6156
- let isNativePtr =
6157
- match addrExprVal with
6158
- | Some vf -> valRefEq g vf g.addrof2_ vref
6159
- | _ -> false
6160
-
6161
6163
None, mkArrayElemAddress g ( readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, ( aexpr :: args), m), readonly, writeonly
6162
6164
6163
6165
// LVALUE: "&meth(args)" where meth has a byref or inref return. Includes "&span.[idx]".
0 commit comments