[nem-bug] [Nemerle 0000929]: Pattern matching cannot handle nulls correctly

feedback at nemerle.org feedback at nemerle.org
Sun Apr 29 19:56:51 CEST 2007


The following issue requires your FEEDBACK.
======================================================================
<http://nemerle.org/bugs/view.php?id=929> 
======================================================================
Reported By:                nikov
Assigned To:                
======================================================================
Project:                    Nemerle
Issue ID:                   929
Category:                   Compiler (match compiler)
Reproducibility:            always
Severity:                   major
Priority:                   normal
Status:                     feedback
======================================================================
Date Submitted:             02-21-2007 12:07 CET
Last Modified:              04-29-2007 19:56 CEST
======================================================================
Summary:                    Pattern matching cannot handle nulls correctly
Description: 
[nemerle]
using System;
using System.Console;
using Nemerle.Utility;

[Record]
class B {
    public x : int;
}
    
module Program
{
  Main() : void
  {
    try {
        Foo(null);
        Foo(B(1));
    }
    catch {
     | e => WriteLine(e)
    }
    _ = ReadKey()
  }

 Foo(o : B) : void {
   | (x = 1) => /* Should check o != null before ldfld */
        WriteLine("yes")
   | _ => 
        WriteLine("no")
 }
}
[/nemerle]

Pattern matching throws NullReferenceException here.

[cil]
.method private hidebysig static void Foo(B o) cil managed
{
      .maxstack 3
      L_0000: nop 
      L_0001: nop 
      L_0002: ldarg.0 
      L_0003: ldfld int32 B::x /* Should check o != null before ldfld */
      L_0008: ldc.i4.1 
      L_0009: bne.un L_001d
      L_000e: ldstr "yes"
      L_0013: call void [mscorlib]System.Console::WriteLine(string)
      L_0018: br L_0027
      L_001d: ldstr "no"
      L_0022: call void [mscorlib]System.Console::WriteLine(string)
      L_0027: ret 
}
[/cil]

There is missing check on null in compiled code.
======================================================================

----------------------------------------------------------------------
 nikov - 02-21-07 12:37 
----------------------------------------------------------------------
For variants options it works well, because of 'isinst' instruction.

----------------------------------------------------------------------
 malekith - 04-29-07 19:56 
----------------------------------------------------------------------
This is, sort of, expected.

When you match a value against pattern that is not 'null', then the value
is assumed to be non-null. We decided for it to work this way, because of
performance considerations -- we don't want to check for nullness at each
field access.

What is annoying here, is that:

foo (_)
  | null => "null"
  | Foobar where ( x = 7, y = z ) => z

will work differntly than:

foo (_)
  | Foobar where ( x = 7, y = z ) => z
  | null => "null"

In the second case, for foo(null) you'll get null reference exception.

But this is the usual way, in which patterns work -- they match one after
another.



Issue History
Date Modified  Username       Field                    Change              
======================================================================
02-21-07 12:07 nikov          New Issue                                    
02-21-07 12:37 nikov          Note Added: 0001762                          
04-29-07 19:56 malekith       Note Added: 0001854                          
04-29-07 19:56 malekith       Status                   new => feedback     
04-29-07 19:56 malekith       Description Updated                          
======================================================================




More information about the bugs mailing list