diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 208fcac02a17e434c209f920392d5525215e911e..029de52c39f6ca86448ecaf73d0b45c16b3ae0ba 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -624,7 +624,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = CheckExprsPermitByrefs cenv env rest | Expr.Op (c,tyargs,args,m) -> - CheckExprOp cenv env (c,tyargs,args,m) context + CheckExprOp cenv env (c,tyargs,args,m) context expr // Allow 'typeof' calls as a special case, the only accepted use of System.Void! | TypeOfExpr cenv.g ty when isVoidTy cenv.g ty -> @@ -734,7 +734,7 @@ and CheckInterfaceImpls cenv env baseValOpt l = and CheckInterfaceImpl cenv env baseValOpt (_ty,overrides) = CheckMethods cenv env baseValOpt overrides -and CheckExprOp cenv env (op,tyargs,args,m) context = +and CheckExprOp cenv env (op,tyargs,args,m) context expr = let limitedCheck() = if env.limited then errorR(Error(FSComp.SR.chkObjCtorsCantUseExceptionHandling(), m)) List.iter (CheckTypePermitByrefs cenv env m) tyargs @@ -828,13 +828,13 @@ and CheckExprOp cenv env (op,tyargs,args,m) context = CheckTypeInstNoByrefs cenv env m tyargs | TOp.ValFieldGetAddr rfref,tyargs,[] -> - if noByrefs context && cenv.reportErrors then + if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressStaticFieldAtThisPoint(rfref.FieldName), m)) CheckTypeInstNoByrefs cenv env m tyargs // NOTE: there are no arg exprs to check in this case | TOp.ValFieldGetAddr rfref,tyargs,[rx] -> - if noByrefs context && cenv.reportErrors then + if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m)) // This construct is used for &(rx.rfield) and &(rx->rfield). Relax to permit byref types for rx. [See Bug 1263]. CheckTypeInstNoByrefs cenv env m tyargs @@ -849,7 +849,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context = CheckExprPermitByref cenv env arg1 // allow byref - it may be address-of-struct | TOp.UnionCaseFieldGetAddr (uref, _idx),tyargs,[rx] -> - if noByrefs context && cenv.reportErrors then + if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(uref.CaseName), m)) CheckTypeInstNoByrefs cenv env m tyargs // allow rx to be byref here, for struct unions @@ -870,12 +870,12 @@ and CheckExprOp cenv env (op,tyargs,args,m) context = // permit byref for lhs lvalue of readonly value CheckExprPermitByref cenv env lhs | [ I_ldflda (fspec) | I_ldsflda (fspec) ],[lhs] -> - if noByrefs context && cenv.reportErrors then + if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(fspec.Name), m)) // permit byref for lhs lvalue CheckExprPermitByref cenv env lhs | [ I_ldelema (_,isNativePtr,_,_) ],lhsArray::indices -> - if not(isNativePtr) && noByrefs context && cenv.reportErrors then + if noByrefs context && cenv.reportErrors && not isNativePtr && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressOfArrayElementAtThisPoint(), m)) // permit byref for lhs lvalue CheckExprPermitByref cenv env lhsArray @@ -982,7 +982,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn | _ -> // Permit byrefs for let x = ... CheckTypePermitByrefs cenv env m ety - if not inlined && isByrefLikeTy cenv.g ety then + if not inlined && (isByrefLikeTy cenv.g ety || isNativePtrTy cenv.g ety) then // allow byref to occur as RHS of byref binding. CheckExprPermitByref cenv env e else diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index f7107f0ada9e45a632a0eb2b4651925978677e57..9c8088a493af6cadf18a282948b377bd22e965fd 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -1681,6 +1681,12 @@ module TypecheckTests = peverify cfg "pos27.exe" + [] + let ``sigs pos28`` () = + let cfg = testConfig "typecheck/sigs" + fsc cfg "%s --target:exe -o:pos28.exe" cfg.fsc_flags ["pos28.fs"] + peverify cfg "pos28.exe" + [] let ``sigs pos26`` () = let cfg = testConfig "typecheck/sigs" diff --git a/tests/fsharp/typecheck/sigs/pos28.fs b/tests/fsharp/typecheck/sigs/pos28.fs new file mode 100644 index 0000000000000000000000000000000000000000..2fded70c6fa16dc59c9da3dcb9dfc08ce42bee34 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/pos28.fs @@ -0,0 +1,25 @@ +module Pos28 + +open FSharp.NativeInterop + +module Test1 = + [] + type Point = + val mutable X: int + val mutable Y: int + new(x,y) = { X=x; Y=y; } + + let fixPoint1() = + let mutable point = Point(1,2) + let p1 = &&point.X + NativePtr.read p1 + +module Test2 = + [] + type Point = { mutable x : int; mutable y : int } + + let fixPoint1() = + let mutable point = Unchecked.defaultof + let p1 = &&point.x + NativePtr.read p1 + diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/AddressOf/E_byrefvaluesnotpermitted002.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/AddressOf/E_byrefvaluesnotpermitted002.fs deleted file mode 100644 index 4ad47a2c094170874f1e0c11b84d16a53cb02ac8..0000000000000000000000000000000000000000 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/AddressOf/E_byrefvaluesnotpermitted002.fs +++ /dev/null @@ -1,10 +0,0 @@ -// #Regression #Conformance #DataExpressions -// AddressOf Operator (warnings) -// Verify we can the compiler always issue warnings about using & and && operators -//The use of native pointers may result in unverifiable \.NET IL code$ -//The address of the variable 'x' cannot be used at this point$ - -module M = - let mutable x = 10 - let w = &&x - diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/AddressOf/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/AddressOf/env.lst index 4d541a7d85c3e984602a1a104458011b1b1fdd3e..789105b81b805514712e9afb5e4a1a00e743f1b6 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/AddressOf/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/AddressOf/env.lst @@ -3,4 +3,3 @@ NoMT SOURCE=addressof001.fsx PRECMD="\$CSC_PIPE /t:library addressof001dll.cs" NoMT SOURCE=addressof002.fsx PRECMD="\$CSC_PIPE /t:library addressof002dll.cs" # addressof002.fsx NOMONO SOURCE=addressof003.fs SCFLAGS="--test:ErrorRanges" PRECMD="copy /y addressof003dll_%OSARCH%.dll addressof003dll.dll" PEVER=/MD # addressof003.fs SOURCE=E_byrefvaluesnotpermitted001.fs SCFLAGS="--test:ErrorRanges" # E_byrefvaluesnotpermitted001.fs - SOURCE=E_byrefvaluesnotpermitted002.fs SCFLAGS="--test:ErrorRanges" # E_byrefvaluesnotpermitted002.fs