From b74189f0542faa3bfc53c9df11167402ab0ebfb8 Mon Sep 17 00:00:00 2001 From: Robert van der Hulst Date: Thu, 10 Mar 2022 08:50:17 +0100 Subject: [PATCH] Fixes #X-Sharp/XSharpPublic/issues/989 --- Tests/Applications/C844/Prg/C844.prg | 5 ++-- Tests/Applications/C845/Prg/C845.prg | 3 ++- Tests/xSharp Tests.viproj | 2 +- .../Binder/Binder_Operators.cs | 27 ++++++++++++++----- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Tests/Applications/C844/Prg/C844.prg b/Tests/Applications/C844/Prg/C844.prg index 071de75de6..7623923746 100644 --- a/Tests/Applications/C844/Prg/C844.prg +++ b/Tests/Applications/C844/Prg/C844.prg @@ -1,5 +1,6 @@ -// 844. Problem with iif() and NULL - /vo11 disabled -// error XS0029: Cannot implicitly convert type 'object' to 'string' +// 844. Problem with iif() and NULL - /vo10 disabled +// error XS0029: Cannot implicitly convert type 'object' to 'string' +#pragma options("vo10", off) FUNCTION Start() AS VOID LOCAL c AS STRING c := iif(FALSE, "", NULL) // error XS0029 diff --git a/Tests/Applications/C845/Prg/C845.prg b/Tests/Applications/C845/Prg/C845.prg index aa8b4e375f..ca012c3eda 100644 --- a/Tests/Applications/C845/Prg/C845.prg +++ b/Tests/Applications/C845/Prg/C845.prg @@ -1,5 +1,6 @@ -// 844. Problem with iif() and NULL - /vo11 enabled +// 844. Problem with iif() and NULL - /vo10 enabled // error XS0029: Cannot implicitly convert type 'object' to 'string' +#pragma options("vo10", on) FUNCTION Start() AS VOID LOCAL c AS STRING c := iif(FALSE, "", NULL) // error XS0029 diff --git a/Tests/xSharp Tests.viproj b/Tests/xSharp Tests.viproj index 23e177d49a..2c632075f7 100644 --- a/Tests/xSharp Tests.viproj +++ b/Tests/xSharp Tests.viproj @@ -106884,7 +106884,7 @@ VO6=0 VO7=0 VO8=0 VO9=0 -VO10=1 +VO10=0 VO11=0 VO12=0 VO13=0 diff --git a/XSharp/src/Compiler/XSharpCodeAnalysis/Binder/Binder_Operators.cs b/XSharp/src/Compiler/XSharpCodeAnalysis/Binder/Binder_Operators.cs index 42eca34822..908a0048cb 100644 --- a/XSharp/src/Compiler/XSharpCodeAnalysis/Binder/Binder_Operators.cs +++ b/XSharp/src/Compiler/XSharpCodeAnalysis/Binder/Binder_Operators.cs @@ -1010,19 +1010,34 @@ private BoundExpression AdjustConstantType(BoundExpression expr, TypeSymbol type public void VODetermineIIFTypes(ConditionalExpressionSyntax node, DiagnosticBag diagnostics, ref BoundExpression trueExpr, ref BoundExpression falseExpr) { - if (trueExpr is null || trueExpr.Type is null) + // a combination of null and a value type is not allowed + // in that case we replace the null with a default value. + var trueNull = trueExpr?.Type is null; + var falseNull = falseExpr?.Type is null; + if (trueNull && falseNull) + { + return; + } + else if (trueNull && !falseExpr.Type.IsReferenceType) { if (Compilation.Options.HasRuntime) + { trueExpr = new BoundDefaultExpression(trueExpr.Syntax, Compilation.UsualType()); - else - trueExpr = new BoundDefaultExpression(trueExpr.Syntax, Compilation.ObjectType); + trueNull = false; + } } - if (falseExpr is null || falseExpr.Type is null) + else if (falseNull && !trueExpr.Type.IsReferenceType) { if (Compilation.Options.HasRuntime) + { falseExpr = new BoundDefaultExpression(falseExpr.Syntax, Compilation.UsualType()); - else - falseExpr = new BoundDefaultExpression(falseExpr.Syntax, Compilation.ObjectType); + falseNull = false; + } + } + if (trueNull || falseNull) + { + // this happens with the combination of a null and a reference type. + return; } // Determine underlying types. For literal numbers this may be Byte, Short, Int or Long TypeSymbol trueType = VOGetType(trueExpr);