@@ -6078,6 +6078,16 @@ let mkDerefAddrExpr mAddrGet expr mExpr exprTy =
60786078/// have intended effect (i.e. is a readonly pointer and/or a defensive copy).
60796079let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut expr addrExprVal m =
60806080 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+
60816091 match expr with
60826092 // LVALUE of "*x" where "x" is byref is just the byref itself
60836093 | 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
60906100 | Expr.Val ( vref, _, m) when MustTakeAddressOfVal g vref || CanTakeAddressOfImmutableVal g m vref mut ->
60916101 let readonly = not ( MustTakeAddressOfVal g vref)
60926102 let writeonly = false
6103+ checkTakeNativeAddress readonly
60936104 None, mkValAddr m readonly vref, readonly, writeonly
60946105
60956106 // LVALUE of "e.f" where "f" is an instance F# field or record field.
@@ -6134,15 +6145,11 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress
61346145
61356146 // LVALUE of "e.[n]" where e is an array of structs
61366147 | Expr.App ( Expr.Val ( vf, _, _), _, [ elemTy], [ aexpr; nexpr], _) when ( valRefEq g vf g.array_ get_ vref) ->
6137-
6148+
61386149 let readonly = false // array address is never forced to be readonly
61396150 let writeonly = false
61406151 let shape = ILArrayShape.SingleDimensional
61416152 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
61466153 None, mkArrayElemAddress g ( readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, [ aexpr; nexpr], m), readonly, writeonly
61476154
61486155 // 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
61536160 let writeonly = false
61546161 let shape = ILArrayShape.FromRank args.Length
61556162 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-
61616163 None, mkArrayElemAddress g ( readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, ( aexpr :: args), m), readonly, writeonly
61626164
61636165 // LVALUE: "&meth(args)" where meth has a byref or inref return. Includes "&span.[idx]".
0 commit comments