Skip to content

Commit c958341

Browse files
TIHanbaronfel
authored andcommitted
Fixed taking native address of an immutable local value (#8618)
1 parent 1c41665 commit c958341

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

src/fsharp/TastOps.fs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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).
60796079
let 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

Comments
 (0)