diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_Observations.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_Observations.fs new file mode 100644 index 00000000000..27358158eeb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CodeGenRegressions/CodeGenRegressions_Observations.fs @@ -0,0 +1,195 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace EmittedIL + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler +open FSharp.Test.Utilities + +module CodeGenRegressions_Observations = + // https://github.com/dotnet/fsharp/issues/13100 + [] + let ``Issue_13100_PlatformCharacteristic`` () = + let source = """ +module PlatformTest + +[] +let main _ = 0 +""" + FSharp source + |> asExe + |> withPlatform ExecutionPlatform.X64 + |> compile + |> shouldSucceed + |> withPeReader (fun rdr -> + let characteristics = rdr.PEHeaders.CoffHeader.Characteristics + if not (characteristics.HasFlag(System.Reflection.PortableExecutable.Characteristics.LargeAddressAware)) then + failwith $"x64 binary should have LargeAddressAware flag. Found: {characteristics}" + if characteristics.HasFlag(System.Reflection.PortableExecutable.Characteristics.Bit32Machine) then + failwith $"x64 binary should NOT have Bit32Machine flag. Found: {characteristics}") + |> ignore + + + // https://github.com/dotnet/fsharp/issues/11935 + [] + let ``Issue_11935_UnmanagedConstraintInterop`` () = + let source = """ +module Test + +let test<'T when 'T : unmanaged> (x: 'T) = x +""" + FSharp source + |> asLibrary + |> withLangVersion10 + |> compile + |> shouldSucceed + |> verifyILContains [ + ".method public static !!T test(!!T x) cil managed" + ] + |> shouldSucceed + + + [] + let ``Issue_11935_UnmanagedConstraintInterop_ClassType`` () = + let source = """ +module Test + +type Container<'T when 'T : unmanaged>() = + member _.GetDefault() : 'T = Unchecked.defaultof<'T> +""" + FSharp source + |> asLibrary + |> withLangVersion10 + |> compile + |> shouldSucceed + |> verifyILContains [ + "Container`1" + ] + |> shouldSucceed + + + [] + let ``Issue_11935_UnmanagedConstraintInterop_StructType`` () = + let source = """ +module Test + +[] +type StructContainer<'T when 'T : unmanaged> = + val Value : 'T + new(v) = { Value = v } +""" + FSharp source + |> asLibrary + |> withLangVersion10 + |> compile + |> shouldSucceed + |> verifyILContains [ + "StructContainer`1" + ] + |> shouldSucceed + + + [] + let ``Issue_11935_UnmanagedConstraintInterop_InstanceMethod`` () = + let source = """ +module Test + +type Processor() = + member _.Process<'T when 'T : unmanaged>(x: 'T) = x +""" + FSharp source + |> asLibrary + |> withLangVersion10 + |> compile + |> shouldSucceed + |> verifyILContains [ + ".method public hidebysig instance !!T Process(!!T x) cil managed" + ] + |> shouldSucceed + + + [] + let ``Issue_11935_UnmanagedConstraintInterop_MultipleTypeParams`` () = + let source = """ +module Test + +let combine<'T, 'U when 'T : unmanaged and 'U : unmanaged> (x: 'T) (y: 'U) = struct(x, y) +""" + FSharp source + |> asLibrary + |> withLangVersion10 + |> compile + |> shouldSucceed + |> verifyILContains [ + "combine(!!T x, !!U y) cil managed" + ] + |> shouldSucceed + + + // https://github.com/dotnet/fsharp/issues/7861 + [] + let ``Issue_7861_AttributeTypeReference`` () = + let source = """ +module Test + +open System + +type TypedAttribute(t: Type) = + inherit Attribute() + member _.TargetType = t + +[)>] +type MyClass() = class end +""" + FSharp source + |> asLibrary + |> compile + |> shouldSucceed + |> verifyAssemblyReference "System.Xml" + |> ignore + + + [] + let ``Issue_7861_NamedAttributeArgument`` () = + let source = """ +module Test + +open System + +type TypePropertyAttribute() = + inherit Attribute() + member val TargetType : Type = null with get, set + +[)>] +type MyClass() = class end +""" + FSharp source + |> asLibrary + |> compile + |> shouldSucceed + |> verifyAssemblyReference "System.Xml" + |> ignore + + + [] + let ``Issue_7861_AttributeOnMethod`` () = + let source = """ +module Test + +open System + +type TypedAttribute(t: Type) = + inherit Attribute() + member _.TargetType = t + +type MyClass() = + [)>] + member _.MyMethod() = () +""" + FSharp source + |> asLibrary + |> compile + |> shouldSucceed + |> verifyAssemblyReference "System.Xml" + |> ignore diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 63150ad3a7d..a5097a21209 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -195,6 +195,7 @@ + diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index b93dea8fd1c..d9e365704d5 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -1362,6 +1362,28 @@ Actual: let verifyILNotPresent = doILCheck ILChecker.checkILNotPresent + /// Verifies that the compiled assembly contains an assembly reference whose name starts with the given prefix. + let verifyAssemblyReference (prefix: string) (result: CompilationResult) : CompilationResult = + match result with + | CompilationResult.Success s -> + match s.OutputPath with + | None -> failwith "Operation didn't produce any output!" + | Some p -> + let bytes = File.ReadAllBytes(p) + use peReader = new PEReader(bytes.ToImmutableArray()) + let mdReader = peReader.GetMetadataReader() + let refs = + [ for h in mdReader.AssemblyReferences do + mdReader.GetString(mdReader.GetAssemblyReference(h).Name) ] + if refs |> List.exists (fun name -> name.StartsWith(prefix, StringComparison.Ordinal)) then + result + else + failwith $"Expected assembly reference starting with '{prefix}'. Found: %A{refs}" + | CompilationResult.Failure f -> + printfn "Failure:" + printfn $"{f}" + failwith "Result should be \"Success\" in order to verify assembly references." + let verifyILBinary (il: string list) (dll: string)= ILChecker.checkIL dll il let private verifyFSILBaseline (baseline: Baseline) (result: CompilationOutput) : unit =