Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] View of /bugs/trunk/bugs.1401-1600
ViewVC logotype

View of /bugs/trunk/bugs.1401-1600

Parent Directory Parent Directory | Revision Log Revision Log


Revision 944 - (download) (annotate)
Thu Oct 4 13:38:32 2001 UTC (17 years, 9 months ago) by macqueen
File size: 464839 byte(s)
Initial revision
Number: 1401
Title:       Posix.Process.waitpid_nh is buggy.
Keywords:    waitpid_nj
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        6/18/98
Version:     110.0.3
System:      x86-linux
Severity:    medium
Problem:     

  The program below (Code: section) causes the error:

  uncaught exception SysErr: unknown child status

  I believe the program should terminate.  The call to waitpid_nh is
  raising the exception, but it should return NONE.

Code:        
  open Posix.Process
  val _ =
     case fork() of
	NONE => (sleep(Time.fromSeconds 5); exit 0w0)
      | SOME pid => (waitpid_nh(W_CHILD pid, []); ())
Transcript:  
Comments:    
Fix:         

  The problem is in runtime/c-libs/posix-process/waitpid.c.
  The status buffer should not be checked if WNOHANG was used and the
  result pid was 0.

Test: bug1401.1.sml
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1402
Title:       Word.fmt incorrectly uses lowercase letters for hex digits.
Keywords:    Word.fmt
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        6/18/98
Version:     110.0.3
System:      x86-linux
Severity:    
Problem:     

The code:
  Word.fmt StringCvt.HEX 0wxABCDEF 
returns:
  "abcdef"

According to the basis library specification
http://cm.bell-labs.com/cm/cs/what/smlnj/doc/basis/pages/word.html#SIG:WORD.fmt:VAL,
the hexadecimal digits 10-15 are represented as [A-F].

Hence, the correct result is "ABCDEF".

Comments:    
Fix:         
Test: bug1402.1.sml
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1403
Title:       Possible bug is Posix.FileSys.pathconf
Keywords:    pathconf
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        6/21/98
Version:     110.0.3
System:      x86-linux
Severity:    
Problem:     

I am confused by the fact that pathconf returns SOME 0w0 instead of
NONE when a property is false.  This does not appear to agree with the
basis library specification:
http://cm.bell-labs.com/cm/cs/what/smlnj/doc/basis/pages/posix-file-sys.html#SIG:POSIX_FILE_SYS.pathconf:VAL

For example, on my machine, the following code:

  Posix.FileSys.pathconf("/bin/ls", "VDISABLE");

returns the following:

  val it = SOME 0wx0 : Word32.word option

I believe that it should return NONE.

Comments:    
Fix:         

  The C code for mkValue in src/runtime/c-libs/posix-filesys/pathconf.c
  has the following test:

   if (val >= 0) {

  Perhaps this should be:

   if (val > 0) {


Test: tests.posix/bug1403.1.sml
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1404
Title: Parser combinator implements bind incorrectly
Keywords: SML/NJ library, parser combinators
Submitter: Andrew Kennedy   Andrew.Kennedy@persimmon.co.uk
Date: 06/23/98
Version: 110
System: Any/All Any Unix 
Subsystem: SML/NJ Library
Severity: minor
Problem:
  ParserComb.bind has wrong implementation -- it doesn't eat its input if
  the parse succeeds.
Comments:
  Obviously the parser combinators haven't been used. Please test them!
Fix:
  Replace   p2' t1 getc strm
  by        p2' t1 getc strm1
Test: ?
Owner: jhr, erg
Status: fixed in 110.8 [jhr, 8/5/98]
----------------------------------------------------------------------
Number: 1405
Title:	     Posix.TTY discrepancy with Basis Library spec
Keywords:    
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        6/24/98
Version:     110.0.3
System:      x86-linux
Severity:    
Problem:     

  According to the Basis Library spec
  http://cm.bell-labs.com/cm/cs/what/smlnj/doc/basis/pages/posix-tty.html,
  the following functions should be defined in Posix.TTY.TC

    getattr
    setattr
    sendbreak
    drain
    flush
    flow

  However, in SML/NJ, they are defined in Posix.TTY

Comments:    
Fix:         
Test: ?
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1406
Title:       STRING does not agree with Basis Library spec
Keywords:    STRING
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        6/25/98
Version:     110.0.3
System:      x86-linux
Severity:    
Problem:     

  The Basis Library spec says that the STRING signature should contain
  a structure specification:

    structure Char : CHAR

  The SML/NJ implementation omits this.

Comments:    
 [jhr, 6/25/97]
  This is still an open issue in the design of the basis (including
  type defs vs substructures).  Until this is resolved, we are holding
  off changes to the SML/NJ signatures.
Fix:         
Test: ?
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1407
Title:       ARRAY does not agree with Basis Library spec
Keywords:    ARRAY
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        6/25/98
Version:     110.0.3
System:      x86-linux
Severity:    major 
Problem:     

  As part of the ARRAY signature, SML/NJ has the value specification:

      val array0   : 'a array

  The Basis Library spec does not include this.

Comments:    
Fix:         
Test: bug1407.1.sml
Owner: jhr
Status: fixed in 110.0.6
----------------------------------------------------------------------
Number: 1408
Title: OrdSet.app order doesn't agree with comment
Keywords: 
Submitter: George Russell   george@persimmon.com
Date: 07/07/98
Version: 110.6
System: Alpha Digital Unix 4.0B
Subsystem: Other
Severity: cosmetic
Problem:
  IntBinarySet.app appears to apply the function to the elements of
  the set in INCREASING order.  This is what I want, but the
  relevant bit of ord-set-sig.sml says      
  >  val app : (item -> unit) -> set -> unit
  >  	(* Apply a function to the entries of the set 
  >           * in decreasing order
	   *)
Code:
  IntBinarySet.app (print o Int.toString)
    (IntBinarySet.addList(IntBinarySet.empty,[1,2,3,4]));
Transcript:
  Standard ML of New Jersey v110.6 [FLINT v1.41], May 21, 1998 [CM; autoload enabled]
  - IntBinarySet.app(print o Int.toString)(IntBinarySet.addList(IntBinarySet.empty,[1,2,3,4]));
  [Autoloading...]
  [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/lib-base-sig.sml.bin... done]
  [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/lib-base.sml.bin... done]
  [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/ord-key-sig.sml.bin... done]
  [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/ord-set-sig.sml.bin... done]
  [recovering /rnd/tools/sml110.6/src/smlnj-lib/Util/CM/alpha32-unix/int-binary-set.sml.bin...GC #0.0.0.0.1.3:   (8 ms)
   done]
  [Autoloading done.]
  1234val it = () : unit

Comments:
Fix:
Test: bug1408.1.sml
Owner: jhr, erg
Status: open
----------------------------------------------------------------------
Number: 1409
Title: Swaps reals in a structure or tuple 
Keywords: reals modules tuples
Submitter: Elsa L. Gunter   elsa@research.bell-labs.com
Date: 07/13/98
Version: 110.7
System: x86 Linux 2.0 and after
Subsystem: SML compiler
Severity: critical
Problem:
If you create a functor that creates at least 7 real values, and you
apply the functor to get a structure, and you rebind those values, two
of the values will get swapped (see code).

Additional information:  You seem to need at leat 7 real values for this
problem to occur.  It is also important that they first be generated 
inside a functor.  It is seems necesary that the rebinding is taking
place in a function that has at least two cases to it, and that the
argument to the function is itself generated by a function application.

In the code, the tuple at the end paira calculated values with what they
should be.
Code:
  functor T () =
  struct
    val g = 1.0
    val f = 2.0
    val m = 3.0
    val p = 4.0
    val q = 5.0
    val u = 6.0
    val h = 7.0
  end;

  structure E =
  struct

    datatype t = A | B

    fun b _ = B

    val s = b()

    structure C = T ()

    val {g,f,m,h,p,q,u} =
	case s
	  of A =>
	     {g = C.g, f = C.f, m = C.m, h = C.h, p = C.p, q = C.q, u = C.u}
	  | _ => 
	     {g = C.g, f = C.f, m = C.m, h = C.h, p = C.p, q = C.q, u = C.u}
  end;

  val test =
  ((E.g , 1.0),(E.f , 2.0),(E.m , 3.0),(E.p ,4.0),(E.q , 5.0),(E.u , 6.0),
   (E.h , 7.0 ))

Transcript:
  tiree% /home/sml/Versions/110.7/bin/sml
  Standard ML of New Jersey v110.7 [FLINT v1.41], June 2, 1998
  val use = fn : string -> unit
  - use "pay.sml";
  [opening pay.sml]
  functor T : <sig>
  structure E :
    sig
      structure C : <sig>
      datatype t = A | B
      val b : 'a -> t
      val f : real
      val g : real
      val h : real
      val m : real
      val p : real
      val q : real
      val s : t
      val u : real
    end
  val test =
    ((1.0,1.0),(2.0,2.0),(3.0,3.0),(4.0,4.0),(6.0,5.0),(5.0,6.0),(7.0,7.0))
    : (real * real) * (real * real) * (real * real) * (real * real)
      * (real * real) * (real * real) * (real * real)
  val it = () : unit

Comments:
Fix: [Zhong, 7/13/98]
  It is caused by the usual misuse of "foldr" (instead of "foldl")
  in one of my argument spilling algorithms.

  The fix of Elsa's bug involves changes to the 
  file named "FLINT/cps/cpstrans.sml" (attached) in 110.7.
Test: bug1409.1.sml
Owner: Zhong
Status: fixed in 110.7.2 [Zhong, 7/13/98]
----------------------------------------------------------------------
Number: 1410
Title: no comments in %header
Keywords: %header comments
Submitter: Elsa L. Gunter   elsa@research.bell-labs.com
Date: 07/13/98
Version: 110.0.3
System: Any/All Any Unix 
Subsystem: ML-Yacc
Severity: minor
Problem:
  Comments in the argument to %header in the input .grm file to ml-yacc
  are not correctly parsed.  In fact, they cause a false error to be
  generated.

Code:
  %%
  %term ident of string | EOF 
  %nonterm START of lambda_term
  %eop EOF
  %pos int
  %header (functor L()(* test *))
  %%
  START : ident (ident)

Transcript:
  tiree% ml-yacc lam.grm
  lam.grm, line 6: Error: syntax error: deleting  PERCENT_HEADER BOGUS_VALUE UNKNOWN
  ? ml-yacc: uncaught exception Semantic

Comments:
  I originally encountered this bug because it occurs in the file
  yacc.grm in the code for ml-yacc.  I will probably fix it myself
  eventually if nobody else gets there first.
Fix:
Test: 
Owner: Andrew
Status: open
----------------------------------------------------------------------
Number: 1411
Title: bad type checking of lazy fun declaration
Keywords: lazy, type checking
Submitter: Philip Wadler <wadler@research.bell-labs.com>
Date: 7/8/98
Version: 110.7.1
System: -
Severity: major 
Problem: 
  An incorrect type is inferred for a lazy fun declaration
Code:
  Compiler.Control.lazysml := true;

  datatype lazy 'a stream = Nil | Cons of 'a * 'a stream;

  fun lazy map f Nil =  Nil
	 | map f (Cons(x,xs))  =  Cons(f x, map f xs);

Transcript:
  datatype 'a stream = Cons of 'a * 'a stream ?.susp | Nil
  type 'a stream = 'a ?.stream ?.susp
  stdIn:10.3-11.47 Warning: match nonexhaustive

  stdIn:10.3-11.47 Warning: match nonexhaustive
	    (f,$ Nil) => ...

  val map = fn : 'a -> 'b ?.stream ?.susp -> 'c ?.stream ?.susp
Comments:
Fix:
  In elaborate/elabcore.sml, only the first clause of the map_ 
  function was being processed, because a recursive function wasn't
  recursing on the rest of the clauses.
Test: tests.lazy/bug1411.1.sml
Owner: dbm
Status: fixed in 110.7.2
----------------------------------------------------------------------
Number: 1412
Title: lazy datatype spec expands to duplicate type specs
Keywords: lazy, datatype specs, signatures
Submitter: Philip Wadler <wadler@research.bell-labs.com>
Date: 7/9/98
Version: 110.7.1
System: -
Severity: major 
Problem: 
  Because the strict and lazy type names generated by a lazy
  datatype specifications are the same, signature elaboration
  complains about duplicate specifications.
Code:
  signature STREAM =
  sig
    datatype lazy stream
      = Nil
      | Cons of string * stream
  end;

  structure Stream : STREAM =
  struct
    datatype lazy  stream
      = Nil
      | Cons of string * stream
  end;

Transcript:
  - use "bug1412.1.sml";
  [opening bug1412.1.sml]
  GC #0.0.0.0.1.6:   (3 ms)
  bug1412.1.sml:5.3-7.31 Error: duplicate specifications for type constructor stream in signature
Comments:
  (Andrew being too clever!)
Fix: make the internal (strict) datatype name distinct from the external
  suspended version (e.g. stream! and stream, respectively), as in Wadler's
  original expansion.  This affects compiler/Semant/elaborate/elabtype.sml
  in the function elabDATATYPEdec.
Test: tests.lazy/bug1412.1.sml
Owner: dbm
Status: fixed in 110.7.2 [dbm, 7/22/98]
----------------------------------------------------------------------
Number: 1413
Title: can't read from instream from process created by Unix.execute
Keywords: Unix.exectute, TextIO, IO, processes
Submitter: Elsa Gunter
Date: 7/20/97
Version: 110.0.3, 110.7
System: mipseb-irix6.2, sparc-solaris2.5, x86-linux
Severity: major
Problem: 
  A process is created using Unix.execute, and output is sent to
  that process, flushed, and the output stream is closed.  When
  input from the process is read it contains (part of) a "Bad file number" 
  error message.
Code:
  val execute = Unix.streamsOf o Unix.execute;
  val (instrm,outstrm) = execute("cat",[]);
  TextIO.output(outstrm,"abcd");
  TextIO.flushOut outstrm;
  TextIO.closeOut outstrm;
  val s = TextIO.inputAll instrm;

Transcript:
  - val execute = Unix.streamsOf o Unix.execute;
  val execute = fn : string * string list -> TextIO.instream * TextIO.outstream
  - val (instrm,outstrm) = execute("cat",[]);
  val instrm = - : TextIO.instream
  val outstrm = - : TextIO.outstream
  - TextIO.output(outstrm,"abcd");
  val it = () : unit
  - TextIO.flushOut outstrm;
  val it = () : unit
  - TextIO.closeOut outstrm;
  val it = () : unit
  - val s = TextIO.inputAll instrm;
  val s =
    "\nuncaught exception SysErr: Bad file number [badf]\n  raised at: <close#"
    : TextIO.vector

Comments:
  Same happens if the command executed is "date" and the outstream
  returned is immediately closed.

  It works ok if "/bin/cat" is used as the command name instead of
  "cat", so the problem seems to be that execute does not use the
  users PATH environment variable to find the full path of the command.
 [Elsa, 7/23/98]
  Using Unix.executeInEnv and passing an environment argument that
  includes the users PATH binding does the same thing.
Fix:
Test: bug1413.1.sml
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1414
Title: Compiler bug: Instantiate: unexpected DATATYPE 354
Keywords: modules, signatures, instantiate, sharing
Submitter: Michael Siff <siff@cs.wisc.edu>
Date: 7/21/98
Version: 110.7 (not 110.0.3?)
System: -
Severity: major 
Problem: 
  Instantiating a signature containing a sharing constraint causes
  "Compiler bug: Instantiate: unexpected DATATYPE 354"
Code:
  signature SIG1 = 
  sig
    type t
    type u

    datatype c = C of u 
    and d = D of t * c   (* needed! *)
  end;

  signature SIG2 =
  sig
    type s = int         (* <------ that is the culprit I think *)
  end;

  signature SIG3 = 
  sig
    structure A : SIG1 
    structure B : SIG2
      sharing type B.s = A.c  (* not valid *)
  end;

Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  - use "test/bugs/bug1414.1.sml";
  [opening test/bugs/bug1414.1.sml]
  signature SIG1 =
    sig
      type t
      type u
      datatype c = C of u
      datatype d = D of t * c
    end
  signature SIG2 = sig type s = int end
  Error: Compiler bug: Instantiate: unexpected DATATYPE 354

Comments:
 [dbm]
  The sharing should be rejected, because int can't share with
  a datatype, but a sensible error message should be generated
  instead of a compiler bug.

  It may be that 110.0.3 accepts this code without an error because
  instantiation is not turned on for signature declarations.

 [Michael Siff, 7/21/98]
  But actually, my original code (not as simple) was like:

    signature SIG2 
      sig
	structure A : ORD_KEY
	type s = A.ord_key
      end

  and this too resulted in bug 1414.

  I have since corrected it to be:

    signature SIG2 
      sig
	structure A : ORD_KEY
	type s
	sharing type s = A.ord_key
      end
Fix:
Test: bug1414.1.sml, bug1414.2.sml
Owner: dbm, Zhong
Status: fixed in 110.9 (dbm)
----------------------------------------------------------------------
Number: 1415
Title:       Date.fmt raises Date on large strings
Keywords:    Date.fmt
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        8/6/98
Version:     110.7
System:      x86-linux
Severity:    
Problem:     
  Date.fmt raises Date when you pass it a format string of length 512 or
  greater, as demonstrated by the following program.

Code:        
  Date.fmt
  (implode(List.tabulate(512, fn _ => #" ")))
  (Date.fromTimeLocal(Time.now()));

Transcript:
  uncaught exception Date
    raised at: boot/date.sml:60.41-60.45

Comments:    
Fix:         
  runtime/c-libs/smlnj-date/strftime.c should allocate a larger buffer
  when the call to strftime returns 0.

 [jhr]
  Upon further examination, I think that this should be fixed in SML.
  We can break the format string apart and feed it to strftime a
  piece at a time.  Once we have all of the results, then we can
  concatenate the final result.  This avoids the potential problem
  of stressing the C memory allocator in pathalogical cases.

 [Weeks, 8/6/98]
  I agree that this works, but you'll have to be pretty conservative on
  the chunk size, or make a pass over the format string to get an upper
  bound on the size of the result string.

 [jhr, 8/6/98]
  We need to make a pass over the format string anyway to check for illegal
  format options (we cannot rely on strftime to do this).  This is something
  that our implementation does not do yet, but it should.

Test: bug1415.1.sml
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1416
Title:       Date.fmt produces incorrect results on %j, %U, %W, and %<other>
Keywords:    Date.fmt
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        8/6/98
Version:     110.7
System:      x86-linux
Severity:    
Problem: 
  Date.fmt produces incorrect results for format directives that
  depend on tm_yday, i.e. %j, %U, and %W.  It also does not follow
  the spec for format directives that are undefined, e.g. %z.

Code:        
  Date.fmt("%j %U %W %z") (Date.fromTimeLocal(Time.now()))
Transcript:  
  val it = "001 00 00 " : string
Comments:    
Fix:         
  In PervEnv/Basis/date.sml toTM should return the appropriate value for
  tm_yday, not 0.

Test: bug1416.1.sml 
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1417
Title: problems with datatype replication in functors
Keywords:    modules, datatype replication
Submitter:   Chris Paris <cap@cmu.edu>
Date:        8/14/98
Version:     110
System:      sparc-solaris2.5 (untested on others)
Severity:    life threatening!
Problem:     Datatype replication involving mutually recursive
	     datatypes sometimes fails.
Code:

(* bug1417.1.sml *)
  signature DB =
  sig
    type foo = int
    datatype partition_classes = STATIC_CLASSES of foo
    and alloc_class = ALLOC_CLASS of unit
  end;

  functor Evolve(Db : DB) = 
  struct 
    datatype partition_classes = datatype Db.partition_classes
  end;

(* bug1417.2.sml *)

  signature DB =
  sig
    datatype transaction = TRANSACTION of lockinfo
    and lockinfo = READLOCK of unit
  end

  functor Evolve(Db : DB) : DB = 
  struct 
    datatype lockinfo = datatype Db.lockinfo
    datatype transaction = datatype Db.transaction
  end;

Another example from Leif Kornstaedt <kornstae@ps.uni-sb.de> (7/5/99):

(* bug1417.3.sml *)

  signature S =
  sig
    type t
    datatype u = C1
    and v = C2 of t
  end

  functor F(type t) :> S where type t = t =
  struct
    type t = t
    datatype u = C1
    and v = C2 of t
  end

  structure M1 = F(type t = int)

  structure M2 =
  struct
    datatype v = datatype M1.v
  end

Transcript:

  Standard ML of New Jersey, Version 110, December 9, 1997 [CM; autoload enabled]
  - use "bug1417.1.sml";
  [opening bug1417.1.sml]
  Error: Compiler bug: TypesUtil: expandTyc:PATHtyc
  - use "bug1417.2.sml";
  [opening bug1417.2.sml]
  bug1417.2.sml:7.13-11.8 Error: value type in structure doesn't match signature spec
      name: TRANSACTION
    spec:   Db.lockinfo -> Db.transaction
    actual: ?.lockinfo -> Db.transaction

Comments:    Works in 110.7 and 110.8. However, it is not practical
	     for me to port from 110 to the current bleeding edge.
Fix:         
Test: bug1417.1.sml, bug1417.2.sml 
Owner: dbm, Zhong
Status: fixed in 110.8, open in 110.0.4
----------------------------------------------------------------------
Number: 1418
Title: CM.set_path is a constant function
Keywords: CM, CMPATH, CM.set_path
Submitter: Elsa Gunter <elsa@research.bell-labs.com>
Date: 8/13/98
Version: 110.0.8  (110.0.3?)
System: -
Severity: major
Problem: 
  CM.set_path always returns nil, even after a path has been set.
Transcript:
  - CM.set_path NONE;
  val it = [] : string list
  - CM.set_path (SOME ["/home/sml/Versions/110.8/lib"]);
  val it = [] : string list
  - CM.set_path NONE;
  val it = [] : string list
Comments:
Fix: (Matthias verify?)
  In cm/cm.sml change the definition of set_path to:

    fun set_path arg =
	(if isSome arg then EntityDesc.clear () else ();
	 map AbsPath.elab
	     (CmConfig.path
	      (Option.map (List.map AbsPath.rigidcur) arg)))
Test: tests.cm/bug1418.1.sml
Owner: Blume
Status: fixed in 110.9 (Blume)
----------------------------------------------------------------------
Number: 1419
Title: incorrect printing of signature containing "where type"
Keywords: signatures, where type, printing
Submitter: Dave MacQueen
Date: 8/17/98
Version: 110.0.3, 110.8
System: -
Severity: minor 
Problem: 
  When a signature including a where type specification is printed
  it can appear as though free variable capture has occurred, even
  though it hasn't.
Code:
  signature S = sig type s type t end;
  signature S1 =
  sig
    type s
    structure A : S where type t = s
  end;
Transcript:
  - signature S = sig type s type t end;
  signature S =
    sig
      type s
      type t
    end
  - signature S1 =
  = sig
  =   type s
  =   structure A : S where type t = s
  = end;
  signature S1 =
    sig
      type s
      structure A :
	sig
	  type s
	  type t = s   (* this refers to the outer s! *)
	end
    end
Comments:
  This is a result of the way where types are elaborated.  The type
  definition is moved inward to the site of the type specification
  that it applies to, but after the rhs has been elaborated, so
  there is no danger of free variable capture.  But when printed,
  the transformed signature looks like free variable capture has 
  happened.
Fix:
Test: bug1419.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1420
Title: improper printing of "multiple defs at tycon spec" warning message
Keywords: error messages, printing
Submitter: Dave MacQueen
Date: 8/17/98
Version: 110.8
System: -
Severity: medium
Problem: 
  An "<empty spath>" is printed for the path of a tycon spec in
  the "multiple defs at tycon spec" warning message.
Code:
Transcript:
  - use "test/bugs/bug1386.1.sml";
  [opening test/bugs/bug1386.1.sml]
  signature CAT =
    sig
      eqtype cat
      val c : cat
    end
  signature L_F =
    sig
      eqtype t
      structure Cat :
	sig
	  type cat = t
	  val c : cat
	end
      val r : t
    end
  test/bugs/bug1386.1.sml:17.9-22.4 Warning: multiple defs at tycon spec: <empty spath>
      (secondary definitions ignored)
  test/bugs/bug1386.1.sml:21.13-21.27 Error: operator and operand don't agree [tycon mismatch]
    operator domain: ?.cat * ?.cat
    operand:         ?.cat * ?.t
    in expression:
      Cat.c = LF.r
Comments:
Fix:
Test: bug1420.1.sml (derived from bug1386.1.sml)
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1421
Title: incorrect type comparison for val spec in signature match
Keywords: signature matching
Submitter: Norman Ramsey <nr@cs.virginia.edu>
Date: 8/18/98
Version: 110.0.3, 110.8
System: -
Severity: major 
Problem: 
  The following declarations are rejected, but should not be.
Code:
  signature E =
  sig
    type 'a err
    val OK : 'a -> 'a err
    val map : ('a -> 'b) -> 'a err -> 'b err
  end;

  structure E1 : E =
  struct
    type 'a err = 'a
    fun OK x = x
    fun map1 f = f
    val map = map1 (* causes an error ... *)
  end;
Transcript:
  Standard ML of New Jersey, Version 110.0.3, January 30, 1998
  - use "test/bugs/bug1421.1.sml";
  [opening test/bugs/bug1421.1.sml]
  signature E =
    sig
      type 'a err
      val OK : 'a -> 'a err
      val map : ('a -> 'b) -> 'a err -> 'b err
    end
  test/bugs/bug1421.1.sml:9.1-14.4 Error: value type in structure doesn't match signature spec
      name: map
    spec:   ('a -> 'b) -> 'a ?.E1.err -> 'b ?.E1.err
    actual: 'a -> 'a

Comments:
Fix:
  In typesutil.sml, function equalType, add "IBOUND _" in addition
  to "VARty _" patterns for fourth and fifth clauses of function eq.
Test: bug1421.1.sml
Owner: Zhong
Status: fixed in 110.9, 110.0.4 [Zhong, 8/18/98]
----------------------------------------------------------------------
Number: 1422
Title: Core dump on Sparc when using lazy features
Keywords: lazy, sparc
Submitter: Matthias Blume   blume@kurims.kyoto-u.ac.jp
Date: 08/18/98
Version: 110.8
System: Sparc Solaris SunOS helium 5.6 Generic_105181-04 sun4u sparc SUNW,Ultra-1
Subsystem: SML compiler
Severity: critical
Problem:
  The following code crashes version 110.8 with a core dump on the
  Sparc (Solaris on Ultra-1).  The same code does NOT crash on x86
  (Linux).

  Could this be related to bug 1389?  If so, this would mean that the
  problem is probably NOT in the code generator since we are using a
  brand-new one...

  A problem in the runtime system/GC perhaps?

Code:
  Compiler.Control.lazysml := true;
  datatype lazy l = Nil | Cons of int * l;
  fun fst _ Nil = []
    | fst 0 _ = []
    | fst n (Cons (x, l)) = x :: fst (n - 1) l;
  val rec lazy ones = Cons (1, ones);
  fst 10 ones;

Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  - Compiler.Control.lazysml := true;
  val it = () : unit
  - datatype lazy l = Nil | Cons of int * l;
  datatype l! = Cons of int * l! ?.susp | Nil
  type l = l! ?.susp
  - fun fst _ Nil = []
  =   | fst 0 _ = []
  =   | fst n (Cons (x, l)) = x :: fst (n - 1) l;
  val fst = fn : int -> l -> int list
  - val rec lazy ones = Cons (1, ones);
  GC #0.0.0.0.1.7:   (10 ms)
  val ones = $$ : l! ?.susp
  - fst 10 ones;
  Bus error

Comments:
  The same code runs fine on the X86 (Pentium notebook running Linux):

  [blume@hana blume]$ ML/8/bin/sml
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  val use = fn : string -> unit
  - Compiler.Control.lazysml := true;
  val it = () : unit
  - datatype lazy l = Nil | Cons of int * l;
  datatype l! = Cons of int * l! ?.susp | Nil
  type l = l! ?.susp
  - fun fst _ Nil = []
  =   | fst 0 _ = []
  =   | fst n (Cons (x, l)) = x :: fst (n - 1) l;
  val fst = fn : int -> l -> int list
  - val rec lazy ones = Cons (1, ones);
  GC #0.0.0.0.1.19:   (10 ms)
  val ones = $$ : l! ?.susp
  - fst 10 ones;
  val it = [1,1,1,1,1,1,1,1,1,1] : int list

 [Matthias, 8/28/98]
  > [Lal] I have not been able to find the bug exhibited by the lazy evaluation
  > program you sent. It is clear that it is not specific to the sparc but 
  > generic to MLRISC. 
  > 
  > I therefore suspected the implementation of mkspecial, getspecial, and 
  > setspecial -- but they all seem to be correct.

  Well, maybe they aren't correct after all.

  I now recall an incident that occured a while ago:
  CM crashed on me (with a bus error), and I was able to resolve that
  problem (although it was never explained) by eliminating the use of
  the built-in "suspension" facility (delay/force).  The problem occured 
  on the Alpha, which at that time was one of the few MLRISC-based
  implementations.  Since I assume that the implementation technology
  for delay/force back then and laziness now is the same, I would really 
  suggest we should look into this again.

  (Back when the problem occured first, someone more or less dismissed
  it as unimportant and surely not to be blamed on get/set/mkspecial.  I
  didn't pursue the issue any further because it didn't seem
  mission-critical at the time.)

Fix:
  [Lal] I have committed a change to CodeGen/main/mlriscGen.sml that fixes 
  bug1422.
Test: bug1422.1.sml
Owner: Leung, Lal?
Status: fixed in 110.8.1 [Lal]
----------------------------------------------------------------------
Number: 1423
Title: 2.0 + 2.0 = nan
Keywords: reals
Submitter: George Russell   george@persimmon.com
Date: 08/10/98
Version: 110.8
System: Sparc Solaris uname -a returns SunOS rosalind 5.5.1 Generic_103640-18 sun4m sparc SUNW,...
Subsystem: SML compiler
Severity: critical
Problem:
Floating point doesn't work!
Code:
2.0 + 2.0;
Transcript:
Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
val use = fn : string -> unit
- 2.0 + 2.0;
val it = nan : real
Comments:
  [Alan] Unfortunately, we are unable to reproduce on this end.
  [George] That's odd.  Are you sure you've tried it on Sparc/Solaris?
    I was wondering whether this new ML-RISC was to blame.
  [Alan]
     Yes, it's odd.

     I've tried to repro it on various sparc/solaris/sun-os combinations with
     no luck:


     SunOS valis 5.6 Generic_105181-06 sun4m sparc SUNW,SPARCstation-5
     SunOS optlab2 5.5.1 Generic_103640-08 sun4u sparc SUNW,Ultra-1
     SunOS merv 4.1.4 2 sun4m
     SunOS vex 5.5.1 Generic_103640-18 sun4u sparc SUNW,Ultra-2

     The new MLRISC is likely to be the culprit.

  [Alan] Could you also check to see if Real.==(2.0+2.0, 4.0) returns true?
  [George] It returns false

  [Alan]
     That's very strange.  Could you send me the dumps for the following?

     val a = 2.0
     val b = 2.0 + 2.0
     val c = Real.toManExp a
     val d = Real.toManExp b
     val e = Real.toManExp Real.posInf
     val f = Real.==(1.0/0.0,Real.posInf)
     val g = Real.==(2.0+2.0,Real.posInf)

     and

     Compiler.Control.CG.printFlowgraph := Compiler.Control.CG.AFTER_RA;
     2.0 + 2.0;

  [Lal]
     Only occurs on older sparcs.
Fix:

Test: bug1423.1.sml
Owner: Alan Leung
Status: fixed in 110.8.1 [Leung, Lal]
----------------------------------------------------------------------
Number: 1424
Title: inadaquate signature matching error message
Keywords: 
Submitter: 
Date: 
Version: 
System: 
Severity: 
Problem: 
  Bad signature matching error message. Does not specify which type names
  did not match.

Transcript:
  ../MLRISC/X86/X86RegAlloc.sml:1.9-80.4 Error: type name does not match definitional specification
  ../MLRISC/X86/X86RegAlloc.sml:1.9-80.4 Error: type name does not match definitional specification
Comments:
Fix:
Test: ?
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1425
Title: Compiler bug: Literals: unexpected CPS header in litsplit
Keywords: code generation, floating point
Submitter: John Reppy
Date: 5/21/98
Version: 110.5.1
System: ?
Severity: major 
Problem: real division causes compiler bug
Code:
Transcript:
  - 1.1-1.0;
  val it = 0.1 : real
  - it/2.0;
  Error: Compiler bug: Literals: unexpected CPS header in litsplit
Comments:
Fix:
Test: bug1425.1.sml
Owner: Zhong
Status: fixed in 110.6
----------------------------------------------------------------------
Number: 1426
Title: smlnj-c interface function, second call core dumps
Keywords: smlnj-c, foreign function call
Submitter: "Karsten Lueth" <Karsten.Lueth@Informatik.Uni-Oldenburg.DE>
Date: 7/28/98
Version: 110.0.3
System: sparc/solaris
Severity: major
Problem: 
  I have some problems with C interface of SML.110.  When I try to call
  a ML function from C, it will only work at the first call.  When call
  the same function for a second time, it will crash with a segmentaton
  fault.
Code:
  The C function:
  void x(int (*f)())
  {
    int i;
    i = f();
    i = f();
  }

  The ML registration: 
  val x = registerCFn("x", [CfunctionT([],CintT)], CvoidT);
Transcript:
Comments:
Fix: Riccardo fixed the bug which had to do with gc.
Test: -
Owner: Riccardo, jhr
Status: fixed in 110.8.1 [Riccardo]
----------------------------------------------------------------------
Number: 1427
Title: End-of-file marks in Stream IO
Keywords: IO
Submitter: Andrew Appel  <appel@princeton.edu>
Date: 08/17/98
Version: 110.8
System: Any/All Any Unix 
Subsystem: SML basis library
Severity: minor
Problem:
  When buffered input is done from a stream device (pipe, tty, socket),
  there can be multiple end-of-file marks (i.e., zero-length inputs).
  This is only partially reflected in functional stream input.
  The program below demonstrates, when the following sequence is typed
  into the interactive standard input: "abcdef\n^D^Dabcde\n"

  The sequence of inputs should be, "abcdef\n", "", "", "abcde\n",
  and indeed the first time through this is the case.
  But the second time the same functional input stream is read,
  the sequence is "abcdef\n", "abcde\n"; the empty strings are lost.
  This violates the rule that for any TextIO.StreamIO.instream f,

   input(f) = input(f)

Code:
  structure TS = TextIO.StreamIO
  fun test f =
    let val f0 = TextIO.getInstream f
	fun g(i,0) = ()
	  | g(i,k) = let val (s,i') = TS.input i
		   in print (Int.toString (size s) ^ "\n");
		      g(i',k-1)
		  end
     in g(f0,4); print "***\n"; g(f0,4)
    end

Transcript:
  7
  0
  0
  6
  ***
  7
  6

Comments:
  Fix this in bin-io-fn.sml and text-io-fn.sml by having
  an explicit end-of-file mark in the sequence of buffers.

Fix:
Test: 
Owner: jhr?
Status: fixed in 110.9.1
----------------------------------------------------------------------
Number: 1428
Title: CM docs out of date
Keywords: Tools.stdShellProcessor
Submitter: Norman Ramsey  <nr@cs.virginia.edu>
Date: 08/18/98
Version: 110.8
System: Any/All Any Unix 
Subsystem: Compilation manager (CM)
Severity: minor
Problem:
Tools.stdShellProcessor appears to have a new type
which is not reflected in the example on page 23
of the manual:

lex+source.nw:9.2-10.69 Error: operator and operand don't agree [tycon mismatch]
  operator domain: {mkCommand:unit -> string, tool:string}
  operand:         {command:string, tool:string}
  in expression:
    Tools.stdShellProcessor {command=command,tool="ML-Lex+"}

Code:
  functor LexSourceFun (structure Tools: CMTOOLS
			val command: string) =
  struct

      local
	  val runlex =
	      Tools.stdShellProcessor { command = command, tool = "ML-Lex+" }

	  fun rule source = let
	      val smlfile = source ^ ".sml"
	  in
	      [(smlfile, SOME "sml")]
	  end

	  val validator = Tools.stdTStampValidator

	  val processor = runlex

	  (* install MlLex class *)
	  open Tools
	  val class = "mllex+"
	  fun sfx s = addClassifier (stdSfxClassifier { sfx = s, class = class })
      in
	  val _ = addToolClass { class = class,
				 rule = dontcare rule,
				 validator = validator,
				 processor = processor }
	  val _ = sfx "lex+"
	  val _ = sfx "l+"
      end
  end
Transcript:
  [opening lex+source.sml]
  lex+source.nw:9.2-10.69 Error: operator and operand don't agree [tycon mismatch]
    operator domain: {mkCommand:unit -> string, tool:string}
    operand:         {command:string, tool:string}
    in expression:
      Tools.stdShellProcessor {command=command,tool="ML-Lex+"}

Comments:
Fix:
  update the documentation

Test: 
Owner: Blume
Status: fixed in 110.8.2 (Blume)
----------------------------------------------------------------------
Number: 1429
Title: two problems with StreamIO.setPosOut
Keywords: I/O, StreamIO, setPosOut
Submitter: Andrew Appel
Date: 8/19/98
Version: 110.8
System: -
Severity: medium 
Problem: 
  In reading text-io-fn.sml (StreamIO.setPosOut)
  I noticed two minor bugs:

  1. setPosOut should flush the buffer before changing position
  2. setPosOut raises an exception whose string refers to "getPosOut"
Comments:
Fix:
Test:
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1430
Title: heap2exec broken
Keywords: heap2exec, executables
Submitter: Carlos Puchol <cpg@research.bell-labs.com>
Date: 8/20/98
Version: 
System: 
Severity: 
Problem: 
  it seems like heap2exec is not bundling things right.
Transcript:
$ /usr/local/sml/110/bin/sml
+@SMLload=tl2strl.heap.sparc-solaris
Usage: tl2strl [-v] [-cr] [-ch] [-h] <file>                                     
$ /usr/local/sml/110/bin/heap2exec
+/usr/local/sml/110/runtime-standalone/run.sparc-solaris
+tl2strl.heap.sparc-solaris tl2strl
bundling /usr/local/sml/110/runtime-standalone/run.sparc-solaris
bundling tl2strl.heap.sparc-solaris
setting heap offset to 167556.
done.
$ ./tl2strl
./tl2strl: Fatal error -- unable to open heap image "sml-image"

Comments:
Fix:
Test:
Owner: Lorenz
Status: open
----------------------------------------------------------------------
Number: 1431
Title: yypos in ml-lex is off by one (or two)
Keywords: ml-lex
Submitter: John Reppy  <jhr@research.bell-labs.com>
Submitter: George Russell  <george@persimmon.co.uk>
Date: 08/22/98, 9/8/98
Version: 110.0.3
System: Any/All Any Unix 
Subsystem: ML-Lex
Severity: major
Problem:
  The first character in the input stream is being assigned position 2.
  It probably should get the value 0, since this would correspond with
  standard indexing conventions for ML, but a value of 1 would also
  be okay --- 2 seems like a bug.
Code:
  (ML-Lex file test.lex follows)
  type lexresult=int
  val error=TextIO.print
  fun eof _ = ~1
  %%
  %%
  .  => (print("yypos="^Int.toString yypos);Char.ord(String.sub(yytext,0)));
Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  val use = fn : string -> unit
  - use "test.lex.sml";
  [opening test.lex.sml]
  GC #0.0.0.0.1.7:   (14 ms)
  GC #0.0.0.0.2.27:   (21 ms)
  GC #0.0.0.1.3.46:   (34 ms)
  structure Mlex :
    sig
      structure Internal : <sig>
      structure UserDeclarations : <sig>
      exception LexError
      val makeLexer : (int -> string) -> unit -> Internal.result
    end
  val it = () : unit
  - Mlex.makeLexer(fn i=>TextIO.inputN(TextIO.stdIn,i))();
  a
  yypos=2val it = 97 : Mlex.Internal.result

Comments:
 [jhr]
  This is an annoying bug (I spent half a day discovering it just
  a couple of weeks ago).  Andrew Appel claims that it has been known
  for some time, but there was a concern that if it was fixed, then
  the fix might break people's code that depended on the incorrect
  behavior.  Personally, I'd like to see it fixed, but at least we
  should document it.
Fix:
Test: -
Owner: Andrew?
Status: open
----------------------------------------------------------------------
Number: 1432
Title: signature match fails for datatype specs if "where type" is used
Keywords: signatures, datatypes, "where" clause
Submitter: Matthias Blume   <blume@kurims.kyoto-u.ac.jp>
Date: 08/31/98
Version: 110.8.1
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: major
Problem:
  Information about a type being a datatype is lost when the type
  spec was augmented using a "where type" clause.  This is true even
  if left and right side of the equation in the "where" clause are
  already known to be datatypes.

  This problem is new in 110.8.1.  It did not occur in 110.8.  (The
  problem occurs within the CML sources.)

Code:
  signature S1 =
  sig
    datatype dt = DT
  end;

  signature S2 =
  sig
    structure nestedS1 : S1
  end;

  structure globalS1 =
  struct
    datatype dt = DT
  end;

  functor F2 (
      structure argS : S2
	where type nestedS1.dt = globalS1.dt
    ) = struct

      structure myS1 : S1 = argS.nestedS1
  end;

Transcript:
  - use "t.sml";
  [opening t.sml]
  t.sml:18.5-18.40 Error: type dt must be a datatype

Comments:
  In the source code given above, if you delete the "where type" clause
  on line 15, then everything elaborates fine.

 [Matthias (original message)]
  I tried to locally fix the CML sources to be able to compile them
  under 110.8.1.  But I run into a strange problem.  When compiling
  src/cml/src/IO/text-io-fn.sml I see the following errors:

  ...
  [compiling IO/text-io-fn.sml -> IO/CM/sparc-unix/text-io-fn.sml.bin]
  IO/text-io-fn.sml:880.24-883.31 Error: type reader must be a datatype
  IO/text-io-fn.sml:880.24-883.31 Error: type writer must be a datatype

  This message refers to the instantiation of the ChanIO functor.
  Apparently, somehow the compiler seems to think that the reader/writer 
  types in PIO aren't datatypes.  Why is that? If they really aren't,
  then I can't seem to understand the structure of the sources.  But if
  they are, then why does the compiler think they aren't?  Is this
  somehow related to Dave's fix of bug 1364?  Does the fix need another
  fix?

Fix:
  Added "repl:bool" field to TYCspec argument to indicate when a spec
  is a datatype replication spec (either directly or indirectly via a
  "where type" definition that applies to the spec).  The repl field is
  definied in ElabSig (Semant/elaborate/elabsig.sml).  The information
  is used in Instantiate, where the type instances associated with a
  repl spec are unwrapped (in function fixUpTycEnt).  This will make
  checkTycBinding in SigMatch work properly when matching a datatype
  spec against a type created by signature instantiation (as in the
  example above).
Test: bug1432.1.sml, ..., bug1432.8.sml
Owner: dbm
Status: fixed in 110.9 (110.8.2) and 110.0.4 [dbm, 9/14/98]
----------------------------------------------------------------------
Number: 1433
Title: eqtype u=t doesn't force eqtype.
Keywords: modules
Submitter: George Russell   george@persimmon.co.uk
Date: 08/28/98
Version: 110.8
System: Alpha Digital Unix 4.0B
Subsystem: SML compiler
Severity: minor
Problem:
  eqtype t=u seems to be an SML/NJ extension so it is not defined how
  it should work, but in my opinion this code should typecheck.
Code:
  structure A :> sig type t eqtype u=t val v: u end=
  struct type t=int type u=int val v=1 end;
  (A.v=A.v);
Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  val use = fn : string -> unit
  - structure A:>sig type t eqtype u=t val v:u end =
  = struct type t=int type u=int val v=1 end;
  structure A :
    sig
      type t
      type u = t
      val v : u
    end
  - (A.v=A.v);
  stdIn:8.1-8.10 Error: operator and operand don't agree [equality type required]
    operator domain: ''Z * ''Z
    operand:         A.u * A.u
    in expression:
      A.v = A.v

Comments:
  See bug 1152 (which appears to be related but which was fixed).

 [dbm, 9/10/98]
  Thanks for the bug report, which is now bug 1433.  There is certainly
  something bogus here, since A.t is abstract (and therefore not an 
  equality type), while A.u is specified to be an equality type and
  is equal to A.t.  Probably there should be an error when the signature
  constraint is matched in the declaration of A.

  You are right that the "eqtype u = t" is not supported in the SML '97
  Definition, but I believe that one can construct an equivalent
  situation with "where type":

    signature S =
    sig
      type t
      structure X : sig eqtype u end where type u = t
      val v : X.u
    end;

  This signature should not elaborate successfully according to rule (64),
  but it currently does elaborate in SML/NJ 110.0.3 through 110.8.

Fix:
  Partial fix, for direct eqtype definitional specs:
   Added an error check to elabTYPEspec in elabsig.sml to generate
   an error message when an eqtype spec includes a definition.
   This still leaves open the problem of what to do when a definition
   is applied to an eqtype spec through a where type defn.
  It is rather difficult to fix the "where type" version.  The
  problem is that when the rhs of the where type def (here "t")
  is elaborated by elabType within ElabSig, the type constructed contains
  the relatized (PATHtyc) version of T, and it is not possible to
  determine the equality property of PATHtycs.  Perhaps this could
  be dealt with by adding an equality property field to PATHtycs.
Test: bug1433.1.sml, bug1433.2.sml
Owner: dbm
Status: open  (partially fixed in 110.9)
----------------------------------------------------------------------
Number: 1434
Title: bogus "Error: non-constructor applied to argument in pattern: ::"
Keywords: types patterns list infix
Submitter: Elsa L. Gunter   elsa@research.bell-labs.com
Date: 09/01/98
Version: 110.8
System: x86 Linux 2.0.0
Subsystem: SML compiler
Severity: minor
Problem:
  When a non-existant structure is opened within another structure,
  subsequent occurrences of :: in patterns fail to be treated as
  constructors and raise a bogus 
  "Error: non-constructor applied to argument in pattern: ::"
  message.
Code:
  structure A =
  struct
    open B
    val (x::y) = [1,2]
  end;

Transcript:
  coll% sml
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  val use = fn : string -> unit
  - use "test.sml";
  [opening test.sml]
  test.sml:3.1-3.7 Error: unbound structure: B
  test.sml:4.5-4.29 Error: non-constructor applied to argument in pattern: ::
  - structure A =
  struct
  open B
  val (x::y) = [1,2]
  end;
  = = = = stdIn:8.1-8.7 Error: unbound structure: B
  stdIn:9.5-9.19 Error: non-constructor applied to argument in pattern: ::

Comments:
Fix:
Test: bug1434.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1435
Title: ML-Yacc documentation needs to be updated
Keywords: ml-yacc, documentation
Submitter: John Reppy
Date: 8/19/08
Version: 110.0.3 - 110.8
System: -
Severity: major 
Problem: 
  The ML-Yacc documentation ought to be updated to reflect the use
  of CM (e.g., section 5 currently talks about loading "base.sml").
Comments:
Fix:
Test: -
Owner: Andrew?
Status: open
----------------------------------------------------------------------
Number: 1436
Title:       representation exception raised by C function
Keywords:    pretty printing, Representation exception, C interface
Submitter:   ammons@cs.wisc.edu
Date:        9/4/1998
Version:     110.0.3
System:      sparc-solaris2.6, x86-linux2.0.30
Severity:    major
Problem:
  The pretty printer throws an exception while pretty printing some
  values massaged from values returned by interfaced C code.
Code:
  C side. Add this line to cfun-list.h:

    C_CALLS_CFUNC("test",	test,	void *,	(void))

  and define test as

    void*
    test(void)
    {
      return (void*) test;
    }

  Create a new runtime.

  ML side. Register the test function.  Unwrap the returned caddr and
  wrap it back up with a new datatype, as in the following transcript:

Transcript:
  whitelight:objs$ sml @SMLrun=./run.x86-linux 
  Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM;
  autoload enabled]
  - CM.make'("/usr/local/smlnj-110/install/smlnj-c/sources.cm");
  [starting dependency analysis]
  [scanning /usr/local/smlnj-110/install/smlnj-c/sources.cm]
  [checking
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/sources.cm.stable
  ... not usable]
  GC #0.0.0.0.1.4:   (20 ms)
  [dependency analysis completed]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/c-calls.sig.sml.bin...
  done]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cutil.sig.sml.bin...
  done]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cutil.sml.bin...
  done]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.sig.sml.bin...
  done]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.defaults.sml.bin...
  done]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.gcc-x86-linux.sml.bin...
  done]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.gcc-sparc-sunos.sml.bin...
  done]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/cc-info.cc-mipseb-irix5.sml.bin...
  done]
  [recovering
  /usr/local/smlnj-110/install/smlnj-c/CM/x86-unix/c-calls.sml.bin...
  done]
  [introducing new bindings into toplevel environment...]
  val it = () : unit
  - structure C = CCalls(structure CCInfo = GCCInfoX86Linux);
  structure C : C_CALLS
  - datatype mud = Mud of C.caddr;
  datatype mud = Mud of ?.C.CAddress.caddr
  - fun make_mud(C.Caddr a) = Mud a;
  stdIn:20.1-20.32 Warning: match nonexhaustive
	    Caddr a => ...

  val make_mud = fn : C.cdata -> mud
  - val f_test = C.registerAutoFreeCFn("test", [], C.CaddrT);
  val f_test = fn : C.cdata list -> C.cdata
  - f_test [];
  val it = Caddr - : C.cdata
  - make_mud(f_test []);

  uncaught exception Representation
    raised at: boot/Unsafe/object.sml:65.19-65.33
	       print/ppobj.sml:354.20
	       print/ppobj.sml:354.20
	       util/pp.sml:554.6
  - 
Comments:
Fix:
Test: -
Owner: Lorenz?, Zhong?
Status: open
----------------------------------------------------------------------
Number: 1437
Title:       Unix.signal missing
Keywords:    Unix, signals
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        9/8/98
Version:     110.7
System:      x86-linux
Severity:    
Problem:     
  The type signal is missing from the Unix structure.
Comments:    
Fix:         
Test: -
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1438
Title: Wrong types for TextIO.StreamIO.inputAll and TextIO.StreamIO.mkInstream
Keywords: types, IO, TextIO, StreamIO
Submitter: Elsa L. Gunter <elsa@research.bell-labs.com>
Date: 09/14/98
Version: 110.8
System: Any/All Any Unix 
Subsystem: SML basis library
Severity: minor
Problem:
  The types for inputAll and mkInstream in TextIO.StreamIO are wrong under
  Unix (but right under Win32).  They are

  TextIO.StreamIO.inputAll : ?.TextIO.instream -> TextIO.StreamIO.vector * ?.TextIO.instream
  TextIO.StreamIO.mkInstream : TextIO.StreamIO.reader * TextIO.StreamIO.vector option -> ?.TextIO.instream

  but the Standard Basis says they should be

  TextIO.StreamIO.inputAll : TextIO.StreamIO.instream -> TextIO.StreamIO.vector
  TextIO.StreamIO.mkInstream : TextIO.StreamIO.reader * TextIO.StreamIO.vector -> TextIO.Stream.instream

  That is, inputAll is returning an extra instream, and mkInstream is taking 
  a vector option instead of a vector.

  Also note that the type ?.TextIO.insteam is being printed in place of
  TextIO.StreamIO.instream.   This is rather confusing at best.

Code:
  val x = (TextIO.StreamIO.inputAll,TextIO.StreamIO.mkInstream);

Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  val use = fn : string -> unit
  - val x = (TextIO.StreamIO.inputAll,TextIO.StreamIO.mkInstream);
  val x = (fn,fn)
    : (?.TextIO.instream -> TextIO.StreamIO.vector * ?.TextIO.instream)
      * (TextIO.StreamIO.reader * TextIO.StreamIO.vector option
	 -> ?.TextIO.instream)

Comments:
  The types seem to be right under Win32, although I think it prints 
  ?.TextIO.instream in place of TextIO.StreamIO.instream there as well.

Fix:
Test: 
Owner: jhr, Appel
Status: fixed in 110.8.1 [Andrew]
----------------------------------------------------------------------
Number: 1439
Title: OS.FileSys.access raises inappropriate SysErr exception
Keywords: exception, file-system
Submitter: Elsa L. Gunter   elsa@research.bell-labs.com
Date: 09/14/98
Version: 110.8
System: Any/All Windows NT 4.0
Subsystem: SML compiler
Severity: minor
Problem:
  OS.FileSys.access raises

    "uncaught exception SysErr: access: cannot get file attributes"

  when a file doesn't exist under Windows NT, but it returns false under
  linux.

  The Standard Basis says: "The function will only raise OS.SysErr for
  errors unrelated to resolving the the pathname and related permissions,
  such as being interupted by a signal during the system call."

Code:
  (* Let "toto" be a file that doesn't exist *)
  val x = OS.FileSys.access ("toto",[]);

Transcript:
  I don't have easy access to WIndows NT at the moment, but the line in
  quotes in the Description of Problem was cut from a real session.

Comments:

Fix:

Test: 
Owner: jhr, Appel
Status: open
----------------------------------------------------------------------
Number: 1440
Title: CM.set_path has no effect in Win 32 or Irix 6.4
Keywords: CM search path
Submitter: Elsa L. Gunter   elsa@research.bell-labs.com
Date: 09/14/98
Version: 110.8
System: x86 Windows NT 4.0
Subsystem: Compilation manager (CM)
Severity: critical
Problem:
  CM.set_path always returns the same list in Win 32 and Irix 6.4.  This
  appears to
reflect an unchanging search path for CM under these operating
  systems.

Code:
  val x = (CM.set_path (SOME ["/usr/local/hol"]);
	   CM.set_path NONE);

Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  val use = fn : string -> unit
  - val x = (CM.set_path (SOME ["/usr/local/hol"]);
	   CM.set_path NONE);
  val x = [".","/home/sml/Versions/110.8/lib"] : string list

Comments:
  This works in the linux version and the solaris version. 
 [Matthias, 10/9/98]
  I have no access to a Win32 version, but (as expected) this bug does
  not seem to exist on the Irix 6.4 version.  I suspect that it was a
  transient problem related to some out-of-date sources.
  (There is no reason whatsoever why CM.set_path should behave
  differently on different systems.)

  See also bug 1418.
Fix:
Test: tests.cm/bug1418.sml
Owner: Blume
Status: fixed in 110.8.1 (IRIX, Solaris, Windows?)
----------------------------------------------------------------------
Number: 1441
Title: reading input from stdIn in emacs under Windows
Keywords: input, Windows
Submitter: Robert Harper <rwh@cs.cmu.edu>
Date: 9/14/98
Version: 110.8
System: x86/Windows
Severity: minor
Problem: 
  If I invoke a function, say, read(), that reads from stdIn,
  the trailing newline from the invocation "read();" gets read as input.
Code:
Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  - fun read () = TextIO.input TextIO.stdIn;
  val read = fn : unit -> TextIO.vector
  - read ();
  val it = "\n" : TextIO.vector

  -  (* To get this final prompt I have to hit return *)
Comments:
  This is running under emacs (emacs 20.3.1 on a PC running NT4.0SP3).
  It appears to work properly from the cmd prompt.
  Perhaps it's an emacs bug after all.
 [Lorenz, 9/15/98]
  The emacs shell mode under NT/W95 (gnu emacs) is known to be buggy
  in this respect.  I reported a number of bugs, similar to those below, 
  to Voelker over a year ago and they apparently still remain open.  
  If the problems appear at the DOS prompt as well, please let me know.  
Fix: -
Test: -
Owner: Riccardo, Lorenz
Status: not a bug
----------------------------------------------------------------------
Number: 1442
Title: EOF to terminate read terminates top level in emacs under Windows 
Keywords: input, I/O, Windows
Submitter: Robert Harper <rwh@cs.cmu.edu>
Date: 9/14/98
Version: 110.8
System: x86/Windows
Severity: minor
Problem: 
  I invoke a function, say, read(), that reads from stdIn.  Then
  if I send eof to terminate the read, it returns and then also closes
  the top level for me, exiting sml.
Transcript:
  - fun read () = TextIO.input TextIO.stdIn;
  val read = fn : unit -> TextIO.vector
  - read();
  abcdval it = "abcd" : TextIO.vector
Comments:
  This is running under emacs (emacs 20.3.1 on a PC running NT4.0SP3).
  It appears to work properly from the cmd prompt.
  Perhaps it's an emacs bug after all.
 [Lorenz, 9/15/98]
  The emacs shell mode under NT/W95 (gnu emacs) is known to be buggy
  in this respect.  I reported a number of bugs, similar to those below, 
  to Voelker over a year ago and they apparently still remain open.  
  If the problems appear at the DOS prompt as well, please let me know.  

Fix: -
Test: -
Owner: Riccardo, Lorenz
Status: not a bug
----------------------------------------------------------------------
Number: 1443
Title:       Real.toManExp broken -- wrong exponent returned. 
Keywords:    Real64.toManExp (file: real64.sml) 
Submitter:   dew@pgroup.com (David Wohlford)
Date:        9/16/1998
Version:     110.0.3
System:      any arch/any OS 
Severity:    minor/major
Problem:
  Real.toManExp returns incorrect values for the exponent of
  floating point numbers.  For example, Real.toManExp 7.0 =>
  {exp=3, man=0.875}.  The exponent should be 2.  Also, 
  Real.toManExp 0.0 returns {exp=~1022, man=0.0}.  I believe
  1.0 * (2^(e_min-1)) is the standard for representing 0.0.

  The problem seems to be that there is a spurious addition
  of 1 to the exponent to work around a previous bug in logb.
  This doesn't seem to be necessary anymore, and other code in
  the module with similar exponent-extracting needs doesn't
  do this anymore (I think -- should check to be sure).
 [dbm]
  May be related to bug 1362.
 
Code:
  Real.toManExp 7.0;
  Real.toManExp 0.0;
 
Transcript:  

  - Compiler.version;
  val it =
    {date="January 30, 1998",system="Standard ML of New Jersey",
     version_id=[110,0,3]} : {date:string, system:string, version_id:int list}
  - Real.toManExp 7.0;
  val it = {exp=3,man=0.875} : {exp:int, man:real}
  - Real.toManExp 0.0;
  val it = {exp=~1022,man=0.0} : {exp:int, man:real}
  - Real.toManExp 1.0;
  val it = {exp=1,man=0.5} : {exp:int, man:real}
 
Comments: 
  It looks like the mantissa is only correct given this 
  incorrect exponent.  With this function as it is, it is 
  hard to write a function that will take a real number and
  return/write a bit-representation of the number (e.g. for
  outputting constant initializations to a .s file).

 [Aleksandar Nanevski [mailto:aleks+@cs.cmu.edu], 7/19/00]
  Real.toManExp doesn't return the correct values for numbers close to
  maxFinite:

    - Real.toManExp Real.maxFinite;
    val it = {exp=0,man=1.79769313486e308} : {exp:int, man:real}

  when the exp should be actually 1023, and the man something else.
  Here's the code that implements this function in the Basis:

   (* AARGH!  Our version of logb gives a value that's one less than the
	  rest of the world's logb functions.
	  We should fix this systematically some time. *)

      fun toManExp x =
	case I.+(Assembly.A.logb x, 1)
	  of ~1023 => if x==0.0 then {man=x,exp=0}
		      else let val {man=m,exp=e} = toManExp(x*1048576.0)
				in {man=m,exp=I.-(e,20)}
			   end
	   | 1024 => {man=x,exp=0}
	   | i => {man=Assembly.A.scalb(x,I.~ i),exp=i}

  Now, to implement a new version of toManExp, I will not be able to
  access these Assembly.A functions.  So the code will necessarily be
  tricky and slow.  This bug has been pointed out a long time ago
  actually.  I found it in the openbug list for SML-NJ under the numbers
  1319, 1362 and 1443.

  There is also one other thing that worries me -- it involves the fp
  arithmetic on Pentium.  The Pentium has 80 bit long internal registers
  for floating point operations.  This means that after a chain of
  operations has been performed using values from the registers, the
  final result will be rounded to 64 bits and stored in memory.
  However, while this improves the stability of numerical computations,
  it is not quite by the IEEE standard (or rather, the standard is a bit
  vague on that issue).  What happens is that if your computation has
  been performed solely in the registers you'll get a different result
  then if some of the intermediate results has been pushed to memory and
  then retrieved back into a register.  So, logically equivalent
  expressions, whose equality can be proved in the IEEE standard may
  give different results, depending on how the register allocation has
  been performed.  Aside, it breaks the extended floats on Pentium,
  unless special care is taken to do these rounding after every
  operation (which is slow), or set specific FP unit flags which prevent
  the additional bits from being used -- which will probably have to be
  done by installing a C function into the runtime system.

  I haven't noticed any bad instances of this problem so far, but that's
  mainly because I didn't run too extensive tests.  Anyway, I wanted to
  make you aware of this problem, since it looks to me that the
  consequences are beyond just extended floats, and rather influence the
  correctness of the whole compiler -- it doesn't look very pretty to me
  to have provably equivalent programs (provable under the `axioms' of
  the IEEE standard) produce different values on the same machine, let
  alone on different machines.

  Again, I'm not sure that SML-NJ actually does this badly; I wouldn't
  know until I test everything. But, I have a nagging feeling, which
  grew after I saw SML-NJ basis implementation of the Real.minPos:

      local
	(* The x86 uses extended precision (80 bits) internally, therefore
	 * it is necessary to write out the result of r * 0.5 to get
	 * 64 bit precision.
	 *)
	val mem = InlineT.PolyArray.array(1, minNormalPos)
	val update = InlineT.PolyArray.update
	val subscript = InlineT.PolyArray.chkSub
	fun f () = let
	  val r = subscript(mem, 0)
	  val y = r * 0.5
	in
	   update(mem, 0, y);
	   if subscript(mem, 0) == 0.0 then r else f ()
	end
      in
	val minPos = f()
      end

  Do you perhaps happen to know any details on this already? If yes, it
  can save me some time in hacking and debugging.

 [Aleksandar Nanevski [mailto:aleks+@cs.cmu.edu], 7/20/00]
  As you asked, the file with fixes for the bugs I've noticed in the
  Real structure is attached.  Even though it still uses some of the old
  functions in the cases when they do behave correctly, it should be
  easy for the SML-NJ people to plug in the assembly primitives and fix
  the bugs in the standard basis.

(**********************************************
 ** Real.sml
 ** sml
 **
 ** Aleksandar Nanevski
 **
 ** Fixes the bug in Real.toManExp. It didn't
 ** work for numbers with exponents around
 ** Real.maxFinite.
 **
 ** Implementation of fromManExp and split which
 ** do not depend on the rounding mode.  Important
 ** since these functions are used in InfInt and
 ** Rational to approximate numbers to their
 ** nearest float.  Besides, as they were originally,
 ** they violated the specification given in the
 ** Standard Basis.
 **
 **
 ** TODO:
 ** - fromManExp should set the overflow and
 **   underflow flags when appropriate.
 **********************************************)

structure Real : REAL =
struct
    structure I = Int
    open Real
    infix ==

    val p512 = Real.fromManExp{man=1.0, exp=512}
    val q512 = Real.fromManExp{man=1.0, exp=Int.~ 512}

    fun toManExp x =
	if x >= 1.0 then
	    (* the exponent is positive, so we can divide by 2^512 with no overflow or underflow *)
	    let val {man=m, exp=k} = Real.toManExp (q512 * x)
	    in
		{man=m, exp=Int.+(k, 512)}
	    end
	else
	    if x == 0.0 then {man=0.0, exp=0}
	    else
		(* the exponent is negative, so we can multiply by 2^512 with no overflow or underflow *)
		let val {man=m, exp=k} = Real.toManExp (p512 * x)
		in
		    {man=m, exp=Int.-(k, 512)}
		end


    (* original fromManExp depends on the rounding mode when  *)
    (* overflowing or underflowing; this is not specified by  *)
    (* the standard basis, and is not good for some functions *)
    (* on infinite integers and rationals *)

    val maxFinHalfPos = 0.5 * maxFinite
    val maxFinHalfNeg = ~maxFinHalfPos
    val minPosDouble = 2.0 * minPos
    val minNegDouble = ~minPosDouble

    fun fromManExp {man=m, exp=e} =
	if (m >= 0.5 andalso m <= 1.0  orelse
	    m <= ~0.5 andalso m >= ~1.0)
	    then
		if I.>(e, 1020) then
		    if m > 0.0 then
			if I.>(e, 1050) then posInf
			else
			    let fun f(i, x) =
				if i=0 then x else
				    if (x > maxFinHalfPos) then posInf
				    else f(I.-(i, 1), x+x)
			    in
				f(I.-(e, 1020), Real.fromManExp{man=m, exp=1020})
			    end
		    else
			if I.>(e, 1050) then negInf
			else
			    let fun f(i, x) =
				if i=0 then x else
				    if (x < maxFinHalfNeg) then negInf
				    else f(I.-(i, 1), x+x)
			    in
				f(I.-(e, 1020), Real.fromManExp{man=m, exp=1020})
			    end
		else
		    if I.<(e, I.~ 1020)
			then if I.<(e, I.~ 1200) then 0.0
			     else
				 if m > 0.0 then
				     let fun f(i, x) =
					 if i = 0 then x else
					     if (x < minPosDouble) then 0.0 (* with setting the underflow flag *)
					     else f(I.-(i, 1), x*0.5)
				     in
					 f(I.-(1020, e), Real.fromManExp{man=m, exp=I.~ 1020})
				     end
				 else
				     let fun f(i, x) =
					 if i=0 then x else
					     if (x > minNegDouble) then 0.0 (* with setting the underflow flag *)
					     else f(I.-(i, 1), x*0.5)
				     in
					 f(I.-(1020, e), Real.fromManExp{man=m, exp=I.~ 1020})
				     end
		    else
			Real.fromManExp{man=m, exp=e} (* This is the common case! *)
	else
	    let val {man=m', exp=e'} = toManExp m
	    in
		fromManExp{man=m', exp=I.+(e', e)}
	    end


    (* SML-NJ calls this maxInt; I changed it's name into    *)
    (* maxPosInt. It is the smallest float with the property *)
    (*                                                       *)
    (* Forall x:float. (x >= maxPosInt) => (x:int)           *)
    (*                                                       *)
    (* It is equal to 2^52.                                  *)

    val maxPosInt = 4503599627370496.0
    val maxNegInt = ~ maxPosInt

    (* split and realMod should be independent of the rounding mode *)
    fun split x =
	if x > 0.0 then
	    if x > maxPosInt then {whole=x, frac=0.0} (* how to make a signed zero? *)
	    else
		(* SML-NJ says this rounds according to the rounding mode. *)
		(* It seems though it doesn't do the job for exponents     *)
		(* above 53 under other roundings; hence the check above   *)
		(* Besides, a check as above is needed anyway if we want   *)
		(* to return correctly as specified by the Basis, on       *)
                (* inputs x=posInf and x=negInf. SML-NJ had an error *)
                (* there too, even under the default rounding *)

		let val w = (x + maxPosInt) - maxPosInt 
		    val f = x - w (* this is computed exactly *)
		in
		    (* check the signs *)
		    if f < 0.0 then {whole=w-1.0, frac=1.0+f}
		    else {whole=w, frac=f}
		end
	else
	    if x < maxNegInt then {whole=x, frac=0.0} (* how to make a signed zero? *)
	    else
		let val w = (x - maxPosInt) + maxPosInt
		    val f = x - w
		in
		    if f > 0.0 then {whole=w+1.0, frac=f-1.0}
		    else {whole=w, frac=f}
		end
	   
    val realMod = #frac o split

end

Fix:
Test: bug1443.1.sml
Owner: jhr, Andrew
Status: open
----------------------------------------------------------------------
Number: 1444
Title: First Century Blues
Keywords: Dates
Submitter: George Russell   george@persimmon.co.uk
Date: 09/17/98
Version: 110.8
System: Alpha Digital Unix 4.0B
Subsystem: SML basis library
Severity: minor
Problem:
  Date.toString does not conform with the standard.  It prints 
  Year 1 as " 0 1" and (perhaps this is more likely to be noticed)
  the first day of the month as " 1" (not "01" as seems implied by
  the basis document).

Code:
  Date.date{year=1,month=Date.Jan,day=1,hour=0,minute=0,second=0,offset=NONE};
  Date.toString it;
Transcript:
  Date.date{year=1,month=Date.Jan,day=1,hour=0,minute=0,second=0,offset=NONE};
  val it =
    DATE
      {day=1,hour=0,isDst=NONE,minute=0,month=Jan,offset=NONE,second=0,wday=Mon,
       yday=0,year=1} : Date.date
  - Date.toString it;
  val it = "Mon Jan  1 00:00:00  0 1" : string
Comments:

Fix:
Test: bug1444.1.sml
Owner: jhr?
Status: open
----------------------------------------------------------------------
Number: 1445
Title: uncaught Unbound in FLINT/trans/transtypes.sml
Keywords: FLINT, transtypes, types
Submitter: Dave MacQueen
Date: 9/21/98
Version: 110.0.3 - 110.8.1
System: -
Severity: major
Problem: 
  Elaborating a functor decl causes an uncaught exception Unbound
  (probably EntityEnv.Unbound?).
Code:
  signature S1 =
  sig
    type t
    val x : t  (* needed *)
  end;

  signature S2 =
  sig
    structure T : S1
  end;

  signature S3 =
  sig
    type s
    datatype t = Kt of s  (* s needed *)
  end;

  (* ok *)
  functor F1
    (structure C : S2
     structure D : S2
     structure E : S3
     sharing D.T = C.T
     sharing type E.t = C.T.t) =
  struct end;

  (* ok *)
  functor F2
    (structure C : S2
     structure D : S2 where T = C.T
     structure E : S3 where type t = C.T.t) =
  struct end;

  (* uncaught exception Unbound at FLINT/trans/transtypes.sml:277.33-277.43 *)
  functor F
    (structure C : S2
     structure D : S2 where T = C.T  (* needed *)
     structure E : S3
     sharing type E.t = C.T.t) =  (* needed *)
  struct end;

Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  - use "x1.sml";
  [opening x1.sml]
  signature S1 =
    sig
      type t
      val x : t
    end
  GC #0.0.0.0.1.2:   (10 ms)
  signature S2 =
    sig
      structure T :
	sig
	  type t
	  val x : t
	end
    end
  signature S3 =
    sig
      type s
      datatype t = Kt of s
    end
  functor F1 : <sig>
  functor F2 : <sig>

  uncaught exception Unbound
    raised at: FLINT/trans/transtypes.sml:277.33-277.43
	       FLINT/trans/translate.sml:150.39
Comments:
  In 110.0.3 error message is:
    uncaught exception Unbound
       raised at: translate/transmodules.sml:80.33-80.43
		  translate/translate.sml:129.39

  If the parameter signature for F is declared separately, as in
  
    signature S4 =
    sig
      structure C : S2
      structure D : S2 where T = C.T  (* needed *)
      structure E : S3
      sharing type E.t = C.T.t
    end;

    functor F(X:S4) = struct end;

  then the elaboration of the S4 declaration succeeds, but the
  functor declaration fails as before.

Fix:
  In Instantiate/buildStrClass/finalize, eliminate the conditional on
  eqSig(sign,sign') in the SOME(VARstrDef...) case for defining finalEnt,
  always returning (GENERATE_ENT false).  The bug code illustrates
  that even when signatures agree, a VARstrDef can introduce external
  free entVars (in this case for type s in S3), requiring some context
  entityEnv (see also mkEntEnv later in instantiate.sml).

Test: bug1445.1.sml, bug1445.2.sml
Owner: Zhong, dbm
Status: fixed in 110.9 [dbm, Zhong]
----------------------------------------------------------------------
Number: 1446
Title: "Translate: unexpected tyvar INSTANTIATED in mkPE" in lazy code
Keywords: lazy, translate
Submitter: Phil Wadler <wadler@research.bell-labs.com>
Date: 9/22/98
Version: 110.8.1
System: -
Severity: major
Problem: 
  Certain lazy declarations cause:

    Compiler bug: Translate: unexpected tyvar INSTANTIATED in mkPE

Code:
  (* bug1446.1.sml *)

  infixr 5 >>;

  datatype lazy series = >> of int * series;

  fun lazy recip () =  (* ok if "lazy" removed on this line *)
      let val rec lazy rs = 1 >> rs
       in rs
      end;

  ============
  (* bug1446.2.sml *)

  datatype lazy series = >> of int * series;

  fun lazy tail (x>>xs) = xs;

  fun lazy plus (f>>fs,g>>gs) = f+g >> plus(fs,gs);

  let val rec lazy rs =
	  let val lazy rs1 = tail rs
	   in 0 >> 1 >> plus(rs1,rs)
	  end
   in rs
  end;

Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  - Compiler.Control.lazysml := true;
  val it = () : unit
  - use "test/src/lazy/ps2.sml";
  [opening test/src/lazy/ps2.sml]
  infixr 5 >>
  datatype series! = >> of int * series! ?.susp
  type series = series! ?.susp
  Error: Compiler bug: Translate: unexpected tyvar INSTANTIATED in mkPE

Comments:
Fix: [Zhong]
  The bug was caused by the fact that we were not generating
  new copies of the "forceExp" function in the elabDec function
  in Semantics/elaborate/elabcore.sml.
Test: bug1446.1.sml, bug1446.2.sml
Owner: dbm, Zhong
Status: fixed in 110.9.1 [Zhong, 9/24/98]
----------------------------------------------------------------------
Number: 1447
Title: Real.fmt fails on large real number
Keywords: Real, format, conversion, StringCvt
Submitter: Dave MacQueen
Date: 10/6/98
Version: 110.8.2+
System: sparc/solaris 2.5.1
Severity: medium
Problem: 
  Real.fmt adds a spurious .1 when converting round real numbers
  above 91827364509181.0 to a string.
Code: (* bug1447.1.sml *)
  Real.fmt (StringCvt.FIX(SOME 0)) 91827364509181.0;
  Real.fmt (StringCvt.FIX(SOME 1)) 91827364509181.0;
  Real.fmt (StringCvt.FIX(SOME 2)) 91827364509181.0;
  Real.fmt (StringCvt.FIX(SOME 0)) 91827364509182.0;
  Real.fmt (StringCvt.FIX(SOME 1)) 91827364509182.0;
  Real.fmt (StringCvt.FIX(SOME 2)) 91827364509182.0;
  Real.fmt (StringCvt.FIX(SOME 0)) 91827364509183.0;
  Real.fmt (StringCvt.FIX(SOME 1)) 91827364509183.0;
  Real.fmt (StringCvt.FIX(SOME 2)) 91827364509183.0;
Transcript:
  - use "/home/sml/Dev/bugs/tests/bug1447.1.sml";
  [opening /home/sml/Dev/bugs/tests/bug1447.1.sml]
  val it = "91827364509181" : string
  val it = "91827364509181.0" : string
  val it = "91827364509181.00" : string
  val it = "91827364509182" : string
  val it = "91827364509182.1" : string
  val it = "91827364509182.10" : string
  val it = "91827364509183" : string
  val it = "91827364509183.1" : string
  val it = "91827364509183.10" : string
  val it = () : unit
Comments:
  This comes from the basis/real.sml regression test.  It causes
  test 11c to fail.
Fix:
Test: bug1447.1.sml
Owner: jhr?
Status: open
----------------------------------------------------------------------
Number: 1448
Title: Real.round does not round to nearest even for ties
Keywords: Real, round
Submitter: Dave MacQueen
Date: 10/6/98
Version: 110.8.2+
System: sparc/solaris 2.5.1
Severity: major
Problem: 
  Real.round rounds upward, rather than to the nearest even, in
  the case of a tie.
Code:
  Real.round 0.5;
  Real.round 1.5;
  Real.round 2.5;
  Real.round (~0.5);
  Real.round (~1.5);
Transcript:
  - Real.round 0.5;
  val it = 1 : int
  - Real.round 1.5;
  val it = 2 : int
  - Real.round 2.5;
  val it = 3 : int
  - Real.round(~0.5);
  val it = 0 : int
  - Real.round(~1.5);
  val it = ~1 : int
Comments:
  This comes from test 7a in the basis/real.sml regression tests.
Fix: 
Test: bug1448.1.sml
Owner: dbm
Status: fixed in 110.0.6 [dbm]
----------------------------------------------------------------------
Number: 1449
Title: FFT benchmark gives wrong answers.
Keywords: reals
Submitter: Andrew Kennedy   andrew@persimmon.co.uk
Date: 10/07/98
Version: 110.8
System: Any/All Other (describe below) 
Subsystem: SML compiler
Severity: major
Problem:
  The FFT benchmark gives the wrong answers on all architectures that we
  have tested. 

Code:
structure Main = struct

local
open Array Math

val printr = print o Real.toString
val printi = print o Int.toString
in

val PI = 3.14159265358979323846

val tpi = 2.0 * PI

fun fft px py np =
  let fun find_num_points i m =
        if i < np then find_num_points (i+i) (m+1) else (i,m)
      val (n,m) = find_num_points 2 1 in
  if n <> np then
    let fun loop i = if i > n then () else (
      update(px, i, 0.0);
      update(py, i, 0.0);
      loop (i+1))
    in
      loop (np+1);
      print "Use "; printi n; print " point fft\n"
    end
  else ();

  let fun loop_k k n2 = if k >= m then () else
    let val n4 = n2 div 4
        val e  = tpi / (real n2)
        fun loop_j j a = if j > n4 then () else
          let val a3 = 3.0 * a
              val cc1 = cos(a)
              val ss1 = sin(a)
              val cc3 = cos(a3)
              val ss3 = sin(a3)
              fun loop_is is id = if is >= n then () else
                let fun loop_i0 i0 = if i0 >= n then () else
                  let val i1 = i0 + n4
	              val i2 = i1 + n4
	              val i3 = i2 + n4
	              val r1 = sub(px, i0) - sub(px, i2)
                      val _ = update(px, i0, sub(px, i0) + sub(px, i2))
                      val r2 = sub(px, i1) - sub(px, i3)
	              val _ = update(px, i1, sub(px, i1) + sub(px, i3))
                      val s1 = sub(py, i0) - sub(py, i2)
	              val _ = update(py, i0, sub(py, i0) + sub(py, i2))
                      val s2 = sub(py, i1) - sub(py, i3)
                      val _ = update(py, i1, sub(py, i1) + sub(py, i3))
                      val s3 = r1 - s2
                      val r1 = r1 + s2
                      val s2 = r2 - s1
                      val r2 = r2 + s1
                      val _ = update(px, i2, r1*cc1 - s2*ss1)
                      val _ = update(py, i2, ~s2*cc1 - r1*ss1)
                      val _ = update(px, i3, s3*cc3 + r2*ss3)
                      val _ = update(py, i3, r2*cc3 - s3*ss3)
                  in
                    loop_i0 (i0 + id)
                  end
                in
                  loop_i0 is;
                  loop_is (2 * id - n2 + j) (4 * id)
                end
          in
            loop_is j (2 * n2);
            loop_j (j+1) (e * real j)
          end
    in
      loop_j 1 0.0;
      loop_k (k+1) (n2 div 2)
    end
  in
    loop_k 1 n
  end;

(************************************)
(*  Last stage, length=2 butterfly  *)
(************************************)

  let fun loop_is is id = if is >= n then () else
    let fun loop_i0 i0 = if i0 > n then () else
      let val i1 = i0 + 1
          val r1 = sub(px, i0)
          val _ = update(px, i0, r1 + sub(px, i1))
          val _ = update(px, i1, r1 - sub(px, i1))
          val r1 = sub(py, i0)
          val _ = update(py, i0, r1 + sub(py, i1))
          val _ = update(py, i1, r1 - sub(py, i1))
      in
        loop_i0 (i0 + id)
      end
    in
      loop_i0 is;
      loop_is (2*id - 1) (4 * id)
    end
  in
    loop_is 1 4
  end;

(*************************)
(*  Bit reverse counter  *)
(*************************)

  let fun loop_i i j = if i >= n then () else
   (if i < j then
     (let val xt = sub(px, j)
      in update(px, j, sub(px, i)); update(px, i, xt)
      end;
      let val xt = sub(py, j)
      in update(py, j, sub(py, i)); update(py, i, xt)
      end)
    else ();
    let fun loop_k k j =
              if k < j then loop_k (k div 2) (j-k) else j+k
        val j' = loop_k (n div 2) j
    in
      loop_i (i+1) j'
    end)
  in
    loop_i 1 1
  end;

  n
  end

fun abs x = if x >= 0.0 then x else ~x

fun test np =
  let val _ = (printi np; print "... ")
      val enp = real np
      val npm = (np div 2) - 1
      val pxr = array (np+2, 0.0)
      val pxi = array (np+2, 0.0)
      val t = PI / enp
      val _ = update(pxr, 1, (enp - 1.0) * 0.5)
      val _ = update(pxi, 1, 0.0)
      val n2 = np  div  2
      val _ = update(pxr, n2+1, ~0.5)
      val _ = update(pxi, n2+1,  0.0)
      fun loop_i i = if i > npm then () else
        let val j = np - i
            val _ = update(pxr, i+1, ~0.5)
            val _ = update(pxr, j+1, ~0.5)
            val z = t * real i
            val y = ~0.5*(cos(z)/sin(z))
            val _ = update(pxi, i+1,  y)
            val _ = update(pxi, j+1, ~y)
        in
          loop_i (i+1)
        end
      val _ = loop_i 1
(***
      val _ = print "\n"
      fun loop_i i = if i > 15 then () else
        (print i; print "\t";
         print (sub(pxr, i+1)); print "\t";
         print (sub(pxi, i+1)); print "\n"; loop_i (i+1))
      val _ = loop_i 0
***)
      val _ = fft pxr pxi np
(***
      fun loop_i i = if i > 15 then () else
        (print i; print "\t";
         print (sub(pxr, i+1)); print "\t";
         print (sub(pxi, i+1)); print "\n"; loop_i (i+1))
      val _ = loop_i 0
***)
      fun loop_i i zr zi kr ki = if i >= np then (zr,zi) else
        let val a = abs(sub(pxr, i+1) - real i)
            val (zr, kr) =
              if zr < a then (a, i) else (zr, kr)
            val a = abs(sub(pxi, i+1))
            val (zi, ki) =
              if zi < a then (a, i) else (zi, ki)
        in
          loop_i (i+1) zr zi kr ki
        end
      val (zr, zi) = loop_i 0 0.0 0.0 0 0
      val zm = if abs zr < abs zi then zi else zr
  in
    printr zm; print "\n"
  end

fun loop_np i np = if i > 13 then () else
  (test np; loop_np (i+1) (np*2))

fun main () = loop_np 1 16

end
end

Transcript:
SML/NJ:

16... 8.881784197e~16
32... 3.5527136788e~15
64... 1.06581410364e~14
128... 2.84217094304e~14
256... 5.68434188608e~14
512... 1.16795462191e~13
1024... 3.41060513165e~13
2048... 7.95807864051e~13
4096... 1.40154554629e~12
8192... 3.63797880709e~12
16384... 7.27595761418e~12
32768... 1.45519152284e~11
65536... 2.91038304567e~11

MLJ (and Moscow ML):

16... 8.88178419700E~16
32... 2.66453525910E~15
64... 1.42108547152E~14
128... 2.93098878501E~14
256... 5.86197757002E~14
512... 1.70530256582E~13
1024... 3.41060513165E~13
2048... 9.09494701773E~13
4096... 1.81898940355E~12
8192... 5.45696821064E~12
16384... 1.09139364213E~11
32768... 2.18278728426E~11
65536... 5.82076609135E~11

Comments:
Fix:
Test: bug1449.1.sml
Owner: Lal?
Status: open
----------------------------------------------------------------------
Number: 1450
Title: bugs in Array2.fromList and Array2.row
Keywords: Array2 fromList row
Submitter: Huh Choong Gil   earny@mathx.kaist.ac.kr
Date: 10/10/98
Version: 110.0.3
System: Any/All Any Unix 
Subsystem: SML basis library
Severity: major
Problem:
wrong behavior of Array2.fromList and Array2.row
Code:
from src/sml-nj/boot/array2.sml
    fun fromList [] = {data = Assembly.array0, nrows = 0, ncols = 0}
    ...
                      List.revAppend (revCol, l))
    ...
         end              
    fun row ({data, nrows, ncols}, i) = let
    ...
              else mkVec (stop+nrows-1, [])
          end

Transcript:
* bug of Array2.fromList
- val a = Array2.fromList [[1,2],[3,4],[5,6]];
val a = - : int Array2.array
- Array2.app Array2.RowMajor (fn x => print (Int.toString x)) a;
125634val it = () : unit

* bug of Array2.row
- val b = Array2.tabulate Array2.RowMajor (2,1,fn _ => 1);
val b = - : int Array2.array
- Array2.nRows b;
val it = 2 : int
- Array2.row (b,1);

uncaught exception subscript out of bounds
  raised at: boot/array2.sml:114.21-114.26

Comments:

Fix:
* bug of Array2.fromList
The problem is the line 

   List.revAppend (revCol, l))

in fun Array2.fromList of array2.sml which i think should be

   List.@(l, List.rev revCol))  


* bug of Array2.row
the problem is the line

   else mkVec (stop+nrows-1, [])

in fun Array2.row of array2.sml which i think should be

   else mkVec (stop+ncols-1, [])


Test: 
Owner: jhr
Status: fixed in 110.9.1 and in 110.0.4 [jhr, 10/19/98]
----------------------------------------------------------------------
Number: 1451
Title: Math.sin(large number) is wrong
Keywords: maths
Submitter: George Russell   george@persimmon.com
Date: 10/13/98
Version: 110.8
System: Alpha Digital Unix 4.0B
Subsystem: SML basis library
Severity: minor
Problem:
sin(large number) returns ~1.0, 1.0 or 0.0
Code:
  Math.sin(1e16);
  Math.sin(1.1e16);
  Math.sin(1.2e16);
  Math.sin(1.3e16);

Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  val use = fn : string -> unit
  - Math.sin(1e16);
  val it = 0.0 : real
  - Math.sin(1.1e16);
  val it = ~1.0 : real
  - Math.sin(1.2e16);
  val it = 1.0 : real
  - Math.sin(1.3e16);
  val it = 0.0 : real

Comments:
  This values are inconsistent - if sin(x)=0, sin(x+y)= -1, then
  x= 0 mod 2pi, y= 3pi/2 mod 2pi; therefore sin(x+2y)=0 and sin(x+3y)=1.
Fix:
  Do what fdlibm does and use multiprecision arithmetic to compute
  x mod 2pi exactly.  This is the ideal solution, since it ensures
  consistency, even though the results aren't very meaningful. 
  Otherwise, return an answer which is obviously wrong (EG NaN or x),
  since the program surely must be.
Test: 
Owner: jhr, Andrew
Status: open
----------------------------------------------------------------------
Number: 1452
Title: Math.sinh(small number)=0.0
Keywords: reals
Submitter: George Russell   george@persimmon.com
Date: 10/13/98
Version: 110.8
System: Alpha Digital Unix 4.0B
Subsystem: SML basis library
Severity: minor
Problem:
For small x, sinh(x) is approximately x.  However New Jersey
thinks it is 0.
Code:
  Math.sinh(1e~20);
Transcript:
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998
  val use = fn : string -> unit
  - Math.sinh(1e~20);
  val it = 0.0 : real

Comments:
  Similar considerations apply to Math.tanh.
Fix:
  I suspect that SML/NJ is using a formula which is something like
  sinh(x)=(e^x - e^{-x})/2.  For small x, e^x=1, so SML/NJ falls into
  the ancient trap of subtracting two nearly equal quantities.  One
  way of circumventing this is to use the expm1 function (available on
  Digital Unix, Sparc-Solaris and Linux at least) which is equal to 
  e^x -1.  Then we have sinh(x)=0.5*expm1(x)*(1+ 1/(expm1(x)+1)).
  (See fdlibm for more details).
Test: bug1452.1.sml
Owner: jhr, Andrew
Status: open
----------------------------------------------------------------------
Number: 1453
Title: Compiler bug: LtyExtern: incorrect lambda types in lt_select
Keywords: lazy compiler
Submitter: Kevin Watkins   kw+@cs.cmu.edu
Date: 10/22/98
Version: 110.8, 110.9.1
System: x86 Linux 2.0.32 (Redhat 4.2)
Subsystem: SML compiler
Severity: major
Problem:
  Compiler internal error was reported while processing source code
  using `lazy' and a polymorphic datatype.

  Note: the following

    val _ = Compiler.Control.lazysml := true;
    datatype lazy stream = Nil | Cons of unit * stream;
    val rec lazy x = Cons(raise Subscript, x);

  is accepted.

Code:
  val _ = Compiler.Control.lazysml := true;
  datatype lazy 'a stream = Nil | Cons of 'a * 'a stream;
  val rec lazy x = Cons(raise Subscript, x);

Transcript:
  gs73$ sml
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 [CM; autoload enabled]
  - val _ = Compiler.Control.lazysml := true;
  - datatype lazy 'a stream = Nil | Cons of 'a * 'a stream;
  datatype 'a stream! = Cons of 'a * 'a stream! ?.susp | Nil
  type 'a stream = 'a stream! ?.susp
  - val rec lazy x = Cons(raise Subscript, x);
  Error: Compiler bug: LtyExtern: incorrect lambda types in lt_select

Comments:

Fix:

Test: tests.lazy/bug1453.1.sml
Owner: dbm, Zhong
Status: open
----------------------------------------------------------------------
Number: 1454
Title: Unexpected force of lazy suspension in pattern match
Keywords: lazy pattern-match
Submitter: Kevin Watkins   kw+@cs.cmu.edu
Date: 10/22/98
Version: 110.8
System: x86 Linux 2.0.32 (Redhat 4.2)
Subsystem: SML compiler
Severity: major
Problem:
  The implementation of `lazy' in 110.8 does not seem to respect the
  semantics described in Wadler et al (How to add laziness to a strict
  language without even being odd).  I have provided source code
  for a simple example which demonstrates the problem in the place
  provided on this bug report form.  It raises an exception rather
  than returning [] as one would expect.

Code:
  val _ = Compiler.Control.lazysml := true;

  datatype lazy stream = Nil | Cons of int * stream;

  fun take (s, 0) = []
    | take (Nil, _) = raise Subscript
    | take (Cons(x, s), n) = x::take(s, n-1);

  val rec lazy don't_force_me = Cons(raise Fail "Was forced",
				     don't_force_me);

  (* should return [] but raises Fail instead *)
  take(don't_force_me, 0);

Transcript:
  gs73$ sml
  Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 [CM; autoload enabled]
  - val _ = Compiler.Control.lazysml := true;
  - datatype lazy stream = Nil | Cons of int * stream;
  datatype stream! = Cons of int * stream! ?.susp | Nil
  type stream = stream! ?.susp
  - fun take (s, 0) = []
  =   | take (Nil, _) = raise Subscript
  =   | take (Cons(x, s), n) = x::take(s, n-1);
  val take = fn : stream! ?.susp * int -> int list
  - val rec lazy don't_force_me = Cons(raise Fail "Was forced",
  =                                    don't_force_me);
  GC #0.0.0.0.1.16:   (0 ms)
  val don't_force_me = $$ : stream! ?.susp
  - (* should return [] but raises Fail instead *)
  - take(don't_force_me, 0);

  uncaught exception Fail: Was forced
    raised at: stdIn:15.42-15.59

Comments:
  One might argue that the semantics of pattern matching should allow
  the behavior I'm claiming is incorrect.  However, the very example
  with which the Wadler et al paper motivates the "even" versus "odd"
  definition of lazy data structures fails.  Here is the code from
  Figure 3 of the paper:

    datatype lazy 'a stream = Nil | Cons of 'a * 'a stream;

    fun lazy map f Nil = Nil
	   | map f (Cons(x,xs)) = Cons(f x, map f xs);

    fun lazy countdown n = Cons (n, countdown (n-1));

    fun cutoff 0 xs = []
      | cutoff n Nil = []
      | cutoff n (Cons(x,xs)) = x :: cutoff (n-1) xs;

  The motivating example is in section 2.1 of the paper. Since `sqrt'
  no longer raises an exception in this version of SML, I will use
  `div' instead.  We would expect

    cutoff 4 (map (fn x => 100 div x) (countdown 4));

  to return

    [25, 33, 50, 100]

  but instead it raises Div.

 [Related report from Bob Harper, 10/1/98]
  Compiler.Control.lazysml := true;
  datatype lazy 'a stream = && of 'a * 'a stream;
  infixr &&;

  fun shd (h && _) = h;
  fun stl (_ && t) = t;     (* eager *)
  fun lazy ltl (_ && t) = t;  (* lazy *)

  fun lazy smap f (h && t) = (f h) && (smap f t)
  fun lazy szip (h && t, h' && t') = (h, h') && (szip (t, t'));

  val rec lazy s = 1 && 1 && smap (op +) (szip (s, stl s))

  My expectation is that I should be able to take shd s and shd(stl s) without
  problem, but that taking shd (stl (stl s)) should loop.  However, it loops the
  first time I take shd s.  I don't get it.  Apparently the second argument to
  the first "&&" is not suspended properly, or something like that.  Could you
  please explain?

  Also, compare the following:

  val rec lazy s1 = 1 && s2
  and lazy s2 = 1 && s3
  and lazy s3 = smap (op +) (szip (s1, s2))

  which works fine, as does the version in which s2 is replaced by stl s1.

  What gives?  I would've thought these would be equivalent.

Fix:

Test: tests.lazy/bug1454.1.sml, bug1454.2.sml
Owner: dbm, Wadler
Status: open
----------------------------------------------------------------------
Number: 1455
Title: IntInf not properly supported
Keywords: IntInf
Submitter: Henry Cejtin   <henry@research.nj.nec.com>
Date: 10/30/98
Version: 110.8
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
  According     to     the    basis    documentation
  (integer.html), if an implementation provides  the
  IntInf structure, then LargeInt.int is supposed to
  be the same as IntInf.int.

  Similarly,  literals  should   be   accepted   for
  IntInf.int constants.  I.e.,
	  val x: IntInf.int = 9
  should be accepted.

  Finally, the standard infix arithmetic operations,
  (+, -, ...)  should be overloaded for  IntInf.int.

Comments:
 [dbm, 2/11/99]
  Support for IntInf is optional, but we should add it.  The signature
  of IntInf is currently incomplete (lacks bitwise operations), and a
  higher performance implementation using primop support would be desirable.
Fix:

Test: 
Owner: jhr, Lal
Status: not a bug
----------------------------------------------------------------------
Number: 1456
Title: Int.sameSign
Keywords: Int.sameSign
Submitter: Henry Cejtin   henry@research.nj.nec.com
Date: 10/30/98
Version: 110.8
System: Any/All Any Unix 
Subsystem: SML basis library
Severity: minor
Problem:
  The basis documentation says that
	  Int.sameSign (x, y)
  should be equivalent to
	  Int.sign x = Int.sign y

	  Int.sign 0 --> 0
	  Int.sign 1 --> 1
  and yet
	  Int.sameSign (0, 1) -> true

  From experiments, it seems that sameSign (x, y) is
  simply testing if the sign bit of x and y  is  the
  same.   Actually,  I  find this to be more useful,
  but  either  the  documentation  or  the  behavior
  should be changed.

  Note,   the   same   behavior   is   exhibited  by
  Int32.sameSign.

Code:
  Int.sameSign (0, 1);
  Int32.sameSign (0, 1);
Transcript:
  - Int.sameSign (0, 1);
  val it = true : bool
  - Int32.sameSign (0, 1);
  val it = true : bool

Comments:

Fix:

Test: bug1456.1.sml
Owner: jhr, Lal
Status: open
----------------------------------------------------------------------
Number: 1457
Title: Posix.FileSys.readdir
Keywords: Posix.Filesys.readdir
Submitter: Henry Cejtin   henry@research.nj.nec.com
Date: 10/30/98
Version: 110.8
System: Any/All Any Unix 
Subsystem: SML basis library
Severity: major
Problem:
  In  Posix.FileSys,  what  is  the  argument for readdir
  having the signature
	  dirstream -> string
  instead of
	  dirstream -> string option
  and having it return the empty string if there  are  no
  more  directories?  This seems completely insane to me.
  Note, that the C readdir() returns NULL when there  are
  no  more  directories, so even it is closer to a string
  option.

Comments:
 [jhr, 2/8/99]
  This is a basis spec issue; we implement the spec.

Fix:
  Change Posix.FileSys.readdir so that it returns a string option, with
  NONE indicating the end of the directory has been reached.
Test: 
Owner: jhr
Status: not a bug
----------------------------------------------------------------------
Number: 1458
Title:       Uninformative IO exception message / crash
Keywords:    IO
Submitter:   Allyn Dimock <dimock@deas.harvard.edu>
Date:        11/04/98
Version:     110.0.3 full-cm
System:      SGI
Severity:    minor
Problem:     Transcript below typed at command loop causes crash.
             The crash is probably a "feature" rather than a bug -- I should
             restore the old value of out before closing the temporary stream.

             But: it would be nice to have the error handled and something
more                   informative than "<unknown>" printed out.

Code:        <SML source code to reproduce the bug>
Transcript:  

- val oldout = !Control.Print.out;
val oldout = {flush=fn,say=fn} : {flush:unit -> unit, say:string -> unit}
- val out = TextIO.openOut("xxx.xxx");
val out = - : TextIO.outstream
- val sayout = {say = fn(s) => TextIO.output (out,s), flush = fn() =>
TextIO.flushOut(out)};
val sayout = {flush=fn,say=fn}
  : {flush:unit -> unit, say:TextIO.vector -> unit}
- Control.Print.out := sayout;
SmlnjFrontEnd.smlnjFrontEnd("test1a.sml");
GC #1.9.15.56.197.4729:   (9 ms)

==================
SMLNJ Lambda Term:


==================
Untyped Cil Term:

let.14 i: = .3{0=1.1:,1=2.2:} 
in 
  i.7:
GC #1.9.15.57.198.4747:   (15 ms)
GC #1.9.15.58.199.4753:   (26 ms)
 %time cumsec #call  name
 33.33    .01     0  Major GC
......
GC #1.9.16.61.202.4768:   (0 ms)
TextIO.closeOut(out);
/usr/local/sml/bin/sml-full-cm: Fatal error -- Uncaught exception Io with
<unknown> raised at boot/IO/text-io-fn.sml:444.14-444.56


Process sml-full-cm exited abnormally with code 1

by the way, the contents of xxx.xxx is:

arctic 37% more xxx.xxx
val it = () : unit
- [opening test1a.sml]
FN(v3 : S{}, 
   i2 = RECORD(1,2)
   SRECORD(i2))

val it = () : unit
- 
arctic 38% 


Comments:    (Attempt to use mcprint to a file)
 [jhr, 11/4/98]
  This is a "feature" of having an interactive top-level loop that
  shares its streams with executing programs.
Fix: 
Test: 
Owner: jhr
Status: not a bug
----------------------------------------------------------------------
Number: 1459
Title: segmentation fault after an interrupt
Keywords: core dump, interrupt
Submitter: Elsa Gunter
Date: 11/13/98
Version: 110.9.1
System: x86/Linux
Severity: major
Problem: 
  Yesterday, just before I went home, I encountered the following bad
  bahavior form sml version 110.9.1 running under Linux:

Transcript:
  ...
  GC #4.38.85.145.802.29587:   (40 ms)
  GC #4.38.85.145.803.29589:   (40 ms)
  GC #4.38.85.145.804.29590:   (10 ms)
  GC #4.38.85.145.805.29622:   (20 ms)
  GC #4.39.86.146.806.29700:   (120 ms)

  Interrupt
  - use "cm-make.sml";
  GC #4.39.86.146.807.29706:   (30 ms)
  /usr/local/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x804c34d
  481.0u 4.6s 11:47.57 68.6% 0+0k 0+0io 941pf+0w
  cambridge% 

Comments:
  The compiler was busy compiling something big, and I didn't need it to
  finish and I didn't want to wait for it, so I interupted it.  Then I
  tried to use another file and it immediately died on me.  I can't
  reproduce the problem, but I thought I shiuld pass it along especially
  since there was some information generated when it died.
Fix:
Test:
Owner: ?
Status: not reproducible
----------------------------------------------------------------------
Number: 1460
Title:       CM.stabilize(') fails when calling BinIO under Win32
Keywords:    CM, IO
Submitter:   Elsa L. Gunter, elsa@research.bell-labs.com
Date:        11/13/98
Version:     110.9.1
System:	     x86-win32  ie. windows nt, windows 95 (I haven't checked 98 yet)
Severity:    major
Problem:     When CM.stabilize' is called it fails with an IO
             exception generated by BinIO.inputAll claiming an
             subscript is out of bounds
Code:	     
  File [test.sml]
	structure A = struct end

  File [test.cm]
	Group is test.sml

  val _ = CM.stabilize'{group="test.cm", recursively=false};

Transcript:  
Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998
- val _ = CM.stabilize'{group="test.cm", recursively=false};
[starting dependency analysis]
[scanning test.cm]
[checking CM\x86-win32\test.cm.stable... not usable]
[parsing test.sml]
[Creating directory CM\DEPEND ...]
[dependency analysis completed]
[compiling test.sml -> CM\x86-win32\test.sml.bin]
[Creating directory CM\x86-win32 ...]
[wrote CM\x86-win32\test.sml.bin]
[starting dependency analysis]
[dependency analysis completed]
writing CM\x86-win32\test.cm.stable failed]

uncaught exception Io: inputAll failed on "CM\x86-win32\test.sml.bin" with exception subscript out of bounds
  raised at: PervEnv/IO/bin-io-fn.sml:107.14-107.56
             ../cm/decl/decl.sml:260.41
             ../cm/util/interrupt.sml:35.58-35.61
             ../cm/decl/decl.sml:376.45-376.48
             ../cm/decl/decl.sml:384.8-384.11
- - 

Comments:
  It doesn't matter whether a CM.make' has been done on the
  group test.cm, or not.
 [Blume]
  It appears that inputAll on Win32 is the culprit.
Fix:
Test: -
Owner: Lorenz, Riccardo
Status: open
----------------------------------------------------------------------
Number: 1461
Title:       Changing directories confuses CM sharing
Keywords:    CM, share
Submitter:   Elsa L. Gunter, elsa@research.bell-labs.com
Date:        12/10/98
Version:     110.9.1
System:      x86-linux
Severity:    major
Problem:
  When the directory is changed on CM, by exporting a heap
  and restarting it in a different place, or by using OS.FileSys.chDir,
  CM seems to loose track of modules that it has already loaded and
  executed.

Code:        
(* Code and Instructions *)

Make the following directories:

bug
bug/bug1
bug/bug2

Create the following files:

(* bug/bug1/first.sml *)

structure First =
struct
val x = ref 0
end

(*------------------------------------*)
(* bug/bug1/first.cm *)

Library

structure First

is

first.sml : shared

(*------------------------------------*)
(* bug/bug2/second.sml *)

structure Second =
struct
val y = !First.x
end

(*------------------------------------*)
(* bug/bug2/second.cm *)

Library

structure Second

is

../bug1/first.cm

second.sml : shared

(*------------------------------------*)
(* bug/load1.sml *)

val _ = CM.make' {group = "<full path>/bug/bug1/first.cm",
		  force_relink = false};

val _ = First.x := 3;

fun finish () = CM.make' {group = "<full path>/bug/bug2/second.cm",
			  force_relink = false};

val _ = SMLofNJ.exportML "bug";

(*------------------------------------*)


Now while in the directory bug, start sml and execute

use "load1.sml";
finish();

Stop sml, then start <<sml @SMLload=bug>> and execute

finish();
Second.y;


Stop sml, cd .., then start <<sml @SMLload=bug/bug>> and execute

finish();
Second.y;

The fisrt value of Second.y is 3, while the second is 0.  I claim the
second is wrong.

To see an alternate way of generating the same problem, add the
following files:

(*------------------------------------*)
(* bug/bug2/third.sml *)

structure Third =
struct
val y = !First.x
end

(*------------------------------------*)
(* bug/bug2/third.cm *)

Library

structure Third

is

../bug1/first.cm

third.sml : shared

(*------------------------------------*)
(* bug/load2.sml *)

val _ = CM.make' {group = "<full path>/bug/bug1/first.cm",
		  force_relink = false};

val _ = First.x := 3;

val _ = CM.make' {group = "<full path>/bug/bug2/second.cm",
			  force_relink = false};

Second.y;

val _ = OS.FileSys.chDir ".." (* any place different, really *)

val _ = CM.make' {group = "<full path>/bug/bug2/third.cm",
			  force_relink = false};

Third.y;

val result = (Second.y = Third.y);

(*------------------------------------*)

Now, while in the bug directory, start sml and execute 

use "load2.sml"

I claim the value of result should be true, but is false.

I append a tar-gzip-uuencoded copy of the bug directory at the end of
this report.


Transcript:
norfolk% ls -R
bug1/	   bug2/      load1.sml  load2.sml

bug1:
first.cm   first.sml

bug2:
second.cm   second.sml	third.cm    third.sml
norfolk% sml
Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998
val use = fn : string -> unit
- use "load1.sml";
[opening load1.sml]
[starting dependency analysis]
[scanning /home/elsa/bug/bug1/first.cm]
[checking /home/elsa/bug/bug1/CM/x86-unix/first.cm.stable... not usable]
[parsing /home/elsa/bug/bug1/first.sml]
[Creating directory /home/elsa/bug/bug1/CM/DEPEND ...]
[dependency analysis completed]
[compiling /home/elsa/bug/bug1/first.sml -> /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin]
[Creating directory /home/elsa/bug/bug1/CM/x86-unix ...]
[wrote /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin]
[introducing new bindings into toplevel environment...]
val finish = fn : unit -> bool
GC #1.1.1.1.1.14:   (120 ms)
write 1,0: 27020 bytes [0x40c00000..0x40c0698c) @ 0x2000
write 1,1: 7800 bytes [0x40c60008..0x40c61e80) @ 0x9000
write 1,2: 11692 bytes [0x40cb0000..0x40cb2dac) @ 0xb000
write 1,3: 2656 bytes [0x40d20000..0x40d20a60) @ 0xe000
write 2,0: 70136 bytes [0x40d80000..0x40d911f8) @ 0xf000
write 2,1: 73480 bytes [0x40e30008..0x40e41f10) @ 0x21000
write 2,2: 16948 bytes [0x40ef0000..0x40ef4234) @ 0x33000
write 2,3: 2304 bytes [0x40f20000..0x40f20900) @ 0x38000
write 2,0: 5 big objects (5 pages) @ 0x39000
write 3,0: 27584 bytes [0x40f40000..0x40f46bc0) @ 0x3a450
write 3,1: 59736 bytes [0x40f70008..0x40f7e960) @ 0x41450
write 3,2: 18660 bytes [0x40fc0000..0x40fc48e4) @ 0x50450
write 3,3: 1288 bytes [0x40fe0000..0x40fe0508) @ 0x55450
write 4,0: 228 bytes [0x41000000..0x410000e4) @ 0x56450
write 4,1: 264 bytes [0x41010008..0x41010110) @ 0x57450
write 4,2: 124 bytes [0x41020000..0x4102007c) @ 0x58450
write 4,3: 24 bytes [0x41030000..0x41030018) @ 0x59450
write 5,0: 371204 bytes [0x41050000..0x410aaa04) @ 0x5a450
write 5,1: 575864 bytes [0x41220008..0x412ac980) @ 0xb5450
write 5,2: 147236 bytes [0x414e0000..0x41503f24) @ 0x142450
write 5,3: 52220 bytes [0x415a0000..0x415acbfc) @ 0x166450
write 5,0: 323 big objects (6625 pages) @ 0x173450
val it = () : unit
- finish();
[starting dependency analysis]
[scanning /home/elsa/bug/bug2/second.cm]
[checking /home/elsa/bug/bug2/CM/x86-unix/second.cm.stable... not usable]
[parsing /home/elsa/bug/bug2/second.sml]
[Creating directory /home/elsa/bug/bug2/CM/DEPEND ...]
[dependency analysis completed]
[compiling /home/elsa/bug/bug2/second.sml -> /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin]
[Creating directory /home/elsa/bug/bug2/CM/x86-unix ...]
[wrote /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin]
[introducing new bindings into toplevel environment...]
val it = true : bool
- 
norfolk% sml @SMLload=bug;

uncaught exception Io: input failed on "load1.sml", Bad file number
  raised at: PervEnv/IO/text-io-fn.sml:113.14-113.56
             Parse/main/frontend.sml:92.32
             Parse/main/frontend.sml:92.32
- finish();
[starting dependency analysis]
[scanning /home/elsa/bug/bug2/second.cm]
[checking /home/elsa/bug/bug2/CM/x86-unix/second.cm.stable... not usable]
[dependency analysis completed]
[recovering /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin... done]
[introducing new bindings into toplevel environment...]
val it = true : bool
- Second.y;
val it = 3 : int
- GC #0.0.0.0.1.5:   (20 ms)

norfolk% cd ..
norfolk% sml @SMLload=bug/bug

uncaught exception Io: input failed on "load1.sml", Bad file number
  raised at: PervEnv/IO/text-io-fn.sml:113.14-113.56
             Parse/main/frontend.sml:92.32
             Parse/main/frontend.sml:92.32
- finish();
[starting dependency analysis]
[scanning /home/elsa/bug/bug2/second.cm]
[checking /home/elsa/bug/bug2/CM/x86-unix/second.cm.stable... not usable]
[scanning /home/elsa/bug/bug1/first.cm]
[checking /home/elsa/bug/bug1/CM/x86-unix/first.cm.stable... not usable]
GC #0.0.0.0.1.3:   (10 ms)
[dependency analysis completed]
[recovering /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin... done]
[recovering /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin... done]
[introducing new bindings into toplevel environment...]
val it = true : bool
- Second.y;
val it = 0 : int
- 
norfolk% cd bug
norfolk% sml
Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998
val use = fn : string -> unit
- use "load2.sml";
[opening load2.sml]
[starting dependency analysis]
[scanning /home/elsa/bug/bug1/first.cm]
[checking /home/elsa/bug/bug1/CM/x86-unix/first.cm.stable... not usable]
[dependency analysis completed]
[recovering /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin... done]
[introducing new bindings into toplevel environment...]
[starting dependency analysis]
[scanning /home/elsa/bug/bug2/second.cm]
[checking /home/elsa/bug/bug2/CM/x86-unix/second.cm.stable... not usable]
GC #0.0.0.0.1.10:   (10 ms)
[dependency analysis completed]
[recovering /home/elsa/bug/bug2/CM/x86-unix/second.sml.bin... done]
[introducing new bindings into toplevel environment...]
val it = 3 : int
[starting dependency analysis]
[scanning /home/elsa/bug/bug2/third.cm]
[checking /home/elsa/bug/bug2/CM/x86-unix/third.cm.stable... not usable]
[scanning /home/elsa/bug/bug1/first.cm]
[checking /home/elsa/bug/bug1/CM/x86-unix/first.cm.stable... not usable]
[parsing /home/elsa/bug/bug2/third.sml]
[dependency analysis completed]
[recovering /home/elsa/bug/bug1/CM/x86-unix/first.sml.bin... done]
[compiling /home/elsa/bug/bug2/third.sml -> /home/elsa/bug/bug2/CM/x86-unix/third.sml.bin]
[wrote /home/elsa/bug/bug2/CM/x86-unix/third.sml.bin]
[introducing new bindings into toplevel environment...]
val it = 0 : int
val result = false : bool
val it = () : unit
- 
norfolk% 

Comments:
Here is a uuencoded, gzipped, tar file with the test files and
directories.  Unpacked version can be found in bugs/tests.cm/bug1461.
=========
begin 644 bug.tgz
M'XL(`"XF<#8``^U946^B0!#VM?R*.5Y.FP9W%W9)VOATESY<[/7!>V\0ETJ*
M8!:X2"[WWV]!04M[M4UD-7:_Q*BX,A-FOIEO9Z?YX[#7,<!!+J70PPR[R-F^
M0P,$P)CM($(8=>5W%[ND![1KQTKD:>8)@!Z/4D^%O1/#5,9?OG"72?"1^+O8
M!L`($:SCKP)-_(-0I)GE+SJP(</)'.>-^#-<Q9\@1Z:`Y#_&E-@]0!WX\@*?
M//[C<"H\41A&FHG<SW+!X;;,!,,(4\-8)T6ZB.`:TKDG^,PXML,:!T6+_S+4
MA[>QE__4KOE/*"KK/W8QU?Q7@1;M8;0I!,9O+X(5C$#P`)#!8\W\L\2&_^3D
M])_6_TK0Q#_E?A+/.A&`^^H_1G2K_^1"6?\98[K^J\`K^F]29<):`%K6\]V!
M7+?.$ZT)SP-M_G<A`/?K/];H/]<ADO\$4:+YKP)MVC\7@(44@%\J86BM2@UX
M;&\U#HV&_]D\%-VT_W?T?WNC_S!S$:OF/S;6_%>!5_K_KS(3_M?^UVFBN_^Y
MH,7_(\U_Z);_Y2RXG/\XFO\JT**];O^?#"7_H\2;D6ZH7V$?_QFAS?S'9N7Y
M#W+U_E\-2IH_2)I_N[,6WA/_"G\>19(OY15S.$\6?%@^E^&+4T+SRKBX``@2
MX?,'P:,P?I)_";PHY7]O#*.^ZZ9VP/4([)W+[S*V,Y*JK+UA;KUUL8H=$_<3
MZS:,^*1(+7_^/11@6I8)_4OPX@*6D>=SF(5!P`6/LRL0W(NB`BX''_:QELW[
M7*RJ:^.AX&D>9?+W?NVZ_+Q9,KA1J:AJ_N,C\M_>[O\I8ZSBOZO/?Y5`*?^#
M/(8@C,-T#OU!!W6@-CNY&R?!SQ\67RT3D=V-P93W,>6"8S]M#8W3PC_5`W1N
$`"@`````
`
end
=========
Fix:     
Test: tests.cm/bug1461
Owner: Matthias
Status: fixed in 110.20 [Matthias]
----------------------------------------------------------------------
Number: 1462
Title: Error in "g" format handling
Keywords: Format (SMLofNJ-LIB)
Submitter: David McClain   dmcclain@azstarnet.com
Date: 12/12/98
Version: 110.0.3
System: x86 Windows NT 4.0 sr 3 (build 1381)
Subsystem: SML/NJ Library
Severity: minor
Problem:
  Machine and OS Independent: The handling of the "%g" format code for
  reals incorrectly omits the decimal point, so that, e.g., 

   Format.format "%g" [Format.REAL 1.2E8]  --->  12e08.

  It's relatively simple to fix the omission in the "format" function, in
  module Format.sml.

Code:
  See above...
Transcript:
  see above...
Comments:
  None. But, NICE WORK! Please keep it up!!
Fix:
    fun format s = let
	  val fmts = compileFormat s
	  fun doField (flags, wid, ty, arg) = let
		fun padFn s = (case (#ljust flags, wid)
		       of (_, NoPad) => s
			| (false, Wid i) => padLeft(s, i)
			| (true, Wid i) => padRight(s, i)
		      (* end case *))
		fun zeroPadFn (sign, s) = (case wid
		       of NoPad => raise BadFormat
			| (Wid i) => zeroLPad(s, i - (String.size sign))
		      (* end case *))
		fun negate i = ((PosInt(~i)) handle _ => MaxInt)
		fun doSign i = (case (i < 0, #sign flags, #neg_char flags)
		       of (false, AlwaysSign, _) => ("+", PosInt i)
			| (false, BlankSign, _) => (" ", PosInt i)
			| (false, _, _) => ("", PosInt i)
			| (true, _, TildeSign) => ("~", negate i)
			| (true, _, _) => ("-", negate i)
		      (* end case *))
		fun doRealSign sign = (case (sign, #sign flags, #neg_char flags)
		       of (false, AlwaysSign, _) => "+"
			| (false, BlankSign, _) => " "
			| (false, _, _) => ""
			| (true, _, TildeSign) => "~"
			| (true, _, _) => "-"
		      (* end case *))
		fun doExpSign (exp, isCap) = let
		      val e = if isCap then "E" else "e"
		      fun mkExp e = zeroLPad(Int.toString e, 2)
		      in
			case (exp < 0, #neg_char flags)
			 of (false, _) => [e, mkExp exp]
			  | (true, TildeSign) => [e, "~", mkExp(~exp)]
			  | (true, _) => [e, "-", mkExp(~exp)]
			(* end case *)
		      end
		fun octal i = let
		      val (sign, i) = doSign i
		      val sign = if (#base flags) then sign^"0" else sign
		      val s = intToOctal i
		      in
		        if (#zero_pad flags)
			  then sign ^ zeroPadFn(sign, s)
			  else padFn (sign ^ s)
		      end
		fun decimal i = let
		      val (sign, i) = doSign i
		      val s = intToStr i
		      in
			if (#zero_pad flags)
			  then sign ^ zeroPadFn(sign, s)
		          else padFn (sign ^ s)
		      end
		fun hexidecimal i = let
		      val (sign, i) = doSign i
		      val sign = if (#base flags) then sign^"0x" else sign
		      val s = intToHex i 
		      in
		        if (#zero_pad flags)
			  then sign ^ zeroPadFn(sign, s)
			  else padFn (sign ^ s)
		      end
	        fun capHexidecimal i = let
		      val (sign, i) = doSign i
		      val sign = if (#base flags) then sign^"0X" else sign
		      val s = intToHeX i 
		      in
		        if (#zero_pad flags)
			  then sign ^ zeroPadFn(sign, s)
			  else padFn (sign ^ s)
		      end
		in
		  case (ty, arg)
		   of (OctalField, LINT i) => octal i
		    | (OctalField, INT i) => octal(Int.toLarge i)
		    | (IntField, LINT i) => decimal i
		    | (IntField, INT i) => decimal(Int.toLarge i)
		    | (HexField, LINT i) => hexidecimal i
		    | (HexField, INT i) => hexidecimal(Int.toLarge i)
		    | (CapHexField, LINT i) => capHexidecimal i
		    | (CapHexField, INT i) => capHexidecimal(Int.toLarge i)
		    | (CharField, CHR c) => padFn(String.str c)
		    | (BoolField, BOOL false) => padFn "false"
		    | (BoolField, BOOL true) => padFn "true"
		    | (StrField, ATOM s) => padFn(Atom.toString s)
		    | (StrField, STR s) => padFn s
		    | (RealField{prec, format=F_Format}, REAL r) => let
		        val {sign, mantissa} = RealFormat.realFFormat(r, prec)
		        val sign = doRealSign sign
		        in
		          if ((prec = 0) andalso (#base flags))
			    then padFn(concat[sign, mantissa, "."])
			    else padFn(sign ^ mantissa)
		        end
		    | (RealField{prec, format=E_Format isCap}, REAL r) => let
		        val {sign, mantissa, exp} = RealFormat.realEFormat(r, prec)
		        val sign = doRealSign sign
		        val expStr = doExpSign(exp, isCap)
		        in
		          if ((prec = 0) andalso (#base flags))
			    then padFn(concat(sign :: mantissa :: "." :: expStr))
			    else padFn(concat(sign :: mantissa :: expStr))
		        end
		    | (RealField{prec, format=G_Format isCap}, REAL r) => let
		        val prec = if (prec = 0) then 1 else prec
		        val {sign, whole, frac, exp} =
			      RealFormat.realGFormat(r, prec)
		        val sign = doRealSign sign
		        val expStr = (case exp
			       of SOME e => doExpSign(e, isCap)
			        | NONE => [])
		        val num = if (#base flags)
			        then let
			          val diff = prec - ((size whole) + (size frac))
			          in
				    if (diff > 0)
				      then zeroRPad(frac, (size frac)+diff)
				      else frac
			          end
			      else if (frac = "")
			        then ""
			        else ("." ^ frac)
		        in  (* Here is a cheap fix, but it will conflict with the line above... *)
		          padFn(concat(sign::whole::"."::frac::expStr))
		        end
		    | (_, LEFT(w, arg)) => let
		        val flags = {
			        sign = (#sign flags), neg_char = (#neg_char flags),
			        zero_pad = (#zero_pad flags), base = (#base flags),
			        ljust = true, large = false
			      }
		        in
			  doField (flags, Wid w, ty, arg)
		        end
		    | (_, RIGHT(w, arg)) => doField (flags, Wid w, ty, arg)
		    | _ => raise BadFmtList
		  (* end case *)
		end
	  fun doArgs ([], [], l) = SS.concat(rev l)
	    | doArgs ((Raw s)::rf, args, l) = doArgs(rf, args, s::l)
	    | doArgs (Field(flags, wid, ty)::rf, arg::ra, l) =
		doArgs (rf, ra, SS.all (doField (flags, wid, ty, arg)) :: l)
	    | doArgs _ = raise BadFmtList
	  in
	    fn args => doArgs (fmts, args, [])
	  end (* format *)

Test: 
Owner: jhr
Status: open 
----------------------------------------------------------------------
Number: 1463
Title: Broken ARRAY2 Code
Keywords: indexing/projection
Submitter: David McClain   dmcclain@azstarnet.com
Date: 12/13/98
Version: 110.0.3
System: x86 Windows NT 4.0 r 3 (build 1381)
Subsystem: SML basis library
Severity: major
Problem:
Indexing for projection of rows works incorrectly.
Code:
  structure A2 = Array2;

  val x = A2.tabulate A2.RowMajor (2,3,fn (r,c) => 10 * r + c);

  A2.row(x,0); --> val it = #[0,1] : int vector (* Nope! *)
  A2.row(x,1); --> val it = #[10,11] : int vector (* ditto *)

  A2.column(x,0); --> val it = #[0,10] : int vector (* these are okay *)
  A2.column(x,1); --> val it = #[1,11] : int vector
  A2.column(x,2); --> val it = #[2,12] : int vector

Transcript:
see above
Comments:
  Looks like I need to implement my own...
Fix:
  This one is a bit beyond me at this early time...
Test: bug1463.1.sml
Owner: jhr, Emden
Status: fixed in 110.9.1 and in 110.0.4 [jhr]
----------------------------------------------------------------------
Number: 1464
Title: unnecessary instantiation of local nongeneralized types
Keywords: type checking, generalization
Submitter: Matthias Blume <blume@kurims.kyoto-u.ac.jp>
Date: 12/16/98
Version: 110.x
System: -
Severity: minor 
Problem: 
It think it is unnecessary to instantiate any non-generalized type
vars that belong to definitions between "local" and "in".  Those
definitions never escape to the top level (which is the only place
where they would hurt).
Code:
Transcript:
Comments:
 [dbm]
  Declarations in local part of a local dec should be treated the
  same as the declarations in let expressions.
Fix:
Test:
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1465
Title:       Type variables not as general as Definition.
Keywords:    type variable
Submitter:   Stephen Weeks <sweeks@research.nj.nec.com>
Date:        12/17/98
Version:     Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998
System:      x86-linux
Severity:    
Problem:     

The class of type variables allowed is not as general as allowed in
the Definition.  For example, I believe the following four
declarations are valid.

Code:        

type '' t = int
type '_ t = int
type ''' t = int
type ''1 t = int

Transcript:  
Comments:    
Fix:         

In ml.lex, the case for type variables should be changed from:

<INITIAL>"'"("'"?)("_"|{num})?{id}

to the following:

<INITIAL>"'"{idchars}*

Test: bug1465.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1466
Title:       GC signal never sent
Keywords:    runtime, GC
Submitter:   Roland McGrath <roland@ai.mit.edu>
Date:        12/16/1998
Version:     110.8
System:      x86-linux
Severity:    minor
Problem:     The Signals.sigGC signal is never in fact raised.
	     Furthermore, in fixing this I discovered the additional bug
	     that any ML signal causes an extra unwarranted minor GC.
	     In the case of the GC signal, this iterates infinitely,
	     running the sigGC handler function repeatedly and nothing else.
Code:        

(* set the GC handler to print so we can tell *)
open Signals; 
setHandler (sigGC, HANDLER (fn (_,_,k) => (print "foobar\n"; k)));

(* force a collection *)
SMLofNJ.Internals.GC.doGC 99;

(* it should have printed "foobar\n", but it didn't *)

Transcript:  

Standard ML of New Jersey v110.8 [FLINT v1.41], August 5, 1998 [full]
val use = fn : string -> unit
- open Signals;
opening Signals
  eqtype signal
  datatype sig_action
    = DEFAULT | HANDLER of signal * int * unit ?.cont -> unit ?.cont | IGNORE
  val listSignals : unit -> signal list
  val toString : signal -> string
  val fromString : string -> signal option
  val setHandler : signal * sig_action -> sig_action
  val overrideHandler : signal * sig_action -> sig_action
  val inqHandler : signal -> sig_action
  datatype sigmask = MASK of signal list | MASKALL
  val maskSignals : sigmask -> unit
  val unmaskSignals : sigmask -> unit
  val masked : unit -> sigmask
  val pause : unit -> unit
  val sigINT : signal
  val sigALRM : signal
  val sigTERM : signal
  val sigGC : signal
- setHandler (sigGC, HANDLER (fn (_,_,k) => (print "foobar\n"; k)));
val it = IGNORE : sig_action
- SMLofNJ.Internals.GC.doGC 99;
GC #1.1.1.1.1.11:   (62 ms)
val it = () : unit

Comments:
  For some reason I have not ascertained, there are always at
  least two collections at once (the sigGC handler is always
  called at least twice).  I don't think this is right, but two
  is closer to one than zero is by my reckoning.

 [jhr, 12/16/98]
  The GC signal got disabled a while back when I was fixing some problems
  with the signal handlers.  It will be fixed in the new run-time system
  that we are working on (should be out in Feb 1999).

  GC signals should not be generated for minor collections, so the infinite
  loop that you encountered can be avoided.

 [Roland McGrath]
  > Firstly, do you agree with my analysis that handling an ML signal induces a
  > spurious minor collection and my fix to avoid that by restoring the real
  > limit pointer?  In my view it is that bug, not signalling on minor
  > collections, that is responsible for the infinite loop.  (And, harmless
  > though it may be, I would like to avoid the extra unwarranted
  > collection--when we have clock ticks arriving as ML signals, the cost of
  > the extra collection might become a practical concern.)

 [jhr]
  In the earlier implementation, where GC signals were actually generated,
  I chose to only generate them for "major" collections.  Minor collections
  happen at a very high rate, and it seems excessive to generate a signal
  for each one.  As far as the extra collection goes, avoiding it in your situation
  is probably worth while, but I don't think that it is worth fixing for
  the current run-time.  I'll try to avoid it in the new run-time.

 [Roland McGrath]
  > Secondly, I think I really would like to have my signal handler run for
  > minor collections.  I am interested in your opinion on this.  My use of the
  > GC signal is, along with weak pointers, to implement finalizers for a
  > special kind of object (i.e. an ML record held weakly is logically keeping
  > alive a foreign object that must be explicitly deallocated).  These objects
  > have extent appropriate for minor collections (they are a kind of call
  > frame).  As they may be created and become garbage very quickly, I am
  > concerned about delaying their collection until a major collection.  (I can
  > work around the problem by catching an actual resource shortage, forcing a
  > major collection (with SMLofNJ.Internals.GC.doGC), and retrying the
  > allocation, before diagnosing it as an out-of-resource exception.)

 [jhr]
  In the new collector, we directly support finalized objects (using Dybvig's
  guardian scheme), but we do not finalize objects on minor collections.
  In a copy collected system, finalization should never be relied on to
  free objects in a timely fashion.  You will need some backup to force
  finalization (by doing GC), when a scare resource is exhausted.  Handling
  weak pointers and finalized objects requires extra overhead, which I'd like
  to avoid in minor collections.


Fix:         The following patch to the runtime does three things:

1 (gc/call-gc.c).  Call GCSignal at the end of InvokeGC.  I don't know if
  this is the right place to call it, but it's the obvious one.  It
  delivers the signal to whichever vproc invoked the GC, which seems correct.

2 (kernel/run-ml).  When handling an ML signal, reset the limit pointer to
  the real heap limit if we do not perform a GC.  This should probably go
  in a subroutine in gc/*.c, and I don't think it dtrt for MP.

3 (mach-dep/signal-util.c).  I don't think this was actually necessary to
  fix anything, since numPendingSigs and numPendingSysSigs are added
  together and the sum tested.  But it just looked wrong to me.

Index: smlnj/runtime/gc/call-gc.c
diff -c smlnj/runtime/gc/call-gc.c:1.1.1.1 smlnj/runtime/gc/call-gc.c:1.2
*** smlnj/runtime/gc/call-gc.c:1.1.1.1	Tue Oct  6 18:05:08 1998
--- smlnj/runtime/gc/call-gc.c	Wed Dec 16 16:50:48 1998
***************
*** 230,235 ****
--- 230,237 ----
  
      ASSIGN(ProfCurrent, PROF_RUNTIME);
  
+     GCSignal (msp->ml_vproc);
+ 
  } /* end of InvokeGC */
Index: smlnj/runtime/kernel/run-ml.c
diff -c smlnj/runtime/kernel/run-ml.c:1.1.1.2 smlnj/runtime/kernel/run-ml.c:1.2
*** smlnj/runtime/kernel/run-ml.c:1.1.1.2	Tue Oct  6 18:10:03 1998
--- smlnj/runtime/kernel/run-ml.c	Wed Dec 16 16:50:48 1998
***************
*** 17,22 ****
--- 17,23 ----
  #include "c-library.h"
  #include "profile.h"
  #include "gc.h"
+ #include "../gc/heap.h"		/* XXX for HEAP_LIMIT */
  
  /* local functions */
  PVT void UncaughtExn (ml_val_t e);
***************
*** 90,95 ****
--- 91,103 ----
  	      /* check for GC */
  		if (NeedGC (msp, 4*ONE_K))
  		    InvokeGC (msp, 0);
+ 		else
+ 		  /* Reset the limit pointer since no actual GC happened.
+ 		     Otherwise, we would do a spurious GC before handling
+ 		     the signal (which is especially problematical for
+ 		     the GC signal!).  */
+ 		    msp->ml_limitPtr	= HEAP_LIMIT(msp->ml_heap);
+ 
  	      /* invoke the ML signal handler */
  		ChooseSignal (vsp);
  		msp->ml_arg		= MakeHandlerArg (msp, sigh_resume);
Index: smlnj/runtime/mach-dep/signal-util.c
diff -c smlnj/runtime/mach-dep/signal-util.c:1.1.1.1 smlnj/runtime/mach-dep/signal-util.c:1.2
*** smlnj/runtime/mach-dep/signal-util.c:1.1.1.1	Tue Oct  6 18:05:10 1998
--- smlnj/runtime/mach-dep/signal-util.c	Wed Dec 16 16:50:48 1998
***************
*** 31,39 ****
      vsp->vp_sigCode = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].sigNum;
      vsp->vp_sigCount = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].count;
      if (IS_SYSTEM_SIG(vsp->vp_sigCode))
!         vsp->vp_numPendingSigs -= vsp->vp_sigCount;
      else
! 	vsp->vp_numPendingSysSigs -= vsp->vp_sigCount;
  
    /* advance the pending queue */
      if ((--vsp->vp_numInQ == 0) || (++vsp->vp_nextPendingSig == NUM_SIGS))
--- 31,39 ----
      vsp->vp_sigCode = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].sigNum;
      vsp->vp_sigCount = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].count;
      if (IS_SYSTEM_SIG(vsp->vp_sigCode))
!         vsp->vp_numPendingSysSigs -= vsp->vp_sigCount;
      else
! 	vsp->vp_numPendingSigs -= vsp->vp_sigCount;
  
    /* advance the pending queue */
      if ((--vsp->vp_numInQ == 0) || (++vsp->vp_nextPendingSig == NUM_SIGS))


Test: -
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1467
Title: Looping functions fail in FLINT
Keywords: FLINT
Submitter: Allen Leung   leunga@cs.nyu.edu
Date: 12/30/98
Version: 110.11
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
FLINT fails on functions such as 


    fun loop() = loop()
or  fun loop i = loop i

Note: The previous bug reported by me is actually caused by this simple
problem.  Please discard previous report.
Code:

Transcript:
- fun loop() = loop();

looking up unbound v27{3,3}
while in fcontract phase

uncaught exception IntmapF
  raised at: ../comp-lib/intmapf.sml:199.25-199.32
             FLINT/opt/fcontract.sml:327.13
             FLINT/main/flintcomp.sml:146.13
- fun loop i = loop i;

while in reify phase

uncaught exception RecoverLty
  raised at: ../comp-lib/intmap.sml:28.41-28.44
             FLINT/main/flintcomp.sml:146.13

Comments:
 [jhr, 12/30/98]
  It appears that this bug was introduced in 110.10.
Fix:

Test: 
Owner: Zhong
Status: open
----------------------------------------------------------------------
Number: 1468
Title:       ccalls crashes on Cfunction(fn _ => Cvoid)
Keywords:    runtime, ccalls
Submitter:   Roland McGrath <roland@ai.mit.edu>
Date:        12/30/1998
Version:     110.8
System:	     x86-linux
Severity:    minor
Problem:     An ML function called from C that returns Cvoid crashes the runtime.
Code:	     <SML source code to reproduce the bug>
Transcript:  <transcript of execution demonstating the bug>
Comments:    I did not provide source or transcript because it requires a
	     runtime with ccalls compiled in and hacked with some C function
	     available via CCalls that makes a callback to ML.
	     Passing such a function `Cfunction(fn _ => Cvoid)' will crash
	     the runtime when that ML function attempts to return to C.
Fix:	     Patch to runtime/c-libs/smlnj-ccalls/c-calls-fns.c follows.

Index: c-calls-fns.c
===================================================================
RCS file: /projects/express/cvsroot/smlnj/runtime/c-libs/smlnj-ccalls/c-calls-fns.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -p -r1.2 -r1.3
--- c-calls-fns.c	1998/12/16 20:00:01	1.2
+++ c-calls-fns.c	1998/12/30 19:43:18	1.3
@@ -178,6 +178,12 @@ PVT Word_t convert_result(ml_state_t *ms
     char *t = chp->rettype;
     int err;
 
+    if (*t == 'V')
+        /* The return type is void, meaning val must be Cvoid
+	 * and our return value will be ignored by the C caller.
+	 */
+        return 0;
+
     /* front-end of interface guarantees that ret is a valid
      * return value for a C function: Word_t or some pointer
      */


Test: *
Owner: Lorenz, Riccardo
Status: open
----------------------------------------------------------------------
Number: 1469
Title: Integer assignment should be unboxed assign
Keywords: FLINT convert
Submitter: Allen Leung   leunga@cs.nyu.edu
Date: 12/30/98
Version: 110.11
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: major
Problem:
  Integer assignment should use unboxedassign.  In 110.11 storelist
  maintainence instructions are generated for assignments such as

     x := y

  where x : int ref

  Note: mandelbrot runs about twice as slow on the HP
  and 1/3 slower on the sparc when compared to 110.9.1
Code:
  Compiler.Control.CG.printit := true;
  val x = ref 0;
  fun f y = x := y;
Transcript:
************************************************* 
v481(v497[PV],v496[PV],v495[C],v494[PV],v493[PV],v492[PV],v491[I]) =
   v496.1 -> v498[PV]
   assign(v498,v491)
   v495(v495,v494,v493,v492,(I)0)
************************************************* 

Comments:
 [jhr, 12/30/98]
  This one is probably my fault.  When I put in the new array
  representation support, I had to make := and Array.update
  be different (the Array.update has an extra level of indirection).
  I guess that I must have broken the type-based specialization.
 [jhr, 12/30/98]
  I just took a look at the code (from the 110.11 sources), and I'm
  not sure why the optimization isn't being done.  Here is the
  code from FLINT/cpsopt/contract.sml:

  fun setter (P.update, [_, _, INT _]) = P.unboxedupdate
    | setter (P.update, [_, _, REAL _]) = P.boxedupdate
    | setter (P.update, [_, _, STRING _]) = P.boxedupdate
    | setter (P.update, [_, _, VAR v]) =
       (case #info(get v)
	 of (FNinfo _) => P.boxedupdate
	  | (RECinfo _) => P.boxedupdate
	  | (OFFinfo _) => P.boxedupdate
	  | _ => P.update
	  (* end case *))
    | setter (P.assign, [_, INT _]) = P.unboxedassign
    | setter (i, _) = i

  It looks like assignment of int refs should be translated to
  an unboxedassign.
 [Zhong, 12/30/98]
  This is not the right place. To fix it, you need to add 
  a new "UNBOXEDASSIGN" primop into the FLINT/kernel/primop.{sig,sml}.
  Then add the following case to the "classPrim" function in 
  FLINT/reps/wrapping.sml:

	 | (PO.ASSIGN, [tc]) =>                           (* special *)
	   let val np =
		 if LT.tc_upd_prim tc = PO.UNBOXEUPDATE then PO.UNBOXEDASSIGN
		 else p
	    in ((d, np, lt, ts), false, false)
	   end

Fix:
 [jhr, 12/30/98]
  I've put in a fix (supplied by Zhong) for this bug and it seems
  to work (at least the cps says "unboxedassign").  I'll commit
  these changes for 110.12; note that the pickler has changed
  to handle the new UNBOXEDASSIGN primop.
Test: bug1469.1.sml
Owner: jhr
Status: fixed in 110.12
----------------------------------------------------------------------
Number: 1470
Title: compilation blowup (in FLINT?)
Keywords: compiler performance
Submitter: Daniel Wang <danwang@CS.Princeton.EDU>
Date: 9/10/98
Version: 110.0.3
System: -
Severity: major 
Problem: 
  Should I expect this to elaborate in a resonable amount of time for
  110.0.3. The signature elaborates in almost no time, but when elaborating
  the structure things get bogged down. The FLINT types should be able to
  represent this type efficiently right? So is this a performance bug in the
  elaborator? When sml gets bogged down elaborating the structure it's space
  usage seems to be constant.
Code:
  signature PRIMS =
    sig
      datatype ('a,'b) sum = L of 'a |  R of 'b
      type b1  = unit
      type b2  = (b1,b1)   sum
      type b3  = (b2,b2)   sum
      type b4  = (b3,b3)   sum
      type b5  = (b4,b4)   sum
      type b6  = (b5,b5)   sum
      type b7  = (b6,b6)   sum
      type b8  = (b7,b7)   sum
      type b9  = (b8,b8)   sum
      type b10 = (b9,b9)   sum
      type b11 = (b10,b10) sum
      type b12 = (b11,b11) sum
      type b13 = (b12,b12) sum
      type b14 = (b13,b13) sum
      type b15 = (b14,b14) sum
      type b16 = (b15,b15) sum
      type b17 = (b16,b16) sum
      type b18 = (b17,b17) sum
      type b19 = (b18,b18) sum
      type b20 = (b19,b19) sum
      type b21 = (b20,b20) sum
      type b22 = (b21,b21) sum
      type b23 = (b22,b22) sum
      type b24 = (b23,b23) sum
      type b25 = (b24,b24) sum
      type b26 = (b25,b25) sum
      type b27 = (b26,b26) sum
      type b28 = (b27,b27) sum
      type b29 = (b28,b28) sum
      type b30 = (b29,b29) sum
      type b31 = (b30,b30) sum
      type b32 = (b31,b31) sum 
    end

  structure Prims :> PRIMS =
    struct
      datatype ('a,'b) sum = L of 'a |  R of 'b
      type b1  = unit
      type b2  = (b1,b1)   sum
      type b3  = (b2,b2)   sum
      type b4  = (b3,b3)   sum
      type b5  = (b4,b4)   sum
      type b6  = (b5,b5)   sum
      type b7  = (b6,b6)   sum
      type b8  = (b7,b7)   sum
      type b9  = (b8,b8)   sum
      type b10 = (b9,b9)   sum
      type b11 = (b10,b10) sum
      type b12 = (b11,b11) sum
      type b13 = (b12,b12) sum
      type b14 = (b13,b13) sum
      type b15 = (b14,b14) sum
      type b16 = (b15,b15) sum
      type b17 = (b16,b16) sum
      type b18 = (b17,b17) sum
      type b19 = (b18,b18) sum
      type b20 = (b19,b19) sum
      type b21 = (b20,b20) sum
      type b22 = (b21,b21) sum
      type b23 = (b22,b22) sum
      type b24 = (b23,b23) sum
      type b25 = (b24,b24) sum
      type b26 = (b25,b25) sum
      type b27 = (b26,b26) sum
      type b28 = (b27,b27) sum
      type b29 = (b28,b28) sum
      type b30 = (b29,b29) sum
      type b31 = (b30,b30) sum
      type b32 = (b31,b31) sum 
    end

Comments:
Fix:
Test: 
Owner: dbm, Zhong
Status: open
----------------------------------------------------------------------
Number: 1471
Title: interrupt ignored in heap image created in background
Keywords: interrupt, signal handling
Submitter: Matthias Blume <blume@kurims.kyoto-u.ac.jp>
Date: 10/20/98
Version: 110.9.1
System: -
Severity: minor 
Problem: 
  I just ran into a nasty little problem.  (I'd rate it a "minor"
  problem, but maybe it can be fixed.)

  When I installed 110.9.1 over here, I wanted to capture an install
  log.  So I did

	  config/install.sh >logfile 2>&1

  and since this meant I wouldn't be able to see anything anyway, I
  thought I _SEND THIS COMMAND INTO THE BACKGROUND_ ...

	  config/install.sh >logfile 2>&1 &

  But sending a command into the background like this means that SIGINT
  gets disabled.  Somehow, ML inherits the disabled interrupt, which
  means that the resulting heap image will ignore control-C.

  Now, the obvious workaround is not to do what I did, but perhaps there 
  is a way of avoiding this potential problem. (?)

Comments:
 [jhr]
  This is the desired semantics under Unix.  Background processes are
  started with SIGINT ignored, and it is bad form to change that (you
  don't want a ^C to the forground to kill all of your backgroup
  processes do you?).
 [Matthias]
  You misunderstood my desire:  I don't want to have signals turned back 
  on while "makeml" (or "config/install.sh") is running.  After all, I
  had sent it to the background because I didn't want to be bothered by
  it.

  The problem is that with the resulting heap-image, which will run
  later in a separate process and _not_ in the background, interrupts
  are _still_ disabled.
 [jhr]
  I see.  Looking at the code, I think that this problem may be
  fixed by changing the "AtInit" cleaner for signals from resetSigTbl
  to initSigTbl, but this means that there is no persistence of signal
  handlers across exportML, which may cause other problems.
 [jhr, 2/8/99]
  This is a feature, not a bug.

 [Matthias, 4/20/99]
  I don't agree with John's comment that bug 1471 be not a bug.  Why?
  What's the point of inheriting (via the heap image) the ignored
  signals of a different process which perhaps ran a long time ago, on a
  different machine, perhaps in the background, etc.?

  I would like to submit the following view:

  1. Signals that are inherited by the usual Unix semantics (via fork
  and exec) should be considered part of the process environment
  (together with the stuff that one can access via OS.Process.getEnv).
  This process environment will be set up anew every time we start a new
  SML/NJ process and does not get propagated via heap images.

  2. Signals that have actively been set by the process are no longer
  considered part of the process environment but part of the process
  state itself.  Those signals will get propagated via heap images.

  I can see that this "part of the environment"/"part of the process
  state" dichotomy may require some additional hair to be introduced
  into the implementation of signal.  However, I find the above
  intuitive and more consistent than what we have now.

Fix:
Test:
Owner: jhr
Status: not a bug???
----------------------------------------------------------------------
Number: 1472
Title: datatype involving real are treated as equality types
Keywords: equality types, datatypes, real
Submitter: Nevin Heintze <nch@research.bell-labs.com>
Date: 10/23/98
Version: 110.9.1
System: -
Severity: major 
Problem: 
  With the definition:

	  datatype expression = 
	       RealConst of real |
	      Cast of ctype * expression

	  and ctype =
	      Struct of declarator

	  and declarator = 
	      Array_d of expression

  the frontend allows declarator to be treated as an equality type, but it
  should not.  For example:

     (fn (x:declarator, y) => (x = y));

  gives

    val it = fn : declarator * declarator -> bool

  whereas 

     (fn (x:Real.real, y) => (x = y))

  gives an error 

    operator domain: ''Z * ''Z
    operand:         real * 'Y
    in expression:
      x = y

  However, both should give an error.

Code:
Transcript:
Comments:
Fix:
Test: bug1472.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1473
Title: weak pointer to a string causes core dump
Keywords: weak pointers
Submitter: Daniel Wang <danwang@CS.Princeton.EDU>
Date: 12/2/98
Version: 110.9.1
System: ?
Severity: minor
Problem: 
  Should this be broken? Is there a work around... (LiftLitteral flag???) 
Code:
Transcript:
  Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998
  val use = fn : string -> unit
  - val x = SMLofNJ.Weak.weak' "this is a string";
  val x = - : ?.Weak.weak'
  - SMLofNJ.Internals.GC.doGC 100;
  GC #1.1.1.1.1.5:  /home/danwang/SMLNJ/110.9.1/dist/bin/sml: Fatal error -- weak big object

  Process sml exited abnormally with code 1
Comments:
 [Matthias, 12/3/98]
  Can't you wrap a ref around your string?

  In any case, weak pointers to state-free objects ("values") are
  semantically troublesome. (See the discussion on the SML/NJ web
  pages.)  Your safest bet is to make sure you only create weak pointers
  to things like references.  As a side benefit this would work around
  the bug (feature?) that you described above.
 [jhr, 2/8/99]
  This should be fixed with the new literal representation.

Fix:
Test:
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1474
Title: Uncaught exception Compile "translate failed"
Keywords: CM redundant match
Submitter: Elsa L. Gunter   elsa@research.bell-labs.com
Date: 01/07/99
Version: 110.9.1
System: x86 Linux 
Subsystem: Compilation manager (CM)
Severity: minor
Problem:
  When CM encounters a bad pattern where the match is redundant, in
  addition to reporting an error, it raises uncaught exception Compile:
  "translate failed"

Code:
  (* sources.cm *)

  Group is
  translate_bug.sml

  (*--------------------------------------------------------------*)
  (* translate_bug.sml *)

  structure C =
      struct
	  datatype t = A | B
	  val f = fn A => () | A => ()
      end

Transcript:
  % sml
  Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998
  val use = fn : string -> unit
  - CM.make();
  [starting dependency analysis]
  [scanning sources.cm]
  [checking CM/x86-unix/sources.cm.stable... not usable]
  [parsing translate_bug.sml]
  [dependency analysis completed]
  [compiling translate_bug.sml -> CM/x86-unix/translate_bug.sml.bin]
  translate_bug.sml:4.10-4.30 Error: match redundant and nonexhaustive
	    A => ...
      -->   A => ...


  uncaught exception Compile: "translate failed"
    raised at: TopLevel/batch/binfile.sml:466.38-466.65
	       ../cm/sched/recompile.sml:203.38-203.41

Comments:
  If you use the file translate_bug.sml instead of doing CM.make, the
  exception is not raised.
Fix:

Test: 
Owner: Matthias
Status: fixed in 110.20 [Matthias]
----------------------------------------------------------------------
Number: 1475
Title: CM uncaught exception Compile elaborate
Keywords: CM pattern matching
Submitter: Elsa L. Gunter   elsa@research.bell-labs.com
Date: 01/07/99
Version: 110.9.1
System: x86 Linux 
Subsystem: Compilation manager (CM)
Severity: minor
Problem:
  When CM encounter a bad pattern having a constant constructor applied to
  an arguement, in addition to giving and error, it raises an uncaught
  exception Compile: "elaborate failed"
Code:
  (* sources.cm *)

  Group is
  elaborate_bug.sml

  (*------------------------------------------------------------------*)
  (* elaborate_bug.sml *)

  structure C =
      struct
	  datatype t = A
	  val f = fn A a => ()
      end

Transcript:
  % sml
  Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998
  val use = fn : string -> unit
  - CM.make();
  [starting dependency analysis]
  [scanning sources.cm]
  [checking CM/x86-unix/sources.cm.stable... not usable]
  [parsing elaborate_bug.sml]
  [Creating directory CM/DEPEND ...]
  [dependency analysis completed]
  [compiling elaborate_bug.sml -> CM/x86-unix/elaborate_bug.sml.bin]
  elaborate_bug.sml:4.10-4.22 Error: constant constructor applied to argument in pattern:A

  uncaught exception Compile: "elaborate failed"
    raised at: TopLevel/batch/binfile.sml:466.38-466.65
	       ../cm/sched/recompile.sml:203.38-203.41

Comments:
  When elaborate_bug.sml is used instead of being loaded via CM.make,
  the uncaught exception does not occur.

Fix:

Test: 
Owner: Matthias
Status: fixed in 110.20 [Matthias]
----------------------------------------------------------------------
Number: 1476
Title: Missing operation in WORD
Keywords: WORD ~
Submitter: Henry Cejtin   henry@research.nj.nec.com
Date: 11/02/98
Version: 1108
System: Any/All Any Unix 
Subsystem: SML basis library
Severity: 
Problem:
  This is not a bug as much as a missing operation.  The WORD signature
  should have the ~ operation defined in it.  words represent integers
  modulo 2^?, so negation makes perfect sense.  It is currently available
  via
	  0w0 - ?
  but should be directly supported.

Comments:
  A new feature request.
Fix:

Test: 
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1477
Title:       assembler syntax nits for X86.prim.asm
Keywords:    runtime, asm, X86.prim.asm
Submitter:   Roland McGrath <roland@ai.mit.edu>
Date:        11/18/1998
Version:     110.8
System:      x86-linux, x86-freebsd, x86-netbsd
Severity:    cosmetic
Problem:     assembler on these system wants * before register in indirect jump
Code:        n/a
Transcript:  n/a
Comments:
  The GNU assembler, which is used on all the free x86 operating systems,
  wants a * prefix on register names in indirect jmp instructions.  Without
  the * it generates a warning, but to my knowledge still assembles the
  instructions correctly.

  The X86.prim.asm code allows for this syntax, by use of the `via' macro.
  My patch defines this macro to * for systems that use the GNU assembler,
  and fixes one instruction missing a "via" and one instruction where an
  inappropriate "via" was inserted.

  The patch includes a check for OPSYS_OSKIT, which is a new symbol for our
  research project's (unpublished) system, so you might not want to include
  that symbol in the check.

Fix:         patch to mach-dep/X86.prim.asm attached below
Index: X86.prim.asm
===================================================================
RCS file: /projects/express/cvsroot/smlnj/runtime/mach-dep/X86.prim.asm,v
retrieving revision 1.1.1.3
retrieving revision 1.5
diff -u -b -p -r1.1.1.3 -r1.5
--- X86.prim.asm	1998/10/06 22:21:35	1.1.1.3
+++ X86.prim.asm	1998/11/17 19:51:53	1.5
@@ -101,7 +101,13 @@
 #define PSEUDOREG_1	vreg12
 #define PSEUDOREG_2 	vreg13
 
+#if (defined(OPSYS_LINUX) || \
+     defined(OPSYS_FREEBSD) || defined(OPSYS_NETBSD) || \
+     defined(OPSYS_OSKIT))
+#define	via *
+#else
 #define	via
+#endif
 
 
 	DATA
@@ -173,7 +179,7 @@ LABEL(CSYM(ML_X86Frame)) /* ptr to the m
 	jb	9f;							\
 	lea	1b, temp;		/* temp holds resume address */	\
 	movl	IMMED(maskval), mask;					\
-	jmp	via CSYM(saveregs);					\
+	jmp	CSYM(saveregs);			      			\
  9:
 
 /**********************************************************************/
@@ -533,7 +539,7 @@ restore_and_jmp_ml:
 jmp_ml:
 	movl	PCOffMSP(temp),temp
 	cmpl	limitptr, allocptr
-	jmpl	temp		      /* Jump to ML code. */
+	jmpl	via temp		/* Jump to ML code. */
 
 pending:
 	cmpl	IMMED(0),InSigHandlerOffVSP(vsp)   /* Currently handling signal? */


Test: -
Owner: jhr
Status: fixed in 110.0.4
----------------------------------------------------------------------
Number: 1478
Title: Fatal Error win32:fault_handler
Keywords: Windows
Submitter: Adam Maciak   maciak@mu-luebeck.de
Date: 01/15/99
Version: 110
System: Other (describe below) Windows 95 a
Subsystem: SML compiler
Severity: critical
Problem:
By typing "use filename" SML closed, because of this bug:
Fatal Error -- win32:fault:handler: unexpected fault @0x1682clf, code = 0xc0000005

Code: ?

Transcript:
  [custon] C:\sml\bin>sml-cm.bat
  Standart ML of new Jersey 110.0.3, January 30,1998 [CM&CMB]
  - use "37.ml";
  [opening 37.ml]
  val lexOrd = fn: char list * char list -> bool
  c:\SML\BIN~1\RUNX86~1.EXE: Fatal Error -- win32:fault_handler ...

Comments:
  After installing Quicktime, SML crashes each time I want to "use" a file.
  I have reinstalled SML and Windows many times but the problem could not be solved.

 [Lorenz, 1/15/99]
  Could you send the smallest piece of source you can make 
  that exhibits this problem?  

  Do you have an NT system to test this on?  Since NT has memory
  protection and 95 does not, it would indicate if a bug in SML/NJ 
  (or elsewhere, e.g. in Quicktime) is stomping on the address space.

Fix:
  Uninstalling Quicktime solved the problem a little bit, that means,
  SML crashes not every time i type "use filename", but every 10th - 20th time.
Test: 
Owner: Lorenz, Riccardo
Status: open
----------------------------------------------------------------------
Number: 1479
Title: failure to run under IRIX 6.5
Keywords: IRIX
Submitter: cporter@sgi.com
Date: 1/18/99
Version: 110.0.3?
System: mipseb/IRIX 6.5
Severity: major
Problem: 
  Compiler fails to build under IRIX 6.5.
Comments:
Fix: [jhr, 3/15/99]
  The fix turns out to be quite simple: add "-o32" to the definition
  of AS in src/runtime/objs/mk.mipseb-irix6 (line 10) and then run
  the build again.
  [DBM: is the fix implemented in current working versions?]
Test:
Owner: jhr?
Status: fixed in 110.0.6
----------------------------------------------------------------------
Number: 1480
Title: eXene unable to open display
Keywords: eXene
Submitter: Matthias Blume <blume@kurims.kyoto-u.ac.jp>
Date: 1/19/99
Version: 110.11 through 110.13
System: sparc
Severity: major
Problem: 
  A sample program of mine (uses CML and eXene) is unable to open the X
  display.  The exact same source code works under 110.9.1.

  Here is the error message that I am seeing (I tried with many
  different settings of the DISPLAY variable -- same error message every
  time):

  - Main.run();
  eXene: unable to open display ":0.0"
    Address family not supported by protocol family
  [000005] ***** shutdown *****
  val it = () : unit

Transcript:
Comments:
  Library sources that are missing in 110.13 were copied from
  110.9.1.  Should I be using newer ones from 110.10 or 110.11?
 [jhr, 1/25/99]
  My guess is that there is a use of arrays in the run-time system sockets
  library that didn't get changed to the new representations.  It should be easy to
  track down and fix.
Fix:
Test:
Owner: jhr
Status: fixed in 110.19
----------------------------------------------------------------------
Number: 1481
Title:       Error: Compiler bug: EntityEnv: lookEP.1 
Keywords:    functors, modules
Submitter:   Romeo Dumitrescu, romeo@ifi.unibas.ch
Date:        01/21/1999
Version:     110.0.3
System:      sparc-solaris2.7
Severity:    minor+
Problem:     
  Compiler error when trying to make a structure from a functor 
  that applies another, undefined functor.
Code:        
  signature SIG =
  sig
    val f : int -> int
  end

  functor Fun2() =
  struct
   structure F : SIG = Fun1()
  end

  structure S = Fun2()

Transcript:
  Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM;
  autoload enabled]
  - use "bug.sml";
  [opening bug.sml]
  bug.sml:8.22-8.28 Error: unbound functor: Fun1
  Error: Compiler bug: EntityEnv: lookEP.1
 
Comments:    
  This error message was already reported (bug 1317, version 109.33) in
  the context of missing signature declaration. Fixed in 109.35

Fix:  
Test: bug1481.1.sml
Owner: dbm, Zhong
Status: open
----------------------------------------------------------------------
Number: 1482
Title: core dump on x86, Alpha, mipseb
Keywords: core dump
Submitter: Andrew Bernard <andrewb+@cs.cmu.edu>
Date: 1/25/99
Version: 110.0.3
System: x86/Linux, alpha/unix
Severity: critical
Problem: 
  I can consistently make the runtime in the 110.0.3
  compiler seg fault with the attached piece of code.
  It appears to happen immediately, 100% of the time
  on x86/Linux and DEC Alpha.  There's a transcript
  in the comment at the end of the code that shows
  how it can be reproduced.

  I thought I should bring this to your attention right
  away, since the code is rather prosaic and isn't
  monkeying around with any unsafe/system structures.
  I tried essentially the same thing by coding it
  directly (i.e. w/o the modules and the functor
  instantiation) and everything works fine, so it
  seems like the module structure is essential.

Code:
  (* ----- nuke.sml ----- *)

  signature SUM =
  sig

    type type1
    type type2

    datatype t =
      Type1 of type1
    | Type2 of type2

  end


  signature SET =
  sig

    type element

    type t

    val empty: t

    val extend: t * element -> t

  end


  structure UnitSet =
  struct

    type element = unit

    type t = bool

    val empty = false

    fun extend(_, ()) = true

  end

  functor SumSet
    (
      structure Sum:  SUM
      structure Set1: SET
			where type element = Sum.type1
      structure Set2: SET
			where type element = Sum.type2
    ) :> SET
	   where type element = Sum.t
      =
  struct

    type element = Sum.t

    type t = Set1.t * Set2.t

    val empty = (Set1.empty, Set2.empty)

    fun extend((set1, set2), Sum.Type1 element1) =
	(Set1.extend(set1, element1), set2)
      | extend((set1, set2), Sum.Type2 element2) =
	(set1, Set2.extend(set2, element2))

  end

  structure UnitUnit =
  struct

    type type1 = unit
    type type2 = unit

    datatype t =
      Type1 of type1
    | Type2 of type2

  end

  structure UnitUnitSet =
  SumSet
    (
      structure Sum  = UnitUnit
      structure Set1 = UnitSet
      structure Set2 = UnitSet
    )

Transcript:
  Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
  - use "nuke.sml";
  [opening nuke.sml]
  GC #0.0.0.0.1.9:   (0 ms)
  signature SUM =
    sig
      type type1
      type type2
      datatype t = Type1 of type1 | Type2 of type2
    end
  signature SET =
    sig
      type element
      type t
      val empty : t
      val extend : t * element -> t
    end
  structure UnitSet :
    sig
      type element = unit
      type t = bool
      val empty : bool
      val extend : 'a * unit -> bool
    end
  functor SumSet : <sig>
  structure UnitUnit :
    sig
      datatype t = Type1 of type1 | Type2 of type2
      type type1 = unit
      type type2 = unit
    end
  structure UnitUnitSet : SET?
  val it = () : unit
  - UnitUnitSet.extend(UnitUnitSet.empty, UnitUnit.Type1());
  /usr/local/lib/sml/110b/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x40d1f34e
Comments:
 [Lal, 1/25/99]
  This does not appear on the alpha using our latest working version,
  110.12.
 [Lal, 2/5/99]
  It also appears on the mips (110.0.3) as well, and would therefore appear to
  be machine independent.
 [dbm, 2/21/01]
  George Russell provided alternative code for the hyperbolic functions based
  on Netlib C implementation (GNU GPL'd).  See Dev/bugs/1482.
Fix:
 May have been fixed since 110.0.3.
 In 110.33, works under x86-linux, alpha-dunix, sparc-solaris8. [dbm, 6/11/01]
Test: bug1482.1.sml
Owner: Zhong, Lal?
Status: fixed in 110.33
----------------------------------------------------------------------
Number: 1483
Title: confusing type error messages (literals, IntInf)
Keywords: type error messages
Submitter: Elsa Gunter
Date: 1/28/99
Version: 110.x
System: -
Severity: major 
Problem: 
  In error messages, different types are printed with the same name,
  so the type mismatch is not apparent.
Code:
Transcript:
  Having open IntInf, and not having coerced the numerals into IntInf.int.

  ../State/prelims.sml:87.16-89.34 Error: operator and operand don't agree [literal]
    operator domain: int * int
    operand:         int * int
    in expression:
      bits_rem - 1
  ../State/prelims.sml:88.25-88.40 Error: operator and operand don't agree [literal]
    operator domain: int * int
    operand:         int * int
    in expression:
      num_rem mod 2
  GC #0.0.0.1.5.84:   (20 ms)
  ../State/prelims.sml:87.16-89.34 Error: operator and operand don't agree [literal]
    operator domain: int * int
    operand:         int * int
    in expression:
      num_rem div 2

Comments:
 [dbm, 2/5/99]
  The problem arrises from the fact that the type of the literal integers
  (e.g. "1", "2" in this case) is a special type variable representing the
  as yet unresolved type of the literal.  Since this type can only resolve
  to Int31.int or Int32.int, it cannot match IntInf.int.  The literal
  type variable prints as "int", as does IntInf.int, since IntInf has been
  opened.
Fix:
  Make the type distinctions evident by some form of annotation.  E.g.
  'int[Lit] for the integer literal type variable.
Test: bug1483.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1484
Title: reorder optimization disabled by FLINT
Keywords: FLINT, reorder
Submitter: Mads Tofte <tofte@diku.dk>
Date: 2/15/98
Version: 110.0.3 and later
System: -
Severity: major 
Problem: 
  The optimization that reordered elements of a literal list (& vector?)
  to avoid building up a large number of temporaries during the list construction
  is now often disabled because type abstractions/applications in FLINT
  keep polymorphic literals (e.g. nil?) from being treated as pure, effect-free
  expressions whose evaluation can be reordered.

  This was noticed in the lexical analyzer for Cobol in Anno Domini.
Comments:
Fix:
Test:
Owner: Zhong (FLINT)
Status: open
----------------------------------------------------------------------
Number: 1485
Title: quadratic(?) blowup compiling long sequence of val bindings
Keywords: translate, FLINT
Submitter: Konrad Slind
Date: 1/8/99
Version: 110.0.3, 110.9.1
System: -
Severity: major
Problem: 
  The compilation of a structure whose body consists of a sequence of
  simple val declarations appears to take time quadratic in the length
  of the declaration sequence.

  This was discovered by Konrad Slind when compiling machine generated
  "theory" files that contained

    (1) a long sequence of fairly simple val declarations
    (2) creation of a big vector containing the values from (1)
    (3) a large case statement.

  This bug report only addresses the compile time behavior of (1), but
  (2) seems to be nonlinear too.

  Konrad's files compiled very slowly under SML/NJ, about an order of
  magnitude slower than under Moscow ML.  The slowdown was serious enough
  to drastically increase the time for building the Konrad's system
  relative to Moscow ML.

Code:
  structure A = struct
  fun f _ = ()
  val A1 = f 0;
  val A2 = f 0;
  .
  .
  .
  val A499 = f 0;
  val A500 = f 0;
  end

Measurements:

  The following measurements compare several SML/NJ versions on
  a 501 declaration test case.
  vex: Ultrasparc 2, 200MHz; Solaris 2.5.1
  slow1-500.sml  (500 declarations, two structures)

  SML/NJ 0.93
  -----------
  507 lines
  closure    20.661024s
  execution  22.457779s
  GC time    3.698343s
  total(usr) 26.230111s
  total(sys) 0.668325s
  code bytes: 66476

  SML/NJ 110.0.3
  --------------
  Code Size                               56888
  Source Lines                            502
  Compiler 080 closure                    27.47u  0.22s  0.78g  
  Compiler 100 spill                      5.33u  0.21s  0.62g  
  TOTAL                                   34.96u  0.59s  1.74g  

  SML/NJ 110.9.1
  --------------
  Code Size                               52376
  Source Lines                            502
  Compiler 080 closure                    28.43u  0.09s  0.81g  
  Compiler 120 cpsgen                     15.75u  0.89s  4.81g  
  TOTAL                                   45.47u  1.13s  5.81g  

  SML/NJ 110.10
  -------------
  Code Size                               52376
  Source Lines                            502
  Compiler 080 closure                    27.38u  0.23s  1.23g  
  Compiler 120 cpsgen                     16.58u  1.07s  4.75g  
  TOTAL                                   45.39u  1.43s  6.23g  


  The following measurements compare compilation times for structures
  of various sizes: 100, 200, 300, 400, 500, 1000, using SML/NJ 110.9.1.
  vex: Ultrasparc 2, 200MHz; Solaris 2.5.1

  100 decls
  ---------
  Code Size                               7376
  Source Lines                            102
  Compiler 080 closure                    0.33u  0.02s  0.01g  
  Compiler 120 cpsgen                     0.59u  0.06s  0.08g  
  TOTAL                                   1.12u  0.09s  0.10g  

  200 decls
  ---------
  Code Size                               14544
  Source Lines                            202
  Compiler 080 closure                    1.87u  0.01s  0.04g  
  Compiler 120 cpsgen                     2.27u  0.22s  0.55g  
  TOTAL                                   4.61u  0.26s  0.65g  

  300 decls
  ---------
  Code Size                               23344
  Source Lines                            302
  Compiler 080 closure                    6.70u  0.14s  0.46g  
  Compiler 120 cpsgen                     5.62u  0.45s  1.79g  
  TOTAL                                   12.98u  0.69s  2.31g  

  400 decls
  ---------
  Code Size                               32144
  Source Lines                            402
  Compiler 080 closure                    14.37u  0.21s  0.95g  
  Compiler 120 cpsgen                     10.98u  0.80s  3.99g  
  TOTAL                                   26.28u  1.09s  5.07g  

  500 decls
  ---------
  Code Size                               40944
  Source Lines                            502
  Compiler 080 closure                    30.66u  0.26s  1.12g  
  Compiler 120 cpsgen                     15.84u  1.11s  5.25g  
  TOTAL                                   47.70u  1.48s  6.55g  

  1000 decls
  ----------
  Error: Compiler bug: SparcCG.incOffset - spill area too small

Comments:
  If the right-hand-sides of the val declarations are simplified to
  a constant (say "val ANNN = 0;", then compilation seems to be linear
  in the size of the structure.  Looking at the CPS code generated for
  smaller examples, it is clear that terms quadratic in the size of
  the structure are being generated.

  The following code defines functions that can be used to generate
  test files of arbitrary sizes.

  (* mk_test_slow2 is like mk_test_slow, except that the function f
   * is defined in the main structure A *)
  fun mk_test_slow2 {file, length} =
      let val ostrm = TextIO.openOut file
	  fun mk 0 = (TextIO.output(ostrm,
				    "val A"^Int.toString length^" = f 0;\nend\n");
		      TextIO.flushOut ostrm; TextIO.closeOut ostrm)
	    | mk n = (TextIO.output
		      (ostrm,"val A"^Int.toString (length - n)^" = f 0;\n");
		      mk (n - 1))
      in
	  (TextIO.output
	   (ostrm,
	    "structure A = struct\nfun f _ = ()\n");
	   mk (length-1))
      end;

Fix:
Test: (generated)
Owner: FLINT, Zhong
Status: open
----------------------------------------------------------------------
Number: 1486
Title: Math.pow gives questionable results
Keywords: reals math
Submitter: Geoff Berry   gcb@cs.duke.edu
Date: 02/11/99
Version: 110.0.3
System: x86 Linux 2.0.36
Subsystem: SML basis library
Severity: major
Problem:
  Math.pow returns results that aren't Real.== to the expected value.

  For example Real.== (Math.pow (3.0, 2.0), 9.0) = false.
Code:
  Real.== (Math.pow (3.0, 2.0), 9.0);
  Math.pow (3.0, 2.0) - 9.0;

Transcript:
Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
- Real.== (Math.pow (3.0, 2.0), 9.0);
val it = false : bool
- Math.pow (3.0, 2.0) - 9.0;
val it = ~1.7763568394e~15 : real

Comments:
Here is an (seemingly) equivalent C program:

  #include <math.h>
  #include <stdio.h>

  int
  main ()
  {
    float a = 3.0;
    float b = 2.0;
    float ans = 9.0;

    printf ("%s\n", (pow (a, b) == ans ? "yes" : "no"));
  }

and running it:

[gcb@dynamic bin]$ ~/test
yes


Fix:

Test: bug1486.1.sml
Owner: jhr, Andrew
Status: open
----------------------------------------------------------------------
Number: 1487
Title: parentheses not permitted in val rec binding
Keywords: syntax
Submitter: Rob Arthan   rda@lemma-one.com
Date: 02/17/99
Version: 110.0.3
System: Sparc Solaris 
Subsystem: SML compiler
Severity: minor
Problem:
  The syntax for declarations includes;

    dec ::= val tyvarseq valbind | ...

  with

    valbind ::= pat = exp | rec valbing

    pat ::= atpat | ... | pat : ty

    atpat ::= longvid | ... | ( pat ) 

  but the full syntax does not seem to be supported.
Code:
  val rec g : 'a -> 'a = fn x => g x;
  val rec (f : 'a -> 'a) = fn x => f x;

Transcript:
  Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
  - val rec g : 'a -> 'a = fn x => g x;
  val g = fn : 'a -> 'a
  - val rec (f : 'a -> 'a) = fn x => f x;
  stdIn:18.10-18.13 Error: syntax error: deleting  ID COLON
  stdIn:18.17-18.22 Error: syntax error: deleting  ARROW TYVAR
  stdIn:18.24-18.28 Error: syntax error: deleting  EQUALOP FN
  stdIn:18.29-18.35 Error: syntax error: deleting  ID DARROW ID

Comments:
  This is a minor problem, but an irritant if you're porting a lot
  of code with this sort of construct in it (in semantically useful
  cases). The fix is trivial, but it's a chore.
 [dbm, 2/17/99]
  The val declaration syntax is rather peculiar (wish we had fixed this
  in SML '97), and there are some "legal" constructs have no interest in
  supporting, like

    val rec rec rec <valbind>
    val <valbind> and rec <valbind> and <valbind>

  but I think we should and can afford to support the syntax in your
  bug report.  I've added it to the list as bug 1487.

Fix:
  I don't have a fix but the ml.grm uses a production "rvb" for the
  construct that follows VAL REC and this doesn't seem to allow enough.

Test: bug1487.1.sml
Owner: dbm, Andrew
Status: open
----------------------------------------------------------------------
Number: 1488
Title: Array.fromList of empty list generates bogus "empty" array
Keywords: crash empty array Array.fromList
Submitter: Perry Cheng <pscheng@cs.cmu.edu>
Date: 02/17/99
Version: 110.13
System: Alpha Digital Unix 4.0
Subsystem: SML compiler
Severity: critical
Problem:
  The following bug was discovered while trying to use MLRISC.
  In particular, the file ra/liveness.sml tickles this bug.

  When the Array.fromList function is called on an empty list.
  The resulting array has length 1 and its first element
  appears to a bit pattern of zero.  So

  Array.fromList([] : int list)  computes to [|0|]

  At a type, (e.g. int * int),  where a bit pattern of zero is not
  valid value, this will lead to a segmentation fault
  as the transcript shows.  Note also that the interactive loop
  somehow knows not to try to print this ill-formed array.

  I believe the problem has to do with changes in array representation.
  Also, I noticed that Array.array0 no longer exists.  Perhaps this
  is related?

  This problem can also be exhibited on a SPARC.

Code:
  See transcript.

Transcript:
  Standard ML of New Jersey v110.13 [FLINT v1.5], January 17, 1999 [CM; autoload enabled]
  - val ls : (int * int) list = [];
  val ls = [] : (int * int) list
  - val arr = Array.fromList ls;
  - Array.length arr;
  val it = 1 : int
  - Array.sub(arr,0);
  Segmentation fault

Comments:
 [jhr, 2/18/99]
  I think that this bug can be fixed by changing line 808 of
  compiler/CodeGen/main/mlriscGen.sml from

			(tag(false, mlZero), CPS.OFFp 0)

  to

			(mlZero, CPS.OFFp 0)

  This will cause the correct length to be stored for arrays of length 0.

Fix:

Test: bug1488.1.sml
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1489
Title: bad type of equality function defined for abstype
Keywords: types, type checking, abstype, equality type
Submitter: Rob Arthan <rda@lemma-one.com>
Date: 2/18/99
Version: 110.0.3 through 110.13
System: -
Severity: major 
Problem: 
  An equality function defined on an abstype does not have the right type.
Code:
  abstype t = Mkt of int
  with val mk = Mkt
       and eq : t * t -> bool = op =
  end;
  val x = mk 3 and y = mk 4;
  eq (x,y);
Transcript:
  - abstype t = Mkt of int
  = with val mk = Mkt
  =      and eq : t * t -> bool = op =
  = end;
  type t
  val mk = fn : int -> t
  val eq = fn : t * t -> bool
  - val x = mk 3 and y = mk 4;
  val x = - : t
  val y = - : t
  - eq (x,y);
  stdIn:23.1-23.9 Error: operator and operand don't agree [equality type required]
    operator domain: ''Z * ''Z
    operand:         t * t
    in expression:
      eq (x,y)

Comments:
  In any case, as with value polymorphism, I find that making the code "less
  functional" solves the problem. If I introduce a semantically irrelevant
  eta-redex, it works as expected:

    val eq : t*t -> bool = fn (x, y) => x = y;

Fix:
Test: bug1489.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1490
Title: double error message for bad string constant
Keywords: error messages, strings
Submitter: Dave MacQueen
Date: 4/14/99
Version: 110.15
System: -
Severity: minor 
Problem: 
  Duplicate error messages are produced in response to an ill-formed
  string expression.
Transcript:
  - "\x";
  stdIn:35.1-35.3 Error: unclosed string
  stdIn:35.4-35.6 Error: unclosed string
Comments:
Fix:
Test: bug1490.1.sml
Owner: jhr?
Status: open
----------------------------------------------------------------------
Number: 1491
Title: Polymorphic Computation Too Slow
Keywords: polymorphism
Submitter: Eijiro Sumii   sumii@yl.is.s.u-tokyo.ac.jp
Date: 03/05/99
Version: 110.0.3
System: Sparc Solaris 2.5.1
Subsystem: SML compiler
Severity: major
Problem:
  Whenever I try large polymorphic computation (as below),
  SML/NJ takes too much time to give a result
  compared with other implementations or langauges.

Code:
  val S = fn x => fn y => fn z => (x z) (y z)
  val K = fn x => fn y => x

  let
      val six =
  ((S ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S))
  ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S))
  ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K))))
  ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K
  K)) (K S)))) ((S (K K)) (K K))))) ((S (K K)) (K K)))))) ((S ((S ((S (K
  S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K
  K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S))
  ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S))
  (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S))))
  ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K))))))
  ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S (K K)) (K K)))))
  ((S (K K)) (K K))))))) ((S K) K)))
  in
      six (fn n => 1 + n) 0
  end

Transcript:
Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
- val S = fn x => fn y => fn z => (x z) (y z);
val S = fn : ('a -> 'b -> 'c) -> ('a -> 'b) -> 'a -> 'c
- val K = fn x => fn y => x;
val K = fn : 'a -> 'b -> 'a
- val six : (int -> int) -> int -> int =
((S ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S))
((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S))
((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K))))
((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K
K)) (K S)))) ((S (K K)) (K K))))) ((S (K K)) (K K)))))) ((S ((S ((S (K
S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K
K)))) ((S ((S (K S)) (K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S))
((S (K K)) (K S)))) ((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S))
(K K))) (K K)))))) ((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S))))
((S ((S (K S)) ((S (K K)) (K K)))) ((S ((S (K S)) (K K))) (K K))))))
((S ((S (K S)) ((S ((S (K S)) ((S (K K)) (K S)))) ((S (K K)) (K K)))))
((S (K K)) (K K))))))) ((S K) K)));
= = = = = = = GC #0.0.0.0.1.5:   (10 ms)
= = = = = GC #0.0.0.0.2.32:   (30 ms)
GC #0.0.0.1.3.44:   (40 ms)
GC #0.0.0.1.4.60:   (20 ms)
GC #0.0.1.2.5.65:   (70 ms)
GC #0.0.1.2.6.69:   (20 ms)
GC #0.0.1.2.7.92:   (30 ms)
GC #0.0.1.2.8.116:   (0 ms)
GC #0.0.1.2.9.223:   (70 ms)
GC #0.1.2.3.10.233:   (110 ms)
GC #0.1.2.3.11.234:   (30 ms)
GC #0.1.2.3.12.235:   (20 ms)
GC #0.1.2.3.13.254:   (20 ms)
GC #0.1.2.3.14.269:   (40 ms)
GC #0.1.2.3.15.303:   (60 ms)
GC #0.1.2.4.16.307:   (80 ms)
GC #0.1.2.4.17.343:   (20 ms)
GC #0.1.2.4.18.348:   (0 ms)
val six = fn : (int -> int) -> int -> int
- six (fn n => 1 + n) 0;
GC #0.1.3.5.19.349:   (0 ms)
val it = 6 : int
- 
Comments:

Fix:

Test: tests/bug1491.1.sml
Owner: Zhong?
Status: open
----------------------------------------------------------------------
Number: 1492
Title: Compile-time performance problem with long list value
Keywords: performance, compile time
Submitter: Rob Arthan   rda@lemma-one.com
Date: 03/11/99
Version: 110.0.3
System: x86 Linux 2.0.18
Subsystem: SML compiler
Severity: major
Problem:
  I have some code which is partly generated by a home-grown parser
  generator. The generated code needs to generate a table represented
  as an array (actually a vector would do, but it uses arrays
  for historical reason).

  To get around a problem with a different compiler, the array
  is generate like this:

	  val x1 = [ ... ];
	  val x2 = [ ....];
	  ....
	  val xN = [ ... ];
	  val xs = Array.fromList(x1 @ x2 @ ... @ xn);

  this is then wrapped inside a structure whose signature hides x1, x2 etc.

  This seems to cause a major compiler performance problem.

  With a little tuning, it can be got to compile in a few minutes on an
  Ultra SPARC with lots of memory, but on a Pentium 100 running Linux
  it takes forever - I put it out of its misery after 30 hours.

Code:
  tests.perf/bug1492.1.sml
  tests.perf/bug1492.2.sml

Transcript:
  The full example issue GC message after GC message and then eventually
  goes quiet (while still consuming 100% of the CPU time).

Comments:
  I accept that the generated code is not particularly pretty and
  without much difficulty I can reprogram the output stage of the
  parser generator, but what will work? divide and conquer (i.e.,
  a tree structure of sub-expressions rather than a list)? doing
  it by assignments? or what?

 [Matthias]
  I just confirmed Rob Arthan's bug report about unacceptable
  compile-time performance.  In my case, I was running 110.9.1 on an
  UltraSparc with 256M of installed RAM.  I put the machine out of its
  misery after about 14 minutes of CPU time (wall clock time was much
  more) because it tried to allocate around 700MB of heap.  Since this
  obviously failed, the GC tried less memory and the machine started a
  swapping frenzy...

  Here are some observations:

  1. The bad phase is cpsgen.
       This became immediately obvious after setting
       Compiler.Stats.say{Begin,End} to true.
  2. Initially, the process ran for about 12 minutes happily within
     about 75M.  During this phase, the GC ran frequently, collecting up
     generation 3 (generation 1 being the "youngest").
     The GC message read
	  GC #5.29.33.xxxx.xxxx.xxxxx:   (xx ms)
     for about a gazillion of times.
  3. Then, suddenly, something changed.  Memory consumption jumped, now
     the GC quickly got to the point where it had to do full
     collections.  Here is a partial transcript:

  .
  .
  .
  GC #5.29.33.1163.1664.34008:   (20 ms)		<- see point 2
  GC #5.29.33.1164.1665.34017:   (20 ms)		<- see point 2
  GC #5.29.33.1165.1666.34076:   (390 ms)		<- here things seem to change
  GC #6.30.34.1166.1667.34085:   (1140 ms)	<- here things have changed
  GC #6.30.35.1167.1668.34105:   (480 ms)
  GC #6.31.36.1168.1669.34125:   (680 ms)
  GC #6.32.37.1169.1670.34145:   (730 ms)
  GC #6.33.38.1170.1671.34165:   (490 ms)
  GC #6.34.39.1171.1672.34185:   (570 ms)
  GC #6.35.40.1172.1673.34205:   (570 ms)
  GC #7.36.41.1173.1674.34225:   (2110 ms)
  GC #7.37.42.1174.1675.34235:   (460 ms)
  GC #7.38.43.1175.1676.34238:   (600 ms)
  GC #7.39.44.1176.1677.34246:   (650 ms)
  GC #7.40.45.1177.1678.34249:   (540 ms)
  GC #7.41.46.1178.1679.34256:   (530 ms)
  GC #8.42.47.1179.1680.34259:   (2730 ms)
  GC #8.43.48.1180.1681.34267:   (500 ms)
  GC #8.44.49.1181.1682.34268:   (350 ms)
  GC #8.45.50.1182.1683.34286:   (390 ms)
  GC #8.46.51.1183.1684.34306:   (410 ms)
  GC #9.47.52.1184.1685.34326:   (3190 ms)
  GC #9.48.53.1185.1686.34346:   (460 ms)
  GC #9.49.54.1186.1687.34366:   (560 ms)
  GC #9.50.55.1187.1688.34386:   (550 ms)
  GC #9.51.56.1188.1689.34406:   (590 ms)
  GC #9.52.57.1189.1690.34426:   (560 ms)
  GC #9.53.58.1190.1691.34446:   (600 ms)
  GC #9.54.59.1191.1692.34466:   (540 ms)
  GC #9.55.60.1192.1693.34485:   (600 ms)
  GC #9.56.61.1193.1694.34489:   (810 ms)
  GC #9.57.62.1194.1695.34497:   (770 ms)
  GC #9.58.63.1195.1696.34500:   (790 ms)
  GC #9.59.64.1196.1697.34507:   (820 ms)
  GC #10.60.65.1197.1698.34510:   (5060 ms)	<- this GC took about
				  3 min. wall clock time because of paging
  GC #10.61.66.1198.1699.34517:   (480 ms)
  GC #10.62.67.1199.1700.34520:   (440 ms)
  GC #10.63.68.1200.1701.34527:   (490 ms)
  GC #10.64.69.1201.1702.34530:   (390 ms)
  GC #10.65.70.1202.1703.34537:   (440 ms)
  /hana/blume/bin/sml: Error -- unable to map 242745344 bytes, errno = 11
  /hana/blume/bin/sml: Error -- unable to allocate to-space for generation 5; trying smaller size
  GC #11.66.71.1203.1704.34540:   (5780 ms)	<- ditto
  /hana/blume/bin/sml: Error -- unable to map 735117312 bytes, errno = 11
  /hana/blume/bin/sml: Error -- unable to allocate to-space for generation 5; trying smaller size
  GC #12.67.72.1204.1705.34549:   (5720 ms)	<- ditto

  At this point I gave up and pressed the interrupt key...

  My guess is that the above code creates an incredible register
  pressure which causes the register allocator to lose its bearings...
  Any other ideas?

 [Matthias, 3/12/99]
  Here is one more data point on the compiler time bug...

  (It should also provide Rob with a reasonable workaround.)

  I modified Rob's code as follows:

  1. I reversed the order of declaration for the slrn'gNNN variables.
  2. Each such variable (except the first one) is now immediately
     concatenated with the previous one.
  3. The final call to Array.fromList is performed on the contents of
     slrn'g0.

  This effectively interleaves the calls to List.@ with the creation of
  those variables, leaving only a small number of variables live at any
  time.  As a result, there is *much* less register pressure, and the
  program compiles fine within a few seconds.  (It's still slow, mind
  you, but the improvement is by several orders of magnitude.)
  I bet that it will be possible to modify the program that generates
  this code to do what I did manually.
  [see test/bug1492.2.sml for code]

 [Lal, 3/12,99]
  I tried this with the latest version (110.13), running on a fairly old 
  ultrasparc and it completed fine (not super fast though). 

  GC #11.117.127.152.254.8335:   (100 ms)
  GC #11.118.128.153.255.8388:   (90 ms)
  GC #11.119.129.154.256.8437:   (90 ms)
  structure S : sig val slrp'gotos : (string * int) list array end
  val it = () : unit
  val it = {gc="29.040",sys="5.090",tot="135.080",usr="100.950"}
    : {gc:string, sys:string, tot:string, usr:string}

  At the very least, 110.13 does a better job in dealing with string
  literals. I confirmed the same behaviour with 110.9.1 on this
  machine. 

 [Matthias, 3/12/99]
  Ok, I tried 110.14 and, indeed, it compiles fine (on an Ultra).
  Still, the time it takes to do that is a bit frustrating, and memory
  consumption (during compile) hovers at about 100MB, with a peak at
  150MB.  It's certainly not good.

  After re-arranging the code as I described earlier, the 110.14
  compiler needs only one major collection as opposed to 12, and memory
  consumption is at 40MB instead of 100MB.

Fix:
  
Test: tests.perf/bug1492.{1,2}.sml
Owner: Zhong?
Status: open
----------------------------------------------------------------------
Number: 1493
Title: NT Installer messes up PATH in the registrry
Keywords: "installer","PATH"
Submitter: Parzival   parz@videon.wave.ca
Date: 03/18/99
Version: 110
System: x86 Windows NT 4
Subsystem: Installation
Severity: minor
Problem:
  The Windows NT installer sucessfully installs the software, and it works,
  but the initial PATH environment variable setting in the registry
  is replaced with the EXPANDED and DOS specific version of the path
  string.

  The registry contains a string that Win NT expands into the command shell
  environment variable whenever it starts a command shell, i.e.

  registry:  Var name        Value
	     .Tex            c:\Tex
	     PATH            c:\bin;%.Tex%\MikTex\bin;c:\Program Files\TextPad

  resulting Path value in the command shell:

  PATH=c:\bin;c:\Tex\MikTex\bin;c:\Program Files\TextPad

  After installing SMLNJ, in directory "c:\sml", the registry looks
  like this:

  registry:  Var name        Value
	     PATH            e:\winnt\system32;e:\winnt;c:\bin;C:\Tex\MikTex\bin;c:\PROGRA~1\TextPad;C:\sml\bin

  So the installer has replaced the existing regigistry PATH value with
  a derived version: The user path setting includes the system (user
  independent) path setting, "\Program Files\" has been replaced by
  "\PROGRA~1\" (the 8.3 filename alias that NT supports for backwards
  comptibility with 16 bit programs that can't cope with long 
  or spaces embedded file names), and embedded 

  Since the path still "works", this problem may not be noticed until,
  say, in the above example, the registry setting for ".Tex" is changed,
  and the expected change to the path is not realized.

  I have a horrendous PATH:

  PATH=%MSDevDir%\bin\ide;%MSDevDir%\bin;%MSVCdir%\bin;%CYGWIN32%\bin;
  %.WinIcon%\bin;c:\pm3\bin;c:\Reactor\bin;c:\Program Files\textpad;
  %.Tex%\MikTex\bin;c:\noweb\bin;%IBMPLI%\bin;%.MOSES%\bin;
  c:\cocktail\bin;

  and the day after installing SML, it became:

  PATH=E:\WINNT\system32;E:\WINNT;.;C:\Perl\bin;C:\bin;C:\PROGRA~1\devstudio\sharedide\bin\ide;
  C:\PROGRA~1\devstudio\sharedide\bin;C:\PROGRA~1\devstudio\vc\bin;
  C:\CYGNUS/B19/H-i386-cygwin32\bin;C:\WinIcon\bin;c:\pm3\bin;
  c:\Reactor\bin;c:\PROGRA~1\textpad;c:\Tex\MikTex\bin;c:\noweb\bin;
  C:\IBMPLIW\bin;C:\MOSES\bin;c:\cocktail\bin;c:\sml\bin;


Code:

Transcript:

Comments:

Fix:
  Your installer is a 16 bit Windows program: Win NT emulates
  the operations it performs on the Windows 3.x "win.ini" file
  in the registry. You need to use a 32 bit installer program.

Test: 
Owner: Riccardo
Status: open
----------------------------------------------------------------------
Number: 1494
Title: rebound datatype prints incorrectly
Keywords: types
Submitter: John Reppy   jhr@research.bell-labs.com
Date: 04/19/99
Version: 110.0.3
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
  When rebinding a datatype, the top-level loop prints
  rhs type name instead of the lhs name.

Code:
  datatype foo = FOO;
  datatype bar = datatype foo;

Transcript:
  - datatype foo = FOO;
  datatype foo = FOO
  - datatype bar = datatype foo;
  datatype foo = FOO

Comments:

Fix:

Test: bug1494.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1495
Title:       110.16 does not build cleanly on Sparc
Keywords:    install, ml-yacc
Submitter:   Matthias Blume <blume@kurims.kyoto-u.ac.jp>
Date:        04/22/99
Version:     110.16
System:      sparc-solaris: SunOS hana 5.6 Generic_105181-11 sun4u sparc SUNW,Ultra-30
Severity:    critical
Problem:     During config/install.sh, compiling the sources of
             ml-yacc fails.
Code:        $ config/install.sh
Transcript:  ...
[opening yacc.grm.sml]
GC #0.1.2.3.17.650:   (10 ms)
GC #0.1.2.3.18.682:   (50 ms)
GC #0.1.3.4.19.709:   (30 ms)
GC #0.1.3.4.20.767:   (40 ms)
GC #0.1.3.4.21.797:   (20 ms)
GC #0.1.3.4.22.822:   (10 ms)
GC #0.1.3.4.23.837:   (10 ms)
GC #0.1.3.4.24.842:   (20 ms)
GC #0.1.3.5.25.850:   (20 ms)
GC #0.1.3.5.26.883:   (10 ms)
Error: Compiler bug: Wrapping: unexpected case in lpsw
- 
!!! build of ml-yacc.sparc-solaris failed
Comments:    Same code does build properly on linux (x86).
 [Matthias, 4/23/99]
  Well, things are *very* bizarre...

  The problem has nothing to do with the version of the CPU or the OS.
  Instead, it seems to depend on the NAME OF THE DIRECTORY (!!!) where I
  install SML/NJ.  Go figure...

  I typically use a directory name that is the part of the version
  number after the dot.  In the case of 110.16 it would be "16".
  Therefore, my installation attempt took place in

	  /hana/blume/ML/16

  This directory is on a local disk that is not accessible from other
  machines in the network.  Therefore, when I tried another machine I
  had to use a different directory -- and everything went through fine.
  Later I discovered that the machine "hana" (my Ultra-30) could also
  install the stuff fine in that other directory.  Finally, I started to
  experiment with that local disk.  Directories like

	  /hana/blume/ML/Bizarre

  etc. worked fine while

	  /hana/blume/ML/16
	  /hana/blume/ML/17
	  /hana/blume/ML/XY

  did not work.  So I started thinking that it has something to do with
  the length of the name.  However,

	  /hana/blume/ML/XYZ

  also did not work.  Finally,

	  /hana/blume/ML/WXYZ

  DID work.

  Another thing I discovered is that the fragile step seems to be the
  one where binfiles are turned into the SML heap image.  Runtime
  systems between "working" and "non working" versions are
  interchangeable (the one from the "non working" directory does work
  when transplanted into the "working" directory, the one from the
  "working" directory does not work in a "non working" directory).  The
  same is not true for the heap image -- a heap image transplanted from
  a "non working" directory into a "working" one still does not work.  A
  heap image that comes from a "working" directory continues to work in
  a "non working" directory.

  I have no clue whatsoever what might be going on here.  Any ideas?

 [jhr, 4/23/99]
  I would guess that there is a string padding problem (ML strings are
  supposed to have a terminating 0 byte to make them interchangable with
  the run-time).  I would suggest putting in some print statements in the
  runtime libraries (I assume that it is failing on open?) to see if
  the string values are bogus.

 [Matthias, 4/23/99]
  I also think that it has something to do with string padding.  Or more
  generally: alignment.
  However, it does not have anything to do with "open", I believe.  My
  message referred to my earlier bug report on this problem where the
  install script fails during the compilation of the ml-yacc sources:

  ...
  [opening yacc.grm.sml]
  GC #0.1.2.3.17.650:   (10 ms)
  GC #0.1.2.3.18.682:   (50 ms)
  GC #0.1.3.4.19.709:   (30 ms)
  GC #0.1.3.4.20.767:   (40 ms)
  GC #0.1.3.4.21.797:   (20 ms)
  GC #0.1.3.4.22.822:   (10 ms)
  GC #0.1.3.4.23.837:   (10 ms)
  GC #0.1.3.4.24.842:   (20 ms)
  GC #0.1.3.5.25.850:   (20 ms)
  GC #0.1.3.5.26.883:   (10 ms)
  Error: Compiler bug: Wrapping: unexpected case in lpsw

  Lal tested this and did not see the problem, so I started poking
  around, trying different machines, directories, etc. 

  My guess is that the new GC API implementation broke something because
  the same problem did not seem to exist in 110.15.  However, it could also be
  the new code generator and I got "lucky" before (or rather: "unlucky"
  now).

 [Lal, 4/30]
  I tried:
	  /home/george/L/16

  which has the same length as:
	  /hana/blume/ML/16

  and ml-yacc installed fine. Both the build script and the sources.cm
  file in the ml-yacc/src directory worked fine. 
 [Matthias, 4/1/99]
  Hmm.  Obviously there _is_ a bug (because it is happening here).
  If it really is an alignment problem of some sort, then anything could
  have an impact -- like the size of the shell environment and such.
  When I get a chance I go and try to find a repeatable instance of the
  problem so you can have a look at it.

  Other people are also seeing problems with 110.1[56], so I am fairly
  confident that it is not just some local problem of mine.  (BTW,
  I have also seen some programs core-dump under 110.16 on the x86.)

 [Matthias, 5/6/99]
  I just went through a series of tests regarding the 110.16 install
  problem that I reported for my Sparc.

  First, to rule out any impact from the shell environment I ran the
  script as

	  env -i PATH=/bin:/usr/bin:/usr/local/bin config/install.sh

  i.e., just barely enough for it to be able to run at all.
  However, the effect I was seeing is the same as before.

  So I went through a series of directory names:

      /hana/blume/M/16                       - succeeds
      /hana/blume/ML/16                      - fails
      /hana/blume/ML/16x                     - fails
      /hana/blume/ML/16xx                    - succeeds
      /hana/blume/ML/16xxx                   - succeeds
      ...                                      ...
      /hana/blume/ML/16xxxxxxxxxxxxxxxxxxx   - succeeds

  So it looks like I hit some really odd problem that only occurs with a
  very low probability.  I have not been able to figure out what's
  causing this.  Any ideas would be appreciated.
  (Assuming it is an alignment problem, it surely does not look like a
  word-boundary alignment problem.  Maybe it has to do with a page
  boundary?  What else could go wrong?)

  Below is a full transcript of the unsuccessful installation attempt.
  (You'll notice that the script uses /home/blume/ML/16 -- but that one
  is symbolically linked to /hana/blume/ML/16.  I confirmed that the
  problem also exists if I run the install script directly from
  /hana/blume/ML/16.)

  [dbm: transcript in /home/sml/Dev/bugs/bug1495.transcript]

 [Lal, 5/6/99]
  If this is a subtle GC bug then in the cases where it  fails, it may
  be possible to run to compeletion with a different allocation size. 
  So in ml-yacc/src execute CM.make() with something like:

	  ../../../bin/sml @SMLalloc=2M

  Allen reported a bug [bug 1496] that showed up when running the
  benchmarks. However, the weird thing is that it only shows up after
  the third repetition. Each repetition starts sml from scratch!

 [Matthias, 5/7/99]
  > If this is a subtle GC bug then in the cases where it  fails, it may
  > be possible to run to compeletion with a different allocation size. 
  > So in ml-yacc/src execute CM.make() with something like:
  > 
  > 	../../../bin/sml @SMLalloc=2M

  Yes, that does it.  I tried both cases: 1. building the ML heap image
  with @SMLalloc=2M and 2. (using the original 512k image) giving this
  option to the ml-yacc build script.  In either case installation goes
  through fine.  (I guess the two cases boil down to the same at some
  point, but I'm not sure.)
  In any case, it more and more looks like a GC bug.

 [jhr, 5/7/99]
  To be more precise, I would guess that it is a bug in the code generator's
  implementation of the new GC API.

 [Matthias, 5/20/99]
  Sorry for being imprecise.  That's exactly my guess also.

Fix: *
Test: *
Owner: Lal
Status: fixed in 110.17 [Lal]
----------------------------------------------------------------------
Number: 1496
Title:       Barnes-hut loops
Keywords:   
Submitter:   Allen Leung (leunga@cs.nyu.edu)
Date:        4/28/99
Version:     110.16
System:      HP-UX optlab5 B.10.20 A 9000/780 2003074095 two-user license
             SunOS griffin 5.6 Generic_105181-12 sun4u sparc SUNW,Ultra-1
Severity: Critical
Problem:     
Code:        
  Run the SML97 benchmarks from the ftp site. 
  Barnes-hut fails to complete on HP-UX and Solaris.
  The program starts to loop after the third trial. 

  The same benchmarks work ok on the x86 though. 

Transcript:  

  [recovering CM/hppa-unix/load.sml.bin... done]
  [recovering CM/hppa-unix/grav.sml.bin... done]
  [recovering CM/hppa-unix/data-io.sml.bin... done]
  [recovering CM/hppa-unix/getparam.sml.bin... done]
  [recovering CM/hppa-unix/rand-sig.sml.bin... done]
  [recovering CM/hppa-unix/rand.sml.bin... done]
  [recovering CM/hppa-unix/main.sml.bin... done]
  [recovering ../CM/hppa-unix/timeit.sml.bin... done]
  [recovering CM/hppa-unix/main2.sml.bin... done]
  [introducing new bindings into toplevel environment...]
  val it = true : bool
  GC #1.1.1.1.2.22:   (90 ms)
  GC #1.1.1.1.3.116:   (10 ms)
  GC #1.1.1.1.4.252:   (0 ms)
  GC #1.1.1.1.5.424:   (0 ms)
  GC #1.1.1.1.6.619:   (0 ms)
  GC #1.1.1.1.7.830:   (0 ms)
  GC #2.2.2.2.8.871:   (100 ms)
  GC #2.2.2.2.9.954:   (0 ms)
  GC #2.2.2.2.10.1061:   (0 ms)
  GC #2.2.2.2.11.1198:   (0 ms)
  GC #2.2.2.2.12.1367:   (0 ms)
  GC #2.2.2.2.13.1562:   (0 ms)
  GC #3.3.3.3.14.1720:   (140 ms)
  GC #3.3.3.3.15.1887:   (0 ms)
  GC #3.3.3.3.16.2084:   (0 ms)
  GC #3.3.3.3.17.2300:   (10 ms)
  GC #3.3.3.3.18.2548:   (0 ms)
  GC #4.4.4.4.19.2569:   (130 ms)
  GC #4.4.4.4.20.2622:   (0 ms)
  GC #4.4.4.4.21.2701:   (0 ms)
  GC #4.4.4.4.22.2810:   (0 ms)
  GC #4.4.4.4.23.2950:   (0 ms)
  GC #4.4.4.4.24.4168:   (0 ms)
  GC #4.4.4.4.25.5426:   (0 ms)
  GC #4.4.4.4.26.6791:   (0 ms)
  GC #4.4.4.4.27.8497:   (0 ms)
  GC #4.4.4.4.28.10387:   (0 ms)
  GC #4.4.4.4.29.12435:   (0 ms)
  GC #4.4.4.4.30.14824:   (0 ms)
  GC #4.4.4.4.31.17344:   (0 ms)
  GC #4.4.4.4.32.20074:   (0 ms)
  GC #4.4.4.4.33.23146:   (0 ms)
  GC #4.4.4.4.34.26296:   (0 ms)
  GC #4.4.4.4.35.29709:   (0 ms)
  GC #4.4.4.4.36.33463:   (0 ms)
  GC #4.4.4.4.37.37243:   (10 ms)
  GC #4.4.4.4.38.41339:   (0 ms)
  GC #4.4.4.4.39.45750:   (0 ms)
  GC #4.4.4.4.40.50187:   (0 ms)

  etc...

Comments:
  Also, there seems to be various phantom segfaults 
  in versions 110.15 and 110.16, usually during long compilations.
  These appeas on the sparc, hppa and the x86.  
  The x86 segfaults the most.  GC problems?

Fix: 
Test: 
Owner: Lal
Status: fixed in 110.17 [Lal]
----------------------------------------------------------------------
Number: 1497
Title:       bug in IntInf.scan StringCvt.HEX
Keywords:    
Submitter:   Stephen Weeks <sweeks@acm.org>
Date:        05/10/99
Version:     110.9.1
System:      x86-linux
Severity:    
Problem:     
  IntInf.scan StringCvt.HEX does not work correctly.  For example, the
  result of scanning the string "0x1" should be 1, but instead 0 is
  returned.  The scanner appears to be ignoring everything after the "0".

Code:        

  let val str = "0x1"
      fun reader offset =
	  if offset = size str
	  then NONE
	  else SOME (String.sub(str, offset), offset + 1)
   in IntInf.toString(#1(valOf(IntInf.scan StringCvt.HEX reader 0)))
  end

Transcript:  
Comments:    
Fix:         
Test: bug1497.1.sml
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1498
Title: Specialized real arrays not pretty-printed correctly
Keywords: 
Submitter: Allen Leung   leunga@cs.nyu.edu
Date: 05/05/99
Version: 110.0.6 - 110.27
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: cosmetic
Problem:
  Arrays of type "real Array.array" do not print like other arrays.
  Instead they print as "prim?".

Transcript:
  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
  - Array.array(3,1);
  val it = [|1,1,1|] : int array
  - Array.array(3, "a");
  val it = [|"a","a","a"|] : string array
  - Array.array(3, true);
  val it = [|true,true,true|] : bool array
  - Array.array(3,1.0);
  val it = prim? : real array

Comments:
 [dbm, 4/27/00]
  It looks like "real Array.array" has probably been converted internally
  to the RealArray.array (Real64Array.array) representation.  For top-level 
  printing, ppObj (MiscUtil/print/ppobj.sml) calls local function ppVal',
  whose code for arrays (Array.array) is

	              else if TU.eqTycon(tyc,BT.arrayTycon) then
			  (printWithSharing ppstrm
			    (obj,accu,
			     fn (obj,accu) =>
				ppArray(Obj.toArray obj, hd argtys, membersOp,
					depth,
					!Control.Print.printLength, accu))
			    handle Obj.Representation =>
				   add_string ppstrm  "prim?")

  If obj is actually a Real64Array.array, then Obj.toArray could fail,
  raising Obj.Representation and causing "prim?" to be printed.

  If Obj.toArray doesn't fail, then the definition of ppArray is assuming
  a polymorphic Array.array, and uses "Array.sub (objs,index)" to extract
  the real element, presumably getting a bogus value that will cause
  Obj.Representation to be raised when ppVal' tries to apply Obj.toReal
  to it: 
	              else if TU.eqTycon(tyc,BT.realTycon) then
			  add_string ppstrm (Real.toString(Obj.toReal obj))

  This would presumably raise Obj.Representation.

 [dbm, 4/27/99]

  It seems odd that _at top level_ there is a discrepency between the
  known type of a value, real Array.array, and it's representation type,
  which appears to be RealArray.array.  I would have thought that this
  would cause other problems than printing, though operations like
  Array.sub seem to work ok:

  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 ...
  - val a = Array.array(3,1.0);
  val a = prim? : real array
  - Array.sub (a,1);
  val it = 1.0 : real

  How is this managed?  Does Array.sub do some kind of dynamic check of
  the representation tag?

 [Zhong, 4/28/00]
  Array.sub is applied to "real array" and the compiler
  automatically specializes it into RealArray.sub ---
  thus everything works out as expected. 

  If you have a large polymorphic function 

      fun huge (x : 'a array) = .........Array.sub(x, 1)........
      ----------------------------------------------------------

      val a = Array.array(3, 1.0)
      val x = huge (a)

  Then Array.sub can't be specialized, but we pass the type descriptor
  to "huge" so at runtime we check this type descriptor and use
  RealArray.sub when it is a real array.

Fix:
   smlnj/src/system/Basis/Implementation/Unsafe/object.sig
   smlnj/src/system/Basis/Implementation/Unsafe/object.sml
     added toRealArray function
   smlnj/src/compiler/MiscUtil/print/ppobj.sml
     added check for tag Obj.RealArray to array printing case in ppObj
Test: bug1498.1.sml
Owner: dbm, Zhong
Status: fixed in 110.0.7, 110.28 [dbm, 4/28/00]
----------------------------------------------------------------------
Number: 1499
Title: Uncaught exception during compilation of bad signature
Keywords: types signature
Submitter: Leif Kornstaedt   kornstae@ps.uni-sb.de
Date: 04/15/99
Version: Version 110.0.3, January 30, 1998 [CM; autoload enabled]
System: x86 Linux 2.0.36
Subsystem: SML compiler
Severity: minor
Problem:
  An exception escapes during compilation of the bad signature given below.

Code:
  signature Bug =
  sig
      type t
      type t
      datatype u = C of t
      and v = D
  end

Transcript:
  - use "Bug.sig";
  [opening Bug.sig]
  Bug.sig:3.2-7.5 Error: duplicate specifications for type constructor t in signature

  uncaught exception Unbound
    raised at: elaborate/elabmod.sml:1364.39-1364.49

Comments:

Fix:

Test: bug1499.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1500
Title: Runtime system on Linux with glibc2
Keywords: runtime, linux, glibc
Submitter: Matthias Blume   blume@kurims.kyoto-u.ac.jp
Date: 04/19/99
Version: 110.16
System: x86 Linux kernel 2.2.6, glibc 2.1.1
Subsystem: Installation
Severity: minor
Problem:
  The runtime system does no longer compile out-of-the-box on one of
  the brand-new Linux systems that use the new glibc (version 2.1 and
  higher).  The problem is with the file

    src/runtime/mach-dep/signal-sysdep.h

  which erroneously redefines a 'struct sigcontext'.  The problem
  can be circumvented by improving the logic of the #if guard that
  is already in place.

Code:

Transcript:

Comments:

Fix:
diff -c -r runtime.distrib/mach-dep/signal-sysdep.h runtime/mach-dep/signal-sysdep.h
*** runtime.distrib/mach-dep/signal-sysdep.h    Wed Feb 24 01:35:26 1999
--- runtime/mach-dep/signal-sysdep.h    Mon Apr 19 16:09:56 1999
***************
*** 348,354 ****
  
  #  if defined(OPSYS_LINUX)
      /** X86, LINUX **/
! #    ifndef _SIGCONTEXT_H
        /* older versions of Linux don't define this in <signal.h> */
        struct sigcontext {
            unsigned short gs, __gsh;
--- 348,354 ----
  
  #  if defined(OPSYS_LINUX)
      /** X86, LINUX **/
! #    if !defined(_SIGCONTEXT_H) && !defined(sigcontext_struct)
        /* older versions of Linux don't define this in <signal.h> */
        struct sigcontext {
            unsigned short gs, __gsh;

Test: 
Owner: jhr
Status: fixed in 110.17, 110.0.4? 
----------------------------------------------------------------------
Number: 1501
Title:       Memory leak
Keywords:    Garbage collection, run-time system
Submitter:   rolsson@cs.chalmers.se
Date:        02/25/1999
Version:     110.0.3
System:	     x86-linux-2.0.34
Severity:    critical
Problem:     
  The following small piece of code causes a steady growth in virtual 
  memory size. The rate of increase is about 120 Mbytes per hour on a 
  400 MHz Pentium II.
  I have tried it up to 240 Mbytes, which is unreasonable for a program
  that should require constant space with tail-recursion optimization
  The leak may be caused by the call to blastWrite.
  
Code:	     

  fun word8_to_char( X : Word8.word ) : char = Char.chr( Word8.toInt X )

  fun word8vector_to_string( Xs : Word8Vector.vector ) : string =
    CharVector.tabulate( Word8Vector.length Xs, fn I =>
      word8_to_char( Word8Vector.sub( Xs, I ) ) )

  fun fromto( Lower, Upper ) =
    if Lower > Upper then nil else Lower :: fromto( Lower+1, Upper )

  fun f() =
    let
      fun g() = fromto(1,500)
      val S = word8vector_to_string( Unsafe.blastWrite( g() ) )
    in
      f()
    end

Transcript:  f();

Comments:
  My conversion of a Word8Vector.vector to a string is probably naive.

 [jhr, 2/25/99]
  Thanks for the report.  I don't see why blastWrite would cause a space
  leak in this case, but I'll look into it.  There is an open bug having to
  do with repeated array allocation, which this may be an instance of.
  It is also possible, but unlikely that the bug is a compiler bug.

  BTW your word8vector_to_string function can be replaced by the function
  Bytes.bytesToString, which is constant-time in SML/NJ.

Fix:	    Avoid blastWrite?
Test: *
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1502
Title: compiler failes to build with small allocation space
Keywords: gc, allocation space, compiler build
Submitter: Lal George
Date: 5/13/99
Version: 110.11 and later
System: -
Severity: critical
Problem: 
  All versions of the compiler (earlier than version 110.11) could build
  with an allocation of 64K. Thus, it appears that there may be a hidden
  bug in the new array/literal stuff.
Code:
Transcript:
Comments:
Fix:
Test:
Owner: jhr, Lal
Status: fixed in 110.17 [Lal]
----------------------------------------------------------------------
Number: 1503
Title: redefinition of `struct sigcontext' under red hat 6.0
Keywords: 
Submitter: Mattox Beckman   beckman@cs.uiuc.edu
Date: 05/13/99
Version: 110.6, 110.16
System: x86 Linux Red Hat 6.0
Subsystem: Installation
Severity: minor
Problem:
Installation fails.  The error message reported:

gcc -ansi -c -O2 -DHOST_X86 -DTARGET_X86 -DOPSYS_UNIX -DOPSYS_LINUX -D_POSIX_SOURCE -D_BSD_SOURCE -DVREGS -DCALLEESAVE=3 -I../objs -I../include ../mach-dep/unix-fault.c
In file included from ../mach-dep/unix-fault.c:9:
../mach-dep/signal-sysdep.h:353: redefinition of `struct sigcontext'
make[1]: *** [unix-fault.o] Error 1
make[1]: Leaving directory `/opt/sml-110.6/src/runtime/objs'
make: *** [all] Error 2
!!! run-time system build failed for some reason

I was able to make a workaround by patching signal-sysdep.h.  Here
is a patch; I wasn't very careful to make sure this would not break
anything else, but it seems that this should be okay:

4% diff src/runtime/mach-dep/signal-sysdep.h signal-sysdep.h 
88a89
> #define _SIGCONTEXT_H
351a353
> #     define _SIGCONTEXT_H

Code:
config/install.sh
Transcript:
see above
Comments:

Same as bug 1500

Fix:
  see above
Test: 
Owner: jhr
Status: fixed in 110.17, 110.0.4? [jhr]
----------------------------------------------------------------------
Number: 1504
Title: problem compiling smlnj-c on linux (red hat 6.0)
Keywords: smlnj-c, C interface
Submitter: Archisman Rudra <archi@cs.nyu.edu>
Date: 5/16/99
Version: ?
System: x86/linux (egcs-2.91.66, red hat 6.0)
Severity: medium
Problem: 
  I found a small bug in compiling the C interface for sml.
  It could be architecture/ compiler specific. I am using egcs-2.91.66
  on a linux (red hat 6.0) running on x86.

  In the last step of the compilation, ld gave an undefined
  symbol for CALL_BIAS in c-entry.o:

Comments:
Fix:
  [root@pelican smlnj-ccalls]# diff c-entry.asm.old c-entry.asm 
  75c75
  <       subl    $CALL_BIAS,%eax         /* adjust pc to point at "->" */
  ---
  >       subl    $ CALL_BIAS,%eax                /* adjust pc to point at "->" */

Test:
Owner: Lorenz, Riccardo
Status: open
----------------------------------------------------------------------
Number: 1505
Title: opaque functor signature match
Keywords: modules, signatures, functors, opaque matching
Submitter: Matthias Blume <blume@kurims.kyoto-u.ac.jp>
Date: 5/19/99
Version: 110.16
System: -
Severity: major 
Problem: 
  Here is a tiny program with higher-order functors (actually, just a
  structure containing a functor).  Trying to compile it results in the
  error shown below.  Why?


Code: (strfun.sml)
  signature S =
  sig
    datatype t = C
    functor F (val v : t) : sig end
  end;

  structure S :> S = struct
    datatype t = C
    functor F (val v : t) = struct end
  end;

Transcript:
  - use "strfun.sml";
  [opening strfun.sml]
  strfun.sml:9.1-15.4 Error: value type in structure doesn't match signature spec
      name: v
    spec:   ?.S.t
    actual: ?.S.t
Comments:
  Note that if I make the signature match transparent  -- S : S instead
  of S :> S -- then it does compile fine.
Fix:
Test: bug1505.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1506
Title: Uncaught Overflow/Div exceptions not printed correctly at top level
Keywords: uncaught exceptions, printing
Submitter: Allen Leung   leunga@cs.nyu.edu
Date: 05/23/99
Version: 110.16
System: x86 Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
In 110.16, on both Solaris and Linux(x86), uncaught exceptions 
generated by overflow trapping instructions are not printed correctly.
(It should print <unknown file>)    

The problem seems to be unrelated to the recently discovered gc bug.

The same code works correctly on HPUX, BTW.

Transcript:
  ----------------- x86 --------------------------
  Standard ML of New Jersey v110.16 [FLINT v1.5], April 15, 1999
  val use = fn : string -> unit
  - 1 div 0;

  uncaught exception divide by zero
    raised at: <file ;|$
			w7<D$L<l$H?T$T¸>
  - fun f x = f(x+x);
  GC #0.0.0.0.1.10:   (20 ms)
  val f = fn : int -> 'a
  - f 10;
  stdIn:7.1-7.5 Warning: type vars not generalized because of
     value restriction are instantiated to dummy types (X1,X2,...)

  uncaught exception overflow
    raised at: <file ëÀë=<ͺ>
  ------------- Solaris -----------------                            
  Standard ML of New Jersey v110.16 [FLINT v1.5], April 15, 1999 [CM; autoload enabled]
  - 1 div 0;

  uncaught exception divide by zero
    raised at: <file >
  - fun f x = f(x+x);
  val f = fn : int -> 'a
  - f 10;
  stdIn:11.1-11.5 Warning: type vars not generalized because of
     value restriction are instantiated to dummy types (X1,X2,...)

  uncaught exception overflow
    raised at: <file >

Comments:
 [jhr, 5/23/99]
  This is a known bug, which I think was introduced when I switched the
  way that code objects are handled.  The way things are supposed to work is
  that there is a file-name string added to the end of the code objects,
  which is used to generate this message.  The problem is that in the new
  code-object allocation scheme, the string is not available at the time
  that the code-object is allocated (in MLRISC).  Lal and I have discussed
  adding a mechanism to the MLRISC API that would allow the clients to pass
  in extra initialization information to the MLRISC module, but it hasn't
  been implemented.  In the new run-time, I've moved these strings from the
  code object into run-time system objects, so it will be possible to
  change the API and set the string after the code object is allocated.

Fix:
Test: 
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1507
Title: compiler does not reach a fix point
Keywords: compiler fixpoint, literal lifting, cps optimization, FLINT
Submitter: Lal George   george@research.bell-labs.com
Date: 06/14/99
Version: 110.12 and greater
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: critical
Problem:
  Removing the line:

	val function5 = cycle(rounds, not(!CG.unroll), function4)

  from FLINT/cpsopt/cpsopt.sml causes the compiler to core dump 
  during a build (makeml). The core dump is obtained after a couple of 
  rounds of compiling the compiler in the process of reaching a fixpoint.

Code:

Transcript:

Comments:
  This bug occurs on the alpha and x86 and is probably target independent.
  The first time the bug is manifest is version 110.12, and does not
  occur in version 110.9.1. 

  The only changes between these versions are: 
    a) the new array representation.
    b) literal lifting.

  The new array representation is an unlikely cause since most of
  the changes are in MLRISC and done after cpsopt. It seems almost 
  certain that the bug is a subtle interaction between literal lifting 
  and cps optimization.

  The bug is difficult to pin down because it rears its ugly head after
  at least 3 or 4 rounds of compiling the compiler and building heap
  images. 

  Literal lifting is currently implemented in CPS. Since everything in CPS
  is being moved to FLINT, a possible solution to this problem would be to
  re-implement literal lifting in FLINT. This will have to be done sooner
  or later anyway, and perhaps this bug will go away in the process.

 [Zhong, 6/14/99]
  If literal lifting is really the problem, why can't we turn it off 
  and see if the compiler still reaches a fix point. The liftLiterals
  flag in Compiler.Control.CG should work as before I assume.

  Personally, I can't rule out the new array-rep code that quickly.
  It touches almost every aspect of the compiler and have subtle
  interaction with representation analysis, primop implementation, etc.

 [jhr, 6/14/99]
  > If literal lifting is really the problem, why can't we turn it off 
  > and see if the compiler still reaches a fix point. The liftLiterals
  > flag in Compiler.Control.CG should work as before I assume.

  The problem is that turning off literal lifting will break the new array
  representations.  I guess that we could try to retrofit the literal lifting
  code into 110.9.1 to test this.

  > 
  > Personally, I can't rule out the new array-rep code that quickly.
  > It touches almost every aspect of the compiler and have subtle
  > interaction with representation analysis, primop implementation, etc.

  Flint/CPS knows nothing about the new array representations. Arrays are
  just an abstraction at that point.  The new representation is only
  visible when primops are translated to MLRisc instructions.  I think that
  it is quite unlikely that there would be a bug in the new array representations
  that was sensitive to CPS transformations.

  On the other hand, since the literal lifting restructures the CPS terms, it
  seems quite likely that there could be an interaction between unrolling of
  CPS terms and literal lifting.

Fix:

Test: 
Owner: Lal and jhr
Status: fixed in 110.25
----------------------------------------------------------------------
Number: 1508
Title: problems with profiler
Keywords:    <optional - e.g. "modules", "types", "IO", "reals">
Submitter:   Allyn Dimock <dimock@deas.harvard.edu>
Date:        6/18/99
Version:     110.03
System:      SGI iris4d  IRIX64
Severity:    minor
Problem:     several difficulties in using Compile.Profile
Code:
  val profile = ref true
  fun whenProfiling f = if (!profile) then f() else ()
  ...
	  val _ = whenProfiling
	      (fn() => (Compiler.Profile.reset();
			Compiler.Profile.setTimingMode (true) ))
	  val (e1, sinks1) = termAnnot (e, sinks)
	  val _ = whenProfiling
	      (fn() => (print ("Profile of TypInfSources.termAnnot\n");
			Compiler.Profile.report (!PPUtil.defaultOutstreamP);
			Compiler.Profile.reset();
			Compiler.Profile.setTimingMode (false)
			))
	  val _ = whenProfiling
	      (fn() => (Compiler.Profile.reset();
			Compiler.Profile.setTimingMode (true) ))
	  val e2 = typeAnnot (e1, sinks1)
	  val _ = whenProfiling
	      (fn() => (print ("Profile of TypInfSources.termAnnot\n");
			Compiler.Profile.report (!PPUtil.defaultOutstreamP);
			Compiler.Profile.reset();
			Compiler.Profile.setTimingMode (false)
			))
	  and so on...

Transcript:
 (1) unhandled exception overflow  from somewhere in profiled
  library code  during the 4'th chunk of code being profiled. (sorry it takes
  several hours to get to the place where this profile is being used and I blew
  away my old log file.  The actual code being profiled takes 25 minutes to run
  with profiling turned off.  This doesn't seem long enough to overflow a 32 bit
  counter.  Are you using smaller integers as counters?

 (2)
  %time cumsec #call  name
  50.00    .01  2344  TypInfSinks.<tempStr>.termAnnot.termAnnot.typeFn1.typeFn1
  50.00    .02   253  MakeProp.<tempStr>.putTermProp
    .00    .02 15602  TypInfSinks.<tempStr>.whenDebugging.whenDebugging
    .00    .02  2473  TermUtil.<tempStr>.appSubterms.appSubterms

  Do you really only sample the clock at 10 millisec intervals?  Is ther ea way
  to get finer granularity?  (of course, if you allow me to go to 1 millisec
  intervals, then
  I am going to need 3 more bits in the counters than whatever was needed to fix
  problem (1)

 (3) the same input with 

		(fn() => (print ("Profile of TypInfSources.termAnnot\n");
			  Compiler.Profile.report (!PPUtil.defaultOutstreamP);
			  Compiler.Profile.setTimingMode (false)
			  Compiler.Profile.reset();
			  ))

  i.e. interchange order of setTimingMode and reset after report.  But leave the
  reset and setTimingMode, before the expression being profiled, unchanged.
  yields:

   50.00    .04     0  Minor GC
   37.50    .06     1  PPUtil.<tempStr>.flush.flush
   12.50    .07  2820  SplayTree.<tempStr>.splay.splay.adj.adj
   12.50    .07  1012 
  MakeProp.<tempStr>.getActivePropMapEntry.getActivePropMapEntry
   12.50    .08   759  IntBinaryMap.<tempStr>.find.find.mem.mem.anon
   12.50    .08   506  MakeProp.<tempStr>.getTermProp.anon
     .00     ...... many more

  PPUtil.<tempStr>.flush.flush is presumably time spent writing out the
  previous Compiler.Profile.report (or possibly the current).  So it looks
  like reset and toggling the timingMode didn't have the expected behavior.

Comments:

Fix:
Test: *
Owner: ?
Status: open
----------------------------------------------------------------------
Number: 1509
Title: Division overflow is not detected properly on the sparc
Keywords: 
Submitter: Allen Leung   leunga@cs.nyu.edu
Date: 06/22/99
Version: 110.17
System: Sparc Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
  Integer division overflow is not detected properly on the sparc.
  This bug has been around since the sparc started using MLRISC as the
  backend. The bug was my fault; I didn't realize division could overflow.

Code:
  val SOME x = Int32.minInt;
  x div ~1;
Transcript:
  leunga@griffin:~/SML/src/MLRISC++{183}> sml
  Standard ML of New Jersey v110.17 [FLINT v1.5], May 20, 1999 [CM; autoload enabled]
  - val SOME x = Int32.minInt;
  stdIn:14.1-14.26 Warning: binding not exhaustive
	    SOME x = ...
  val x = ~2147483648 : Int32.int
  - x div ~1;
  val it = 2147483647 : Int32.int

Comments:

Fix:
  The fix is in (the upcoming) 110.18
Test: 
Owner: Lal, Leung
Status: fixed in 110.18 (Leung)
----------------------------------------------------------------------
Number: 1510
Title:       Signature matching bug makes "casts" possible
Keywords:    compiler, signature matching
Submitter:   Leif Kornstaedt <kornstae@ps.uni-sb.de>
Date:        07/05/1999
Version:     Standard ML of New Jersey, Version 110.0.3, January 30, 1998
System:      x86-linux
Severity:    major
Problem:     Type-safety is compromised.
Code:

  functor Cast(type from type to) :>
  sig
    type ('a, 'b) t = 'a -> 'b
    val cast: (from, to) t
  end =
  struct
    type ('a, 'b) t = 'a -> 'a
    fun cast x = x
  end

  structure IntListToIntOption =
    Cast(type from = int list
	 type to = int option)

  val it = IntListToIntOption.cast [17]

Transcript:

Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
- use "castfunctor.sml";
[opening castfunctor.sml]
functor Cast : <sig>
structure IntListToIntOption :
  sig
    type ('a,'b) t = 'a -> 'b
    val cast : (from,to) t
  end
val it = SOME 17 : ?.to
val it = () : unit

Comments: 
Fix: 
  dummyargs function in TypesUtil (Semant/types/typesutil.sml) was
  producing a list of equal types, instead of distinct types.  Use
  Stamps.fresh to generate distinct stamps for each type.  
Test: bug1510.1.sml, bug1510.2.sml
Owner: dbm, Zhong
Status: fixed in 110.0.7, 110.28 [dbm, 4/28/00]
----------------------------------------------------------------------
Number: 1511
Title:       Compiler problem "tyvarType: CONty"
Keywords:    compiler
Submitter:   Leif Kornstaedt <kornstae@ps.uni-sb.de>
Date:        07/05/1999
Version:     Standard ML of New Jersey, Version 110.0.3, January 30, 1998
System:      x86-linux
Severity:    minor
Problem:     Compiler aborts compilation with an error message
Code:

  signature S =
  sig
    type ('a, 'b) t = 'a -> 'b
    val x: ('a, int) t
  end;

  structure M :> S =
  struct
    type ('a, 'b) t = 'a -> 'a
    fun x y = y
  end;

Transcript:

Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
- use "crash2.sml";
[opening crash2.sml]
Error: Compiler bug: TypesUtil: tyvarType: CONty

Comments:    none
Fix:         none known
Test: bug1511.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1512
Title:       Nested absolute indent boxes don't work in PP library
Keywords:    SML-NJ library -- PP
Submitter:   David Casperson <casper@unbc.ca>
Date:        07/05/1999
Version:     110.0.3
System:      not relevant
Severity:    ??
Problem:     Nested absolute indent boxes are indented relative to the
             indent which exists at the time the box is created rather
             than relative to the indent of next outermost box.
 
Code:        
(*--------------------------------------------------------------------------*)
(* show bugs in sml PP package *)

OS.FileSys.chDir "/csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/PP/" ;
List.map use
[
"src/pp-device-sig.sml",
"src/pp-stream-sig.sml",
"src/pp-token-sig.sml",
"src/pp-stream-fn.sml",
"devices/simple-textio-dev.sml"
] ;

structure StringToken : PP_TOKEN =
  struct
    type token = string
    type style = unit

    fun string(x:token) = x ;
    fun style(x:token) = ()
    fun size (x:token) = String.size x ;
  end;

local
    structure PPStream = PPStreamFn(structure
                                        Token = StringToken
                                    and Device = SimpleTextIODev) ;

    open PPStream ;
in
    datatype indent = datatype indent ;
    val strm1 = openStream (SimpleTextIODev.openDev
                            {dst=TextIO.stdOut, wid=80}) ;
    val openHOVBox  = openHOVBox strm1 ;
    val openVBox    = openVBox strm1 ;
    val closeBox    = (fn () => closeBox strm1) ;
    val flushStream = (fn () => flushStream strm1) ;
    val string      = string strm1 ;
    val cut         = (fn () => cut strm1) 
end ;

fun go2() =
    (
     openHOVBox (Abs (0)) ;
     string "Indented(" ;
     openHOVBox (Rel (0)) ;
     string "booogle" ;
     openVBox (Abs(0)) ;                (* This should be indented inside
                                           the box above, but it isn't*)
     cut () ;
     string "line1" ;
     cut () ;
     string "line2" ;
     closeBox () ;
     cut () ;
     string ")" ;
     closeBox () ;
     cut () ;
     closeBox () ;
     flushStream () 
     ) ;
go2() ;
(*--------------------------------------------------------------------------*)
Transcript:  
(*--------------------------------------------------------------------------*)
Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
- [opening /csd2/home/casper/Sml/Code/test-pp-bug2.sml]
val it = () : unit
[opening src/pp-device-sig.sml]
signature PP_DEVICE =
  sig
    type device
    type style
    val sameStyle : style * style -> bool
    val pushStyle : device * style -> unit
    val popStyle : device -> unit
    val defaultStyle : device -> style
    val depth : device -> int option
    val lineWidth : device -> int option
    val textWidth : device -> int option
    val space : device * int -> unit
    val newline : device -> unit
    val string : device * string -> unit
    val char : device * char -> unit
    val flush : device -> unit
  end
[opening src/pp-stream-sig.sml]
GC #0.0.0.0.1.11:   (10 ms)
signature PP_STREAM =
  sig
    type device
    type stream
    type token
    type style
    datatype indent = Abs of int | Rel of int
    val openStream : device -> stream
    val flushStream : stream -> unit
    val closeStream : stream -> unit
    val openHBox : stream -> unit
    val openVBox : stream -> indent -> unit
    val openHVBox : stream -> indent -> unit
    val openHOVBox : stream -> indent -> unit
    val openBox : stream -> indent -> unit
    val closeBox : stream -> unit
    val token : stream -> token -> unit
    val string : stream -> string -> unit
    val pushStyle : stream * style -> unit
    val popStyle : stream -> unit
    val break : stream -> {nsp:int, offset:int} -> unit
    val space : stream -> int -> unit
    val cut : stream -> unit
    val newline : stream -> unit
    val nbSpace : stream -> int -> unit
    val onNewline : stream -> unit -> unit
  end
[opening src/pp-token-sig.sml]
signature PP_TOKEN =
  sig
    type token
    type style
    val string : token -> string
    val style : token -> style
    val size : token -> int
  end
[opening src/pp-stream-fn.sml]
GC #0.0.0.1.2.37:   (20 ms)
[Autoloading...]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/atom-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/hash-string.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/atom.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fmt-fields.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/format-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/real-format.sml.bin...GC #0.0.0.1.3.43:   (10 ms)
 done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/format.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/list-format-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/list-format.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fifo-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fifo.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/queue-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/queue.sml.bin... done]
[Autoloading done.]
GC #0.0.0.1.4.56:   (10 ms)
src/pp-stream-fn.sml:294.4-294.78 Warning: binding not exhaustive
          PP
            {closed=_,curDepth=_,curIndent=_,dev=_,fmtStk=_,leftTot=leftTot,
             queue=_,rightTot=rightTot,scanStk=scanStk as ref (<pat> :: <pat>),
             spaceLeft=_,styleStk=_,width=_} = ...
GC #0.0.0.1.5.85:   (20 ms)
GC #0.0.0.1.6.98:   (10 ms)
GC #0.0.0.1.7.110:   (10 ms)
GC #0.0.0.1.8.122:   (10 ms)
GC #0.0.0.1.9.123:   (10 ms)
GC #0.0.0.1.10.141:   (0 ms)
GC #0.0.1.2.11.142:   (30 ms)
GC #0.0.1.2.12.168:   (10 ms)
functor PPStreamFn : <sig>
[opening devices/simple-textio-dev.sml]
structure SimpleTextIODev :
  sig
    datatype device = ...
    type style = unit
    val sameStyle : style * style -> bool
    val pushStyle : device * style -> unit
    val popStyle : device -> unit
    val defaultStyle : device -> style
    val depth : device -> int option
    val lineWidth : device -> int option
    val textWidth : device -> int option
    val space : device * int -> unit
    val newline : device -> unit
    val string : device * string -> unit
    val char : device * char -> unit
    val flush : device -> unit
    val openDev : {dst:TextIO.outstream, wid:int} -> device
  end
val it = [(),(),(),(),()] : unit list
structure StringToken : PP_TOKEN
GC #0.0.1.2.13.201:   (0 ms)
datatype indent = Abs of int | Rel of int
val strm1 =
  PP
    {closed=ref false,curDepth=ref 1,curIndent=ref 0,dev=DEV {dst=-,wid=80},
     fmtStk=ref [],leftTot=ref 1,queue=-,rightTot=ref 1,
     scanStk=ref [(#,#),(#,#)],spaceLeft=ref 80,styleStk=ref [],width=80}
  : ?.PPStream.stream
val openHOVBox = fn : indent -> unit
val openVBox = fn : indent -> unit
val closeBox = fn : unit -> unit
val flushStream = fn : unit -> unit
val string = fn : string -> unit
val cut = fn : unit -> unit
val go2 = fn : unit -> unit
Indented(booogle
line1
line2)val it = () : unit
val it = () : unit
- 
(*--------------------------------------------------------------------------*)
Comments:    I am not 100% sure what is intended in the original code.
             I am also not sure if I have sent this report to the right
             place.
             The following fix definitely seems to help.  The old code has
             problems because the curIndent may not be set until later.
Fix:         
***************
*** 207,215 ****
  		val PP{curIndent, spaceLeft, width, fmtStk, ...} = strm
  		val spaceLeft' = !spaceLeft
  		val insPt = width - spaceLeft'
! 		val offset = (case indent
! 		       of (Rel off) => spaceLeft' - off
! 			| (Abs off) => width - (!curIndent + off)
  		      (* end case *))
  (***** CAML version does the following: ****
  		val _ = if (insPt > maxIndent)
--- 209,218 ----
  		val PP{curIndent, spaceLeft, width, fmtStk, ...} = strm
  		val spaceLeft' = !spaceLeft
  		val insPt = width - spaceLeft'
! 		val offset = (case (indent,!fmtStk)
! 		       of ((Rel off),_) => spaceLeft' - off
! 			| ((Abs off),(_,wid)::_) => wid - off
!                       | ((Abs off), nil) => width - off
  		      (* end case *))
  (***** CAML version does the following: ****
  		val _ = if (insPt > maxIndent)
Test: *
Owner: jhr
Status: fixed in 110.0.4 and 110.19 (jhr, 7/5/99)
----------------------------------------------------------------------
Number: 1513
Title:       Nested boxes containing breaks mess up scan stack in PP
Keywords:    SML-NJ library -- PP
Submitter:   David Casperson <casper@unbc.ca>
Date:        05/07/1999
Version:     110.0.3
System:      not relevant
Severity:    ??
Problem:     breaks and end-boxes don't interact correctly 
Code:        
(*--------------------------------------------------------------------------*)
(* show bugs in sml PP package *)

OS.FileSys.chDir "/csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/PP/" ;
List.map use
[
"src/pp-device-sig.sml",
"src/pp-stream-sig.sml",
"src/pp-token-sig.sml",
"src/pp-stream-fn.sml",
"devices/simple-textio-dev.sml"
] ;

structure StringToken : PP_TOKEN =
  struct
    type token = string
    type style = unit

    fun string(x:token) = x ;
    fun style(x:token) = ()
    fun size (x:token) = String.size x ;
  end;

local
    structure PPStream = PPStreamFn(structure
                                        Token = StringToken
                                    and Device = SimpleTextIODev) ;

    open PPStream ;
in
    datatype indent = datatype indent ;
    val strm1 = openStream (SimpleTextIODev.openDev
                            {dst=TextIO.stdOut, wid=80}) ;
    val openHOVBox  = openHOVBox strm1 ;
    val openVBox    = openVBox strm1 ;
    val closeBox    = (fn () => closeBox strm1) ;
    val flushStream = (fn () => flushStream strm1) ;
    val string      = string strm1 ;
    val cut         = (fn () => cut strm1) 
end ;


fun go1 () =
    (
     openHOVBox (Abs(0)) ;
     string "bad " ;
     cut () ;                           (* This should not cause a break!! *)
     openHOVBox (Abs(0)) ;
     string "cut " ;
     cut() ;
     string "here." ;
     closeBox() ;
     cut() ;
     string "  Shouldn't have happened." ;
     closeBox() ;
     flushStream ()
     )
    ;

go1() ;
(*--------------------------------------------------------------------------*)
Transcript:  
(*--------------------------------------------------------------------------*)
Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
- [opening /csd2/home/casper/Sml/Code/test-pp-bug1.sml]
val it = () : unit
[opening src/pp-device-sig.sml]
signature PP_DEVICE =
  sig
    type device
    type style
    val sameStyle : style * style -> bool
    val pushStyle : device * style -> unit
    val popStyle : device -> unit
    val defaultStyle : device -> style
    val depth : device -> int option
    val lineWidth : device -> int option
    val textWidth : device -> int option
    val space : device * int -> unit
    val newline : device -> unit
    val string : device * string -> unit
    val char : device * char -> unit
    val flush : device -> unit
  end
[opening src/pp-stream-sig.sml]
GC #0.0.0.0.1.11:   (10 ms)
signature PP_STREAM =
  sig
    type device
    type stream
    type token
    type style
    datatype indent = Abs of int | Rel of int
    val openStream : device -> stream
    val flushStream : stream -> unit
    val closeStream : stream -> unit
    val openHBox : stream -> unit
    val openVBox : stream -> indent -> unit
    val openHVBox : stream -> indent -> unit
    val openHOVBox : stream -> indent -> unit
    val openBox : stream -> indent -> unit
    val closeBox : stream -> unit
    val token : stream -> token -> unit
    val string : stream -> string -> unit
    val pushStyle : stream * style -> unit
    val popStyle : stream -> unit
    val break : stream -> {nsp:int, offset:int} -> unit
    val space : stream -> int -> unit
    val cut : stream -> unit
    val newline : stream -> unit
    val nbSpace : stream -> int -> unit
    val onNewline : stream -> unit -> unit
  end
[opening src/pp-token-sig.sml]
signature PP_TOKEN =
  sig
    type token
    type style
    val string : token -> string
    val style : token -> style
    val size : token -> int
  end
[opening src/pp-stream-fn.sml]
GC #0.0.0.1.2.37:   (20 ms)
[Autoloading...]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/atom-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/hash-string.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/atom.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fmt-fields.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/format-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/real-format.sml.bin...GC #0.0.0.1.3.43:   (0 ms)
 done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/format.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/list-format-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/list-format.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fifo-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/fifo.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/queue-sig.sml.bin... done]
[recovering /csd2/home/casper/Sml/SMLNL-110/src/smlnj-lib/Util/CM/sparc-unix/queue.sml.bin... done]
[Autoloading done.]
GC #0.0.0.1.4.56:   (10 ms)
src/pp-stream-fn.sml:294.4-294.78 Warning: binding not exhaustive
          PP
            {closed=_,curDepth=_,curIndent=_,dev=_,fmtStk=_,leftTot=leftTot,
             queue=_,rightTot=rightTot,scanStk=scanStk as ref (<pat> :: <pat>),
             spaceLeft=_,styleStk=_,width=_} = ...
GC #0.0.0.1.5.85:   (20 ms)
GC #0.0.0.1.6.98:   (10 ms)
GC #0.0.0.1.7.110:   (10 ms)
GC #0.0.0.1.8.122:   (10 ms)
GC #0.0.0.1.9.123:   (10 ms)
GC #0.0.0.1.10.141:   (10 ms)
GC #0.0.1.2.11.142:   (30 ms)
GC #0.0.1.2.12.168:   (10 ms)
functor PPStreamFn : <sig>
[opening devices/simple-textio-dev.sml]
structure SimpleTextIODev :
  sig
    datatype device = ...
    type style = unit
    val sameStyle : style * style -> bool
    val pushStyle : device * style -> unit
    val popStyle : device -> unit
    val defaultStyle : device -> style
    val depth : device -> int option
    val lineWidth : device -> int option
    val textWidth : device -> int option
    val space : device * int -> unit
    val newline : device -> unit
    val string : device * string -> unit
    val char : device * char -> unit
    val flush : device -> unit
    val openDev : {dst:TextIO.outstream, wid:int} -> device
  end
val it = [(),(),(),(),()] : unit list
structure StringToken : PP_TOKEN
GC #0.0.1.2.13.201:   (0 ms)
datatype indent = Abs of int | Rel of int
val strm1 =
  PP
    {closed=ref false,curDepth=ref 1,curIndent=ref 0,dev=DEV {dst=-,wid=80},
     fmtStk=ref [],leftTot=ref 1,queue=-,rightTot=ref 1,
     scanStk=ref [(#,#),(#,#)],spaceLeft=ref 80,styleStk=ref [],width=80}
  : ?.PPStream.stream
val openHOVBox = fn : indent -> unit
val openVBox = fn : indent -> unit
val closeBox = fn : unit -> unit
val flushStream = fn : unit -> unit
val string = fn : string -> unit
val cut = fn : unit -> unit
val go1 = fn : unit -> unit
bad 
cut here.  Shouldn't have happened.val it = () : unit
val it = () : unit
- 
(*--------------------------------------------------------------------------*)
Comments:       This is clearly just a typo in the source.  As it is, any
                box containing a break messes up the scan stack.   
Fix:         
***************
*** 342,349 ****
  	    (* check that depth < maxDepth *)
  ****)
  	      enqueueTok (strm, {sz = ref 0, tok = END, len = 0});
! 	      setSize (strm, false);
! 	      setSize (strm, true);
  	      curDepth := depth-1)
  	    else raise Fail "unmatched close box"
  
--- 345,352 ----
  	    (* check that depth < maxDepth *)
  ****)
  	      enqueueTok (strm, {sz = ref 0, tok = END, len = 0});
! 	      setSize (strm, true);     (* interchanged with following *)
! 	      setSize (strm, false);    (* 05 Jul 1999. dgc. *)
  	      curDepth := depth-1)
  	    else raise Fail "unmatched close box"
  
Test: *
Owner: jhr
Status: fixed in 110.0.4 (jhr, 110.0.4)
----------------------------------------------------------------------
Number: 1514
Title:	     sockets c-library broken
Keywords:    sockets
Submitter:   Johannes 5 Joemann <joemann@fuenf.free.de>
Date:        07/07/1999
Version:     110.17
System:	     Any/All
Severity:    major
Problem:
Parameters given from ML to the runtime sockets library are not correctly
interpreted, obviously due to a change in their representation (as was
pointed out by jhr in bug 1480) that is not reflected in the usage of
the appropriate (de-)referencing C macros.
So when you try to open a connection you get NO CARRIER;) e.g.
SysErr: No such file or directory [noent]

Code:	
Transcript:
- UnixSock.toAddr "/tmp/.s.PGSQL.5432";
val it = ADDR - : UnixSock.sock_addr
- UnixSock.fromAddr it;
val it = "\213 +" : string

Comments:
The patches below are sufficient to do TCP connections to Postgres and
open a Unix domain socket. I didn't check the whole sockets lib, if you
think it helps if I check out more, let me know.
Since this is the first (and hopefully the last:-) time I looked at this
runtime C lib stuff, no guarantee that the patches are in tune with what
your intention of using the macros is. It just works the way I did it.

Fix:
*** connect.c   1999/07/05 23:57:30     1.1
--- connect.c   1999/07/07 03:07:17
***************
*** 21,27 ****
      ml_val_t  addr = REC_SEL(arg, 1);
      int               sts;

!     sts = connect (sock, PTR_MLtoC(struct sockaddr, addr), OBJ_LEN(addr));

      CHK_RETURN_UNIT(msp, sts);

--- 21,27 ----
      ml_val_t  addr = REC_SEL(arg, 1);
      int               sts;

!     sts = connect (sock, GET_SEQ_DATAPTR(struct sockaddr, addr), REC_SELINT(addr, 1));

      CHK_RETURN_UNIT(msp, sts);
*** from-unixaddr.c     1999/07/07 00:51:23     1.1
--- from-unixaddr.c     1999/07/07 01:00:36
***************
*** 20,26 ****
   */
  ml_val_t _ml_Sock_fromunixaddr (ml_state_t *msp, ml_val_t arg)
  {
!     struct sockaddr_un        *addr = PTR_MLtoC(struct sockaddr_un, arg);

      ASSERT(addr->sun_family == AF_UNIX);

--- 20,26 ----
   */
  ml_val_t _ml_Sock_fromunixaddr (ml_state_t *msp, ml_val_t arg)
  {
!     struct sockaddr_un        *addr = GET_SEQ_DATAPTR(struct sockaddr_un, arg);

      ASSERT(addr->sun_family == AF_UNIX);
*** from-inetaddr.c     1999/07/07 01:22:10     1.1
--- from-inetaddr.c     1999/07/07 01:25:21
***************
*** 21,27 ****
   */
  ml_val_t _ml_Sock_frominetaddr (ml_state_t *msp, ml_val_t arg)
  {
!     struct sockaddr_in        *addr = PTR_MLtoC(struct sockaddr_in, arg);
      ml_val_t          inAddr, res;

      ASSERT (addr->sin_family == AF_INET);
--- 21,27 ----
   */
  ml_val_t _ml_Sock_frominetaddr (ml_state_t *msp, ml_val_t arg)
  {
!     struct sockaddr_in        *addr = GET_SEQ_DATAPTR(struct sockaddr_in, arg);
      ml_val_t          inAddr, res;

      ASSERT (addr->sin_family == AF_INET);
*** to-inetaddr.c       1999/07/07 02:28:05     1.1
--- to-inetaddr.c       1999/07/07 02:33:17
***************
*** 22,32 ****
  ml_val_t _ml_Sock_toinetaddr (ml_state_t *msp, ml_val_t arg)
  {
      struct sockaddr_in        addr;

      memset(&addr, 0, sizeof(struct sockaddr_in));

      addr.sin_family = AF_INET;
!     memcpy (&addr.sin_addr, REC_SELPTR(char, arg, 0), sizeof(struct in_addr));
      addr.sin_port = htons(REC_SELINT(arg, 1));

      return ML_CData (msp, &addr, sizeof(struct sockaddr_in));
--- 22,33 ----
  ml_val_t _ml_Sock_toinetaddr (ml_state_t *msp, ml_val_t arg)
  {
      struct sockaddr_in        addr;
+     ml_val_t inAddr = REC_SEL(arg, 0);

      memset(&addr, 0, sizeof(struct sockaddr_in));

      addr.sin_family = AF_INET;
!     memcpy (&addr.sin_addr, GET_SEQ_DATAPTR(char, inAddr), sizeof(struct in_addr));
      addr.sin_port = htons(REC_SELINT(arg, 1));

      return ML_CData (msp, &addr, sizeof(struct sockaddr_in));

Test: *
Owner: jhr
Status: fixed in 110.31
----------------------------------------------------------------------
Number: 1515
Title:       ML signal handling broken since 110.15
Keywords:    runtime, signals
Submitter:   Roland McGrath <roland@ai.mit.edu>
Date:        7/19/1999
Version:     110.20 (and back through 110.15)
System:	     all
Severity:    major
Problem:     ML signals don't work
Code:	     just try it, clearly noone has since 110.15
Transcript:  it crashes, trust me
Comments:    It seems clear the ML signals code in the runtime never ran once.
Fix:	     Below find a patch to runtime/mach-dep/signal-util.c with the fix.
	     This patch also includes a fix I previously reported that
	     never got merged in.  Enjoy.

Index: smlnj/runtime/mach-dep/signal-util.c
diff -u smlnj/runtime/mach-dep/signal-util.c:1.1.1.2 smlnj/runtime/mach-dep/signal-util.c:1.2.2.2
--- smlnj/runtime/mach-dep/signal-util.c:1.1.1.2	Tue Mar 23 04:14:17 1999
+++ smlnj/runtime/mach-dep/signal-util.c	Mon Jul 19 03:14:30 1999
@@ -31,9 +31,9 @@
     vsp->vp_sigCode = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].sigNum;
     vsp->vp_sigCount = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].count;
     if (IS_SYSTEM_SIG(vsp->vp_sigCode))
-        vsp->vp_numPendingSigs -= vsp->vp_sigCount;
+        vsp->vp_numPendingSysSigs -= vsp->vp_sigCount;
     else
-	vsp->vp_numPendingSysSigs -= vsp->vp_sigCount;
+	vsp->vp_numPendingSigs -= vsp->vp_sigCount;
 
   /* advance the pending queue */
     if ((--vsp->vp_numInQ == 0) || (++vsp->vp_nextPendingSig == NUM_SIGS))
@@ -89,7 +89,7 @@
 ml_val_t MakeResumeCont (ml_state_t *msp, ml_val_t resume[])
 {
   /* allocate the resumption closure */
-    ML_AllocWrite(msp,  0, MAKE_DESC(10, DTAG_record));
+    ML_AllocWrite(msp,  0, MAKE_DESC(11, DTAG_record));
     ML_AllocWrite(msp,  1, PTR_CtoML(resume));
     ML_AllocWrite(msp,  2, msp->ml_arg);
     ML_AllocWrite(msp,  3, msp->ml_cont);
@@ -153,16 +153,16 @@
 
     contClosure = PTR_MLtoC(ml_val_t, msp->ml_closure);
 
-    msp->ml_arg			= contClosure[2];
-    msp->ml_cont		= contClosure[3];
-    msp->ml_closure		= contClosure[4];
-    msp->ml_linkReg		= contClosure[5];
-    msp->ml_linkReg		= contClosure[6];
-    msp->ml_exnCont		= contClosure[7];
-    msp->ml_varReg		= contClosure[8];
-    msp->ml_calleeSave[0]	= contClosure[9];
-    msp->ml_calleeSave[1]	= contClosure[10];
-    msp->ml_calleeSave[2]	= contClosure[11];
+    msp->ml_arg			= contClosure[1];
+    msp->ml_cont		= contClosure[2];
+    msp->ml_closure		= contClosure[3];
+    msp->ml_linkReg		= contClosure[4];
+    msp->ml_pc			= contClosure[5];
+    msp->ml_exnCont		= contClosure[6];
+    msp->ml_varReg		= contClosure[7];
+    msp->ml_calleeSave[0]	= contClosure[8];
+    msp->ml_calleeSave[1]	= contClosure[9];
+    msp->ml_calleeSave[2]	= contClosure[10];
 
 } /* end of LoadResumeState */
 
@@ -183,4 +183,3 @@
 	return FALSE;
 
 } /* end of GCSignal */

As well as the fixes to signal-util.c that I sent previously,
this additional change to mach-dep/X86.prim.asm was necessary
for ML signal handling to work (without this change, it still crashes).
I tested x86-linux and x86-freebsd platforms.  I don't know if there
are analogous bugs in `sigh_resume' routine on other platforms.


Index: X86.prim.asm
===================================================================
RCS file: /projects/express/cvsroot/smlnj/runtime/mach-dep/X86.prim.asm,v
retrieving revision 1.5.2.2
diff -u -b -p -r1.5.2.2 X86.prim.asm
--- X86.prim.asm	1999/05/09 19:50:31	1.5.2.2
+++ X86.prim.asm	1999/07/19 23:24:22
@@ -168,7 +168,6 @@ ML_CODE_HDR(sigh_return_a)
 ENTRY(sigh_resume)
 	movl	IMMED(REQ_SIG_RESUME), request_w
 	movl	IMMED(ML_unit),stdlink
-	movl	IMMED(ML_unit),stdclos
 	movl	IMMED(ML_unit),pc
 	jmp	CSYM(set_request)

Comments:
 [Matthias, 7/20/99]
  Hmm, what exactly are the symptoms of this "broken signals" thing?  As
  far as I can tell, ^C does work as expected on my Linux box.  This
  would indicated that signal handling -- at least for SIGINT -- works.
  (This is in versions 110.17...110.20.)  Am I just being lucky?

 [Roland McGrath <roland@frob.com>, 7/19/99]
  I was not quite clear in my description of the problem.  It indeed handles
  the signals fine, it's resuming the interrupted ML code after the handler
  that crashes every time.  Since the handler for SIGINT just throws back to
  the REPL and never tries to resume the interrupted code, you don't notice it.

  Try for example:

  Signals.setHandler (UnixSignals.sigQUIT, Signals.HANDLER (fn (_,_,k) => (print "interrupted\n"; k)));

  and then generate a SIGQUIT from the keyboard (usually ^\).

  Here's an example session from 110.16 (the runtime code in question is
  unchanged between 110.15 and 110.20):

  Standard ML of New Jersey v110.16 [FLINT v1.5], April 15, 1999 [CM; autoload enabled]
  - Signals.setHandler (UnixSignals.sigQUIT, Signals.HANDLER (fn (_,_,k) => (print "interrupted\n"; k)));
  val it = HANDLER fn : Signals.sig_action
  - [[[[ here I hit ^\ on the terminal ]]]]interrupted
  /work/express/stock-smlnj/bin/sml: Fatal error -- bogus fault not in ML: (11, 0x804c699)


  Process sml exited abnormally with code 1

 [Matthias, 6/20/01]
 Amazingly, 1 year and 11 months after the bug was reported (and fixed!),
 the fix is now finally in...
 Somehow Roland's patch did get applied only partially; MakeResumeCont
 still constructed a record with an incorrect descriptor (wrong length).

 After discussion with John (Reppy) we agreed that the correct solution
 is to construct a 10-element record after all because "varReg" is supposed
 to be a per-execution-context value that is not to be overridden when
 invoking a continuation.  (Right now this probably would not have mattered
 much because we have only one execution context.)

Test: *
Owner: jhr
Status: fixed in 110.34 (06/19/01) by blume and jhr
----------------------------------------------------------------------
Number: 1516
Title: mode bits for heap2exec output file
Keywords: heap2exec
Submitter: Jeff Foster <jfoster@cs.berkeley.edu>
Date: 7/15/99
Version: -
System: -
Severity: medium
Problem: 
  We recently discovered a minor bug in heap2exec while using it to
  build a stand-alone program analysis tool.

  When heap2exec creates the new output file:

      if ((out_fd = open(argv[EXEC_POS],O_WRONLY|O_CREAT|O_TRUNC)) == -1) {

  the mode bits for the new file are omitted.  Apparently when the O_CREAT
  flag is specified the mode bits are required.  When they are omitted,
  whatever random garbage is on the stack is used for the mode bits.  As a
  result, whenever we run heap2exec the resulting file has the group sticky
  bit set, which causes us all sorts of problems.

Fix:
  The solution is to specify the mode bits, e.g.,

      if ((out_fd = open(argv[EXEC_POS],O_WRONLY|O_CREAT|O_TRUNC,0777)) == -1) {

Test:
Owner: Lorenz
Status: fixed  (Lorenz, 7/15/99)
----------------------------------------------------------------------
Number: 1517
Title:       "New CM-manager" linking bug
Keywords:    Compilation Manager, private directive, linking
Submitter:   Simon Helsen, shelsen@acm.org
Date:        07/26/99
Version:     Standard ML of New Jersey v110.20 [FLINT v1.5], July 16, 1999
System:      PentiumII, Linux (Kernel) 2.0.37
Severity:    major

Problem:
  The new CM raises an Error due to ill-treating the
  "private"-directive. The error occurs in the second compilation within
  one sml session. It seems a plain bug in the implementation of the
  private directive in CM

Code:        The following two files already produce the error:

test.sml
--------

structure Nonsense = struct
   val id = 4
end

sources.cm
----------

Library 
structure Nonsense 
is
test.sml : private

Transcript:  for the above example:

Standard ML of New Jersey v110.20 [FLINT v1.5], July 16, 1999
- CM.make "sources.cm";
[scanning ./sources.cm]
[parsing ./test.sml]
[creating directory ./CM/SKEL ...]
[compiling ./test.sml]
[creating directory ./CM/x86-unix ...]
[wrote ./CM/x86-unix/test.sml]
[New bindings added.]
val it = true : bool
- CM.make "sources.cm";
[scanning ./sources.cm]
./sources.cm:4.1-4.9 Error: link-time error in ./test.sml
  NoCodeBug
  
val it = false : bool
-

Comments:    none
 [Matthias, 7/27/99]
  Thanks for the bug report.  Looks like I am discarding executable code
  too early in the case of non-shareable modules.  I'll look into this.
  (I am currently revising the internal recompile logic anyway, so I
  should be able to fix this problem while doing so.)

  PS: Could you tell me what you need the "private" directive for?  I am
  looking for a realistic example because I was even thinking of
  dropping "private" altogether because it causes CM's internal logic to
  become quite complex -- much more complex than I would like it to be.

Fix: -
Test: *
Owner: Matthias
Status: fixed in 110.24 [Matthias, 11/5/99]
----------------------------------------------------------------------
Number: 1518
Title:       Posix.IO.FLock.flock type disagrees with basis library spec
Keywords:    flock
Submitter:   Stephen Weeks <sweeks@acm.org>
Date:        08/14/99
Version:     110.9.1
System:      x86-linux
Severity:    
Problem:     

The spec does not have the "l_" prefixing each field in the record. 

Posix.IO.FLock.flock;
val it = fn
  : {l_len:int, l_pid:?.POSIX_IO.pid option, l_start:int,
     l_type:?.POSIX_IO.lock_type, l_whence:?.POSIX_IO.whence}
    -> ?.POSIX_IO.FLock.flock

Code:        
Transcript:  
Comments:    
Fix:         
Test: *
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1519
Title: Compiler bug: HppaCG.incOffset - spill area too small
Keywords: spill area, HPPA
Submitter: Chris Waters   <bcw01z@email.mot.com>
Date: 09/01/99
Version: 110.0.3
System: HPPA HPUX 
Subsystem: SML compiler
Severity: major
Problem:
  Using a very large Yacc file the compiler gives up and crashes with
  the above error.  It also returns these messages :

   raised at: util/errormsg.sml:54.14-54.19 
              util/stats.sml:164.40 
              util/stats.sml:164.40 
              sched/recompile.sml:206.38-206.41
Comments:

Fix:
 
Test: 
Owner: Lal, Allen
Status: open
----------------------------------------------------------------------
Number: 1520
Title:       Output of type variables
Keywords:    types
Submitter:   Andreas Rossberg, rossberg@ps.uni-sb.de
Date:        09/03/1999
Version:     110.0.3
System:      Linux
Severity:    cosmetic
Problem:     When printing types with more than 26^2 type variables,
             identifiers generated for the higher variables are junk.
Code:        
                fun f(x,y) = x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x
                val f = fn x => (f o f) x

Transcript:  Was not possible to paste here because it contained invalid
             characters :-(
Comments:    -
Fix:         Just make the function to generate tyvar ids more general.
Test: *
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1521
Title: random crashes on AMD K6-III
Keywords: x86, AMD, crashes
Submitter: Alain Deutsch <deutsch@pst.inrialpes.fr>
Date: 8/16/99
Version: ???
System: AMD K6-III/450, Linux
Severity: critical
Problem: 
   We are experiencing fairly surprising problems with SML/NJ running on an
  AMD K6-III/450 based Linux machine. Problems are: random SML crashes,
  often during garbage collection, in the form of various inconsistencies
  detected by the GC.

   Our application program runs perfectly on a similar Linux machine that is
  equipped with an Intel PIII/550. SML/NJ version and Linux version are
  exactly the same on both machines.

   Did you hear similar reports by other users ?

   Do you think this could possibly related to the fact that the K6 has
  separate instruction and data caches, and that the contents of the
  instruction cache may be incorrect due to the fact that SML GC relocates
  code segments ?

   If so, would a cache flush instruction at the end of GC solve the problem?

Code:
Transcript:
Comments:
  That might very well be the problem, but one needs to do the flush after
  code is allocated.  The source code uses a macro called FlushICache to invoke
  flushing of the instruction cache where needed.  You migh try changing its
  definition in runtime/include/cache-flush.h and rebuilding the run-time to
  see if the problem goes away.
Fix:
Test:
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1522
Title:       Replication of replicated datatype - not allowed
Keywords:    compiler, modules
Submitter:   Leif Kornstaedt <kornstae@ps.uni-sb.de>
Date:        08/19/1999
Version:     Standard ML of New Jersey, Version 110.0.3, January 30, 1998
System:      x86-win32
Severity:    major
Problem:

It is not possible to replicate a datatype defined in a structure
with an opaque signature constraint.  In my understanding of the
Definition, this should be possible (correct me if I'm wrong!).

Code:

  structure S0 =
  struct
    datatype t = C | D
  end;

  signature S =
  sig
    datatype t = datatype S0.t
  end;

  structure S1 :> S =
  struct
    datatype t = datatype S0.t
  end;

  structure S2 =
  struct
    datatype t = datatype S1.t
  end;

Transcript:

  Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
  - use "replic.sml";
  [opening replic.sml]
  replic.sml:18.3-18.29 Error: rhs of datatype replication not a datatype

Comments: 
Fix: -
Test: bug1522.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1523
Title: installing SML/NJ-C Foreign Function Interface library
Keywords: foreign function
Submitter: Ovidiu Podisor   Ovidiu.Podisor@innovative.ro
Date: 09/27/99
Version: 110.0.3, January 30, 1998 
System: x86 Linux RedHat 6.0
Subsystem: Installation
Severity: critical
Problem:
  Link error when building the run time system with smlnj-ccalls enabled.

  The problem lies in the fact that CALL_BIAS is not macro-expanded 
  in the line:

	  subl	$CALL_BIAS,%eax	/* adjust pc to point at "->" */

  because of the '$' character.

  See below for a fix.

Transcript:
[root@smarald objs]# make -f mk.x86-linux-ccalls
(make RUNTIME="run.x86-linux" VERSION="v-x86-linux" CC="gcc -ansi" CFLAGS="-O" CPP="gcc -x c -E -P -ansi" TARGET=X86 DEFS="  -DHOST_X86 -DTARGET_X86 -DOPSYS_UNIX -DOPSYS_LINUX -D_POSIX_SOURCE -D_BSD_SOURCE -DVREGS -DCALLEESAVE=3 -D_SIGCONTEXT_H -DC_CALLS" XOBJS="" XLIBS="" LD_LIBS="" XCLIBS="../c-libs/smlnj-ccalls/libsmlnj-ccalls.a" run.x86-linux)
make[1]: Entering directory `/usr/share/smlnj/src/runtime/objs'
...
make[2]: Leaving directory `/usr/share/smlnj/src/runtime/memory'
gcc -ansi -o run.x86-linux -O  main.o c-libraries.o unix-raise-syserr.o ml-options.o new-boot.o load-ml.o run-ml.o globals.o ml-state.o error.o timers.o unix-timers.o qualify-name.o swap-bytes.o unix-fault.o signal-util.o unix-signal.o unix-prof.o prim.o  ../c-libs/smlnj-ccalls/libsmlnj-ccalls.a ../c-libs/posix-os/libposix-os.a ../c-libs/smlnj-runtime/libsmlnj-runt.a ../c-libs/smlnj-signals/libsmlnj-sig.a ../c-libs/smlnj-prof/libsmlnj-prof.a ../c-libs/smlnj-sockets/libsmlnj-sock.a ../c-libs/smlnj-time/libsmlnj-time.a ../c-libs/smlnj-date/libsmlnj-date.a ../c-libs/smlnj-math/libsmlnj-math.a ../c-libs/posix-process/libposix-process.a ../c-libs/posix-procenv/libposix-procenv.a ../c-libs/posix-filesys/libposix-filesys.a ../c-libs/posix-io/libposix-io.a ../c-libs/posix-sysdb/libposix-sysdb.a ../c-libs/posix-signal/libposix-signal.a ../c-libs/posix-tty/libposix-tty.a ../c-libs/posix-error/libposix-error.a ../gc/libgc.a ../memory/libmem.a   -lm
../c-libs/smlnj-ccalls/libsmlnj-ccalls.a(c-entry.o)(.text+0x6): undefined reference to `CALL_BIAS'
collect2: ld returned 1 exit status
make[1]: *** [run.x86-linux] Error 1
make[1]: Leaving directory `/usr/share/smlnj/src/runtime/objs'
make: *** [all] Error 2
Comments:

Fix:
[root@smarald smlnj-ccalls]# diff /usr/share/smlnj/src/runtime/c-libs/smlnj-ccalls/c-entry.asm /usr/share/mathc/src/runtime/c-libs/smlnj-ccalls/c-entry.asm 
7,12d6
<        
< #if defined(TARGET_X86)
<         #define CONCAT(a,b)  CONCAT_(a,b)
<         #define CONCAT_(a,b) a ## b
<         
<         #define CALL_BIAS     5
14c8,10
<         #define cresult       %eax
---
> #if defined(TARGET_X86)
> #define CALL_BIAS     5
> #define cresult       %eax
79c75
<       subl    CONCAT($,CALL_BIAS),%eax        /* adjust pc to point at "->" */
---
>       subl    $CALL_BIAS,%eax         /* adjust pc to point at "->" */

Test: -
Owner: Lorenz
Status: open
----------------------------------------------------------------------
Number: 1524
Title:       Bus Error
Keywords:    allocation space, GC 
Submitter:   Simon Helsen, shelsen@acm.org
Date:        10/7/99
Version:     Standard ML of New Jersey v110.23 [FLINT v1.5], October 8, 1999
System:      PentiumII 450, Linux (Kernel) 2.0.37
Severity:    major

Problem:
  After compilation/loading and linking, CM.make crashes with a "bus
  error" report on the x86-linux platform. The problem does not occur
  everywhere (i.e. in some CM library collections it doesn't happen) and
  it doesn't occur at all on a sparc-unix platform for exactly the same
  software

Code: /home/sml/Dev/bugs/bug1524
  (http://optpcs.cs.nyu.edu/~leunga/buserror.tar.gz)

Transcript:  

mlope/control> /home/helsen/languages/ml/smlnj/bin/sml > transcript
CM.make "sources.cm";
GC #0.0.0.0.1.7:   (10 ms)
GC #0.0.0.0.2.49:   (20 ms)
GC #0.0.0.1.3.121:   (30 ms)
GC #0.0.0.1.4.165:   (20 ms)
GC #0.0.0.1.5.219:   (20 ms)
GC #0.0.0.1.6.222:   (10 ms)
GC #0.0.0.1.7.239:   (0 ms)
GC #0.0.0.1.8.247:   (0 ms)
GC #0.0.0.1.9.273:   (0 ms)
GC #0.0.0.1.10.297:   (10 ms)
GC #0.0.1.2.11.323:   (60 ms)
GC #0.0.1.2.12.378:   (10 ms)
GC #0.0.1.2.13.395:   (10 ms)
GC #0.0.1.2.14.404:   (0 ms)
Bus error
mlope/control> 

------------------

and diagnostic contains this :

------------------

Standard ML of New Jersey v110.23 [FLINT v1.5], October 8, 1999
- [autoloading]
[autoloading done]
[scanning ./sources.cm]
[scanning ./../library/sources.cm]
[scanning ./../library/array/sources.cm]
[scanning ./../library/array/../basic/sources.cm]
[scanning ./../library/array/../basic/../pervasive/sources.cm]
[scanning ./../library/array/../basic/../pervasive/../nj-basis/sources.cm]
[scanning ./../library/array/../list/sources.cm]
[scanning ./../library/array/../list/../number/sources.cm]
[scanning ./../library/array/../list/../number/../smlnj-lib/sources.cm]
[scanning ./../library/array/../list/../number/../from_basis.cm]
[scanning ./../library/array/../list/../promise/sources.cm]
[scanning ./../library/array/../list/../sequence/sources.cm]
[scanning ./../library/array/../list/../sequence/../container/sources.cm]
[scanning ./../library/directed-graph/sources.cm]
[scanning ./../library/directed-graph/../misc/sources.cm]
[scanning ./../library/directed-graph/../misc/../time/sources.cm]
[scanning ./../library/directed-graph/../property/sources.cm]
[scanning ./../library/directed-graph/../set/sources.cm]
[scanning ./../library/directed-graph/../set/../trace/sources.cm]
[scanning ./../library/env/sources.cm]
[scanning ./../library/ml-yacc-lib/sources.cm]
[./../library/array/../basic/CM/x86-unix/relation.sig loaded]
[./../library/array/../basic/CM/x86-unix/relation.sml loaded]
[./../library/array/../basic/../pervasive/../nj-basis/CM/x86-unix/int-inf-sig.sml loaded]
[./../library/array/../basic/../pervasive/../nj-basis/CM/x86-unix/int-inf.sml loaded]
[./../library/array/../basic/../pervasive/CM/x86-unix/pervasive.sml loaded]
[./../library/array/../basic/CM/x86-unix/outstream.sig loaded]
[./../library/array/../basic/CM/x86-unix/dynamic-wind.sig loaded]
[./../library/array/../basic/CM/x86-unix/dynamic-wind.sml loaded]
[./../library/array/../basic/CM/x86-unix/outstream.sml loaded]
[./../library/array/../basic/CM/x86-unix/layout.sig loaded]
[./../library/array/../basic/CM/x86-unix/order0.sig loaded]
[./../library/array/../basic/CM/x86-unix/char0.sig loaded]
[./../library/array/../basic/CM/x86-unix/string0.sig loaded]
[./../library/array/../basic/CM/x86-unix/char0.sml loaded]
[./../library/array/../basic/CM/x86-unix/string0.sml loaded]
[./../library/array/../basic/CM/x86-unix/layout.sml loaded]
[./../library/array/../basic/CM/x86-unix/instream.sig loaded]
[./../library/array/../basic/CM/x86-unix/instream.sml loaded]
[./../library/array/../list/../number/../smlnj-lib/CM/x86-unix/random-sig.sml loaded]
[./../library/array/../list/../number/../smlnj-lib/CM/x86-unix/lib-base-sig.sml loaded]
[./../library/array/../list/../number/../smlnj-lib/CM/x86-unix/lib-base.sml loaded]
[./../library/array/../list/../number/../smlnj-lib/CM/x86-unix/random.sml loaded]
[./../library/array/../basic/CM/x86-unix/t.sig loaded]
[./../library/array/../list/../number/CM/x86-unix/basic-ring.sig loaded]
[./../library/array/../list/../number/CM/x86-unix/ring.sig loaded]
[./../library/array/../list/../number/CM/x86-unix/ordered-ring.sig loaded]
[./../library/array/../list/../number/CM/x86-unix/integer.sig loaded]
[./../library/array/../list/../number/CM/x86-unix/fixed-integer.sig loaded]
[./../library/array/../basic/CM/x86-unix/iterate.sig loaded]
[./../library/array/../basic/CM/x86-unix/iterate.sml loaded]
[./../library/array/../list/../number/CM/x86-unix/ring.fun loaded]
[./../library/array/../list/../number/CM/x86-unix/basic-ordered-ring.sig loaded]
[./../library/array/../list/../number/CM/x86-unix/ordered-ring.fun loaded]
[./../library/array/../list/../number/CM/x86-unix/basic-integer.sig loaded]
[./../library/array/../list/../number/CM/x86-unix/integer.fun loaded]
[./../library/array/../list/../number/CM/x86-unix/fixed-integer.sml loaded]
[./../library/array/../basic/CM/x86-unix/ref.sig loaded]
[./../library/array/../basic/CM/x86-unix/error.sig loaded]
[./../library/array/../basic/CM/x86-unix/error.sml loaded]
[./../library/array/../basic/CM/x86-unix/ref.sml loaded]
[./../library/array/../list/../number/CM/x86-unix/ring-elt-ref.sig loaded]
[./../library/array/../list/../number/CM/x86-unix/ring-elt-ref.fun loaded]
[./../library/array/../list/../number/CM/x86-unix/int-ref.sml loaded]
[./../library/array/../list/../sequence/../container/CM/x86-unix/container.sig loaded]
[./../library/array/../list/../sequence/CM/x86-unix/sequence.sig loaded]
[./../library/array/../list/../sequence/CM/x86-unix/destructable.sig loaded]
[./../library/array/../list/CM/x86-unix/list.sig loaded]
[./../library/array/../list/CM/x86-unix/strict.sig loaded]
[./../library/array/../list/../sequence/CM/x86-unix/basic.sig loaded]
[./../library/array/../list/../sequence/CM/x86-unix/destructable.fun loaded]
[./../library/array/../list/CM/x86-unix/basic.sig loaded]
[./../library/array/../list/CM/x86-unix/basic-iter.sig loaded]
[./../library/array/../list/CM/x86-unix/list.fun loaded]
[./../library/array/../list/CM/x86-unix/strict.fun loaded]
[./../library/array/../list/CM/x86-unix/iter.fun loaded]
[./../library/array/../list/CM/x86-unix/basic-strict.sig loaded]
[./../library/array/../list/CM/x86-unix/basic-strict.fun loaded]
[./../library/array/../list/CM/x86-unix/strict.sml loaded]
[./../library/array/../list/CM/x86-unix/list-ref.sig loaded]
[./../library/array/../list/CM/x86-unix/list-ref.fun loaded]
[./CM/x86-unix/region.sig loaded]
[./CM/x86-unix/region.fun loaded]
[./../library/array/../basic/CM/x86-unix/order.sig loaded]
[./../library/directed-graph/../misc/../time/CM/x86-unix/time.sig loaded]
[./../library/directed-graph/../misc/../time/CM/x86-unix/time.fun loaded]
[./../library/array/../basic/CM/x86-unix/unit.sig loaded]
[./../library/array/../basic/CM/x86-unix/unit.sml loaded]
[./../library/array/../basic/CM/x86-unix/string.sig loaded]
[./../library/array/../basic/CM/x86-unix/string.sml loaded]
[./../library/directed-graph/../set/../trace/CM/x86-unix/computation.sig loaded]
[./../library/directed-graph/../set/../trace/CM/x86-unix/trace.sig loaded]
[./../library/directed-graph/../set/../trace/CM/x86-unix/intermediate-computation.sig loaded]
[./../library/directed-graph/../set/../trace/CM/x86-unix/string-map.sig loaded]
[./../library/directed-graph/../set/../trace/CM/x86-unix/trace.fun loaded]
[./../library/directed-graph/../set/../trace/CM/x86-unix/intermediate-computation.fun loaded]
[./../library/directed-graph/../set/../trace/CM/x86-unix/string-map.fun loaded]
[./../library/directed-graph/../set/../trace/CM/x86-unix/link.sml loaded]
[./../library/array/../basic/CM/x86-unix/char.sig loaded]
[./../library/array/../basic/CM/x86-unix/char.sml loaded]
[./../library/directed-graph/../misc/CM/x86-unix/dir.sig loaded]
[./../library/directed-graph/../misc/CM/x86-unix/file.sig loaded]
[./../library/directed-graph/../misc/CM/x86-unix/process.sig loaded]
[./../library/directed-graph/../misc/CM/x86-unix/process.sml loaded]
[./../library/directed-graph/../misc/CM/x86-unix/filesys.fun loaded]
[./../library/directed-graph/../misc/../time/CM/x86-unix/date.sig loaded]
[./../library/directed-graph/../misc/../time/CM/x86-unix/date.fun loaded]
[./../library/array/../basic/CM/x86-unix/bool.sig loaded]
[./../library/array/../basic/CM/x86-unix/bool.sml loaded]
[./CM/x86-unix/control.sig loaded]
[./CM/x86-unix/control.sml loaded]
[linking with $basis.cm/basis.cm@145608(general.sig)]
[linking with $basis.cm/basis.cm@144582(general.sml)]
[linking with $basis.cm/basis.cm@523852(array.sig)]
[linking with $basis.cm/basis.cm@506888(array.sml)]
[linking with $basis.cm/basis.cm@765896(vector.sig)]
[linking with $basis.cm/basis.cm@752000(vector.sml)]
[linking with $basis.cm/basis.cm@111449(basis-structs.sml)]
[linking with $basis.cm/basis.cm@111212(bind-largest32.sml)]
[linking with $basis.cm/basis.cm@111025(basis-time.sml)]
[linking with $basis.cm/basis.cm@166594(pre-basis.sml)]
[linking with $basis.cm/basis.cm@144377(pre-string.sml)]
[linking with $basis.cm/basis.cm@166469(string-cvt.sig)]
[linking with $basis.cm/basis.cm@161951(string-cvt.sml)]
[linking with $basis.cm/basis.cm@318727(bool.sig)]
[linking with $basis.cm/basis.cm@316402(bool.sml)]
[linking with $basis.cm/basis.cm@144252(list.sig)]
[linking with $basis.cm/basis.cm@134701(list.sml)]
[linking with $basis.cm/basis.cm@187864(num-format.sml)]
[linking with $basis.cm/basis.cm@168579(num-scan.sml)]
[linking with $basis.cm/basis.cm@161778(char.sig)]
[linking with $basis.cm/basis.cm@145733(char.sml)]
[linking with $basis.cm/basis.cm@134544(string.sig)]
[linking with $basis.cm/basis.cm@120266(string.sml)]
[linking with $basis.cm/basis.cm@258191(substring.sml)]
[linking with $basis.cm/basis.cm@222057(mono-vector.sig)]
[linking with $basis.cm/basis.cm@222182(char-vector.sml)]
[linking with $basis.cm/basis.cm@215004(mono-array.sig)]
[linking with $basis.cm/basis.cm@258396(char-array.sml)]
[linking with $basis.cm/basis.cm@558290(substring.sig)]
[linking with $basis.cm/basis.cm@558069(text.sig)]
[linking with $basis.cm/basis.cm@557410(text.sml)]
[linking with $basis.cm/basis.cm@557187(Exports/char.sml)]
[linking with $basis.cm/basis.cm@298706(integer.sig)]
[linking with $basis.cm/basis.cm@298879(int32.sml)]
[linking with $basis.cm/basis.cm@293277(int31.sml)]
[linking with $basis.cm/basis.cm@293072(bind-int-32.sml)]
[linking with $basis.cm/basis.cm@385679(bind-largeint-32.sml)]
[linking with $basis.cm/basis.cm@120141(Unsafe/cinterface.sig)]
[linking with $basis.cm/basis.cm@117826(Unsafe/cinterface.sml)]
[linking with $basis.cm/basis.cm@324005(ieee-real.sig)]
[linking with $basis.cm/basis.cm@318884(ieee-real.sml)]
[linking with $basis.cm/basis.cm@292899(word.sig)]
[linking with $basis.cm/basis.cm@380702(word31.sml)]
[linking with $basis.cm/basis.cm@362732(real-format.sml)]
[linking with $basis.cm/basis.cm@347072(math.sig)]
[linking with $basis.cm/basis.cm@347197(math64.sml)]
[linking with $basis.cm/basis.cm@346867(real.sig)]
[linking with $basis.cm/basis.cm@324335(real64.sml)]
[linking with $basis.cm/basis.cm@324130(bind-real-32.sml)]
[linking with $basis.cm/basis.cm@316229(time.sig)]
[linking with $basis.cm/basis.cm@302336(time.sml)]
[linking with $basis.cm/basis.cm@557030(date.sig)]
[linking with $basis.cm/basis.cm@558447(date.sml)]
[linking with $basis.cm/basis.cm@229166(Unix/pre-os.sml)]
[linking with $basis.cm/basis.cm@289345(word32.sml)]
[linking with $basis.cm/basis.cm@289140(bind-sysword-32.sml)]
[linking with $basis.cm/basis.cm@462010(Posix/posix-error.sml)]
[linking with $basis.cm/basis.cm@288935(Posix/posix-prelude.sml)]
[linking with $basis.cm/basis.cm@285843(Posix/posix-signal.sml)]
[linking with $basis.cm/basis.cm@385884(word8.sml)]
[linking with $basis.cm/basis.cm@274560(Posix/posix-process.sml)]
[linking with $basis.cm/basis.cm@391454(Posix/posix-filesys.sml)]
[linking with $basis.cm/basis.cm@449332(Posix/posix-procenv.sml)]
[linking with $basis.cm/basis.cm@215129(word8-vector.sml)]
[linking with $basis.cm/basis.cm@199067(word8-array.sml)]
[linking with $basis.cm/basis.cm@424536(Posix/posix-io.sml)]
[linking with $basis.cm/basis.cm@420766(Posix/posix-sysdb.sml)]
[linking with $basis.cm/basis.cm@257986(byte.sig)]
[linking with $basis.cm/basis.cm@255832(byte.sml)]
[linking with $basis.cm/basis.cm@230033(Posix/posix-tty.sml)]
[linking with $basis.cm/basis.cm@229876(Posix/posix-error.sig)]
[linking with $basis.cm/basis.cm@229719(Posix/posix-signal.sig)]
[linking with $basis.cm/basis.cm@198580(Posix/posix-flags.sig)]
[linking with $basis.cm/basis.cm@229514(Posix/posix-process.sig)]
[linking with $basis.cm/basis.cm@229341(Posix/posix-procenv.sig)]
[linking with $basis.cm/basis.cm@228961(Posix/posix-filesys.sig)]
[linking with $basis.cm/basis.cm@198862(Posix/posix-io.sig)]
[linking with $basis.cm/basis.cm@198737(Posix/posix-sysdb.sig)]
[linking with $basis.cm/basis.cm@198391(Posix/posix-tty.sig)]
[linking with $basis.cm/basis.cm@198122(Posix/posix.sig)]
[linking with $basis.cm/basis.cm@192677(Posix/posix.sml)]
[linking with $basis.cm/basis.cm@471548(bind-word-32.sml)]
[linking with $basis.cm/basis.cm@111803(OS/os-path.sig)]
[linking with $basis.cm/basis.cm@526065(OS/os-path-fn.sml)]
[linking with $basis.cm/basis.cm@523977(Unix/os-path.sml)]
[linking with $basis.cm/basis.cm@111928(OS/os-filesys.sig)]
[linking with $basis.cm/basis.cm@548511(Unix/os-filesys.sml)]
[linking with $basis.cm/basis.cm@486850(option.sig)]
[linking with $basis.cm/basis.cm@483963(option.sml)]
[linking with $basis.cm/basis.cm@483838(NJ/cont.sig)]
[linking with $basis.cm/basis.cm@482436(NJ/cont.sml)]
[linking with $basis.cm/basis.cm@482279(NJ/signals.sig)]
[linking with $basis.cm/basis.cm@488161(NJ/internal-signals.sml)]
[linking with $basis.cm/basis.cm@479047(NJ/cleanup.sig)]
[linking with $basis.cm/basis.cm@475233(NJ/cleanup.sml)]
[linking with $basis.cm/basis.cm@486975(NJ/signals.sml)]
[linking with $basis.cm/basis.cm@482122(Unix/unix-signals.sig)]
[linking with $basis.cm/basis.cm@480106(Unix/unix-signals.sml)]
[linking with $basis.cm/basis.cm@479172(OS/at-exit.sml)]
[linking with $basis.cm/basis.cm@111678(OS/os-process.sig)]
[linking with $basis.cm/basis.cm@471753(Unix/os-process.sml)]
[linking with $basis.cm/basis.cm@110868(OS/os-io.sig)]
[linking with $basis.cm/basis.cm@112802(Unix/os-io.sml)]
[linking with $basis.cm/basis.cm@110663(OS/os.sig)]
[linking with $basis.cm/basis.cm@112306(Unix/os.sml)]
[linking with $basis.cm/basis.cm@110040(IO/io.sig)]
[linking with $basis.cm/basis.cm@110165(IO/io.sml)]
[linking with $basis.cm/basis.cm@767836(exn-name.sml)]
[linking with $basis.cm/basis.cm@767471(Exports/general.sml)]
[linking with $basis.cm/basis.cm@556825(Exports/int.sml)]
[linking with $basis.cm/basis.cm@827719(Exports/int32.sml)]
[linking with $basis.cm/basis.cm@668007(Exports/word.sml)]
[linking with $basis.cm/basis.cm@766226(Exports/string.sml)]
[linking with $basis.cm/basis.cm@792031(Exports/word32.sml)]
[linking with $basis.cm/basis.cm@792393(Exports/largeint.sml)]
[linking with $basis.cm/basis.cm@794946(Exports/char-vector.sml)]
[linking with $basis.cm/basis.cm@827514(Exports/int31.sml)]
[linking with $basis.cm/basis.cm@640150(bind-position-32.sml)]
[linking with $basis.cm/basis.cm@624019(IO/prim-io.sig)]
[linking with $basis.cm/basis.cm@624755(IO/prim-io-fn.sml)]
[linking with $basis.cm/basis.cm@624176(IO/text-prim-io.sml)]
[linking with $basis.cm/basis.cm@659791(IO/bin-prim-io.sml)]
[linking with $basis.cm/basis.cm@623862(IO/os-prim-io.sig)]
[linking with $basis.cm/basis.cm@646741(Unix/posix-bin-prim-io.sml)]
[linking with $basis.cm/basis.cm@640355(Unix/posix-text-prim-io.sml)]
[linking with $basis.cm/basis.cm@620286(IO/clean-io.sml)]
[linking with $basis.cm/basis.cm@576018(IO/stream-io.sig)]
[linking with $basis.cm/basis.cm@575861(IO/text-stream-io.sig)]
[linking with $basis.cm/basis.cm@575688(IO/text-io.sig)]
[linking with $basis.cm/basis.cm@576175(IO/text-io-fn.sml)]
[linking with $basis.cm/basis.cm@574558(Unix/posix-text-io.sml)]
[linking with $basis.cm/basis.cm@573975(Exports/real.sml)]
[linking with $basis.cm/basis.cm@867095(NJ/smlnj.sml)]
[linking with $basis.cm/basis.cm@889098(NJ/wrap-export.sml)]
[linking with $basis.cm/basis.cm@888941(NJ/export.sig)]
[linking with $basis.cm/basis.cm@886307(NJ/export.sml)]
[linking with $basis.cm/basis.cm@792236(NJ/interval-timer.sig)]
[linking with $basis.cm/basis.cm@885073(NJ/interval-timer.sml)]
[linking with $basis.cm/basis.cm@884777(NJ/print-hook.sml)]
[linking with $basis.cm/basis.cm@836690(timer.sig)]
[linking with $basis.cm/basis.cm@837123(internal-timer.sml)]
[linking with $basis.cm/basis.cm@747522(real64-vector.sml)]
[linking with $basis.cm/basis.cm@730940(real64-array.sml)]
[linking with $basis.cm/basis.cm@767298(Unsafe/object.sig)]
[linking with $basis.cm/basis.cm@777068(Unsafe/object.sml)]
[linking with $basis.cm/basis.cm@573818(Unsafe/poll.sig)]
[linking with $basis.cm/basis.cm@775784(Unsafe/poll.sml)]
[linking with $basis.cm/basis.cm@767173(Unsafe/unsafe-vector.sig)]
[linking with $basis.cm/basis.cm@767048(Unsafe/unsafe-array.sig)]
[linking with $basis.cm/basis.cm@766923(Unsafe/unsafe-mono-vector.sig)]
[linking with $basis.cm/basis.cm@766449(Unsafe/unsafe-mono-array.sig)]
[linking with $basis.cm/basis.cm@766574(Unsafe/unsafe.sig)]
[linking with $basis.cm/basis.cm@770835(Unsafe/unsafe.sml)]
[linking with $basis.cm/basis.cm@870768(NJ/prof-control.sig)]
[linking with $basis.cm/basis.cm@878462(NJ/prof-control.sml)]
[linking with $basis.cm/basis.cm@109915(NJ/gc.sig)]
[linking with $basis.cm/basis.cm@877506(NJ/gc.sml)]
[linking with $basis.cm/basis.cm@870579(NJ/internals.sig)]
[linking with $basis.cm/basis.cm@876712(NJ/internals.sml)]
[linking with $basis.cm/basis.cm@870217(NJ/sysinfo.sig)]
[linking with $basis.cm/basis.cm@872175(NJ/sysinfo.sml)]
[linking with $basis.cm/basis.cm@667882(NJ/weak.sig)]
[linking with $basis.cm/basis.cm@871459(NJ/weak.sml)]
[linking with $basis.cm/basis.cm@870342(NJ/smlnj.sig)]
[linking with $basis.cm/basis.cm@870941(Exports/smlnj.sml)]
[linking with $basis.cm/basis.cm@574180(Exports/time.sml)]
[linking with $basis.cm/basis.cm@791826(Exports/word31.sml)]
[linking with $basis.cm/basis.cm@728142(bind-largeword-32.sml)]
[linking with $basis.cm/basis.cm@794741(Exports/largeword.sml)]
[linking with $basis.cm/basis.cm@727953(pack-word.sig)]
[linking with $basis.cm/basis.cm@728347(pack-word-b32.sml)]
[linking with $basis.cm/basis.cm@112101(Exports/os.sml)]

------------------

Comments:

  The problem seems related to the x86-platform and did not
  occur in previous versions! 

 [Matthias, 10/8/99]
  I have also experienced such crashes on the x86 platform.
  There are two easy ways of triggering a crash (in 110.23):

  1. Run a CML program, or
  2. Reduce the allocation size to 128k or less.

  Both things are quite annoying.  First, I want to play with CML on the
  x86 platform.  But even more importantly, there are systems that have
  a 128k cache (notably the popular "Celeron A" CPUs), and anything
  bigger than that in allocation size is going to slow the system down
  quite noticably.

  I have just built a 2-CPU Celeron system, and it is screaming fast --
  except when I run SML/NJ.  (Getting MP support back into SML/NJ would
  also be nice, btw.)  "Celeron A" CPUs are actually faster (or can be
  faster) than the corresponding PentiumII CPUs because the Celeron has
  a fast cache (full clock speed) while the PentiumII has a slower cache
  (half clock speed).  The PentiumII cache is 256k, though, which is
  twice as much as what's on the Celeron.

  Is there anything inherently preventing SML/NJ from reducing
  allocation size to 128k?

 [Allen Leung, 10/8/99]
  I compiled the recompile the compiler with 'sml @SMLalloc=64k'
  and 'sml @SMLalloc=128k'.  I ran the SMLNJ benchmarks with -alloc 64k.
  I also tried compiling and running my other ML programs with a small allocation
  space.   But none of these reproduces the crash.

  This is on a system with dual pentium II xeon cpus and one gig of memory,
  running Linux 5.2 Kernel 2.2.7.

  I can crash cml however.  

  The new bug is likely to be caused by the new ra introduced in 110.23.  
  But I suspect the cml bug has some other origin, since the same program 
  I tested also crashed in 110.20.

 [Matthias, 10/8/99]
  Well, maybe the problem is confined to the boot sequence.

  Try the following with 110.23:

  - Take the original 110.23 distribution files
  - Do zcat 110.23-config.tar.Z | tar xf -
  - Edit config/install.sh and change the allocation size for x86 to 128k
  - Do the usual config/install.sh thing

  Here is a partial transcript (this is on a PentiumII laptop, but it is
  identical to the Celeron case):

  .
  .
  [Loading init.cmi/CM/x86-unix/core.sml]
  [Loading init.cmi/CM/x86-unix/built-in.sml]
  [Loading init.cmi/CM/x86-unix/pre-perv.sml]
  [Loading init.cmi/CM/x86-unix/pre-string.sml]
  /home/blume/ML/23test/bin/.run/run.x86-linux: Fatal error -- unexpected fault, signal = 11, code = 0x804c869
  !!! Boot code failed, no heap image built (sml.x86-linux).
  Command exited with non-zero status 1

  If I reduce the size to 64k, the same problem is triggered ever earlier.

 [Allen Leung, 10/8/99]
  I can repro this.  This also causes the same crash in 110.20.  
  So it seems to be something that's been around for a few releases.   

 [Lal, 10/8/99]
  This bug does not seem to be x86 specific, but goes back all the way
  to 110.12. The table below shows the various experiments I did. 
  110.9.1 will reach the toplevel prompt even with an allocation space
  of 8k!  

  My feeling is that this bug  may be another manifestation of bug 1507.

  ---------------------------------------------------------
  version:	arch:	command:		symptom:
  110.23		alpha	makeml -alloc 128k	crash
  110.22		alpha	makeml -alloc 128k	crash
  110.20		alpha	makeml -alloc 128k	crash
  110.19		alpha	makeml -alloc 128k	ok
  110.19		alpha	makeml -alloc 64k	crash
  110.18		alpha	makeml -alloc 128k	ok
  110.18		alpha	makeml -alloc 64k	crash
  110.17		alpha	makeml -alloc 64k	crash
  110.16		alpha	makeml -alloc 64k	crash
  110.12		alpha	makeml -alloc 64k	crash
  110.9.1		alpha	makeml -alloc 128k	ok
  110.9.1		alpha	makeml -alloc 64k	ok
  110.9.1		alpha	makeml -alloc 32k	ok
  110.9.1		alpha	makeml -alloc 16k	ok 
  110.9.1		alpha	makeml -alloc 8k	ok 

 [Lal, 10/8/99]
  There may be two unrelated bugs: 110.{12,13,14} generate a runtime
  system error with an allocation space of 64k. 

    bin/.run/run.alpha32-dunix: Fatal error -- bad object tag 19, obj = 0x20300f8, desc = 0x20300cc

  Whereas 110.15 core dumps with an allocation space of 64k.
  Again, it is possible that this is the same bug.

 [jhr, 10/8/99]
  I could believe that the boot sequence might fail on a small allocation
  space.  The boot code is probably not robust w.r.t. checking for heap
  exhaustion.

 [Leunga, 10/?/99]
  I used 110.23 to compile itself, it takes up about 900 secs. 
  Then I used the new image to compile itself; that takes 817 secs, which
  is comparable to the 814 secs I got before.

  On the x86, I have modified system/makeml to use ALLOC=256k, since that
  is used in config/install.sh.   I suspect you used the default of 1M to
  build the x86 image, then redistributed it.  On the x86, alloc=1M is slower, 
  probably because of smaller cache.  I recommend modifying makeml to 
  use the same ALLOC parameters as config/install.sh; this will prevent 
  a lot of headaches in the future.    

  I found that if you don't do that to makeml, 
  the comparisons are meaningless, even
  if you start up sml with the appropriate SMLalloc parameter.  
  I have no idea why.  In 110.21, I usually compare builds from 'makeml'.

 [Lal, 10/13/99]
  I talked with John about the allocation space size issue, and making
  the default smaller than 1M would not be the right thing to do. It is
  certainly the right thing to do for the Pentium II, but some newer x86
  chips have caches that are 1M, and the numbers vary across the board. 
  A recent message from Blume indicated that a cache size of 32k was
  best! 

  Currently, config/install.sh does not process command line options but 
  it is sensitive to the architecture since it does:

      case $ARCH in
	mips*) ALLOC=1M ;;
	x86)
	  ALLOC=256k
	;;
	alpha32)
	  ALLOC=512k
	;;
	*)
	  ALLOC=512k
	;;
      esac

  whereas makeml does have a allocation size command line argument but
  otherwise defaults to 1M. As you suggest, I have added the above code
  to makeml to make things consistent at the very least, for now ... 
  Eventually, I think we want to have command line options to
  config/install.sh. 

Fix: 
Test: *
Owner: jhr, Lal
Status: open
----------------------------------------------------------------------
Number: 1525
Title: Array2 bug
Keywords: Array2
Submitter: Ken Larsen <Ken.Larsen@cl.cam.ac.uk>
Date: 10/12/99
Version: 110.0.5
System: -
Severity: major 
Problem: 
  Array2 doesn't behave as specified.
  With code below rmTest and cmTest both evaluate to false.
  Thus, something is wrong in foldi (and in mapi, appi also it turns
  out).

Code:
  val arr = Array2.tabulate Array2.RowMajor (3,3,fn x => x)

  val upperRight = {base = arr, row = 0, col = 1, 
		    nrows = SOME 2, ncols = NONE}

  val rm =
      Array2.foldi Array2.RowMajor (fn(i,j,e,acc)=>((i,j),e) :: acc) [] upperRight

  fun dup(x, acc) = (x, x) :: acc

  val rmResult = foldl dup [] [(0,1), (0,2), (1,1), (1,2)]

  val rmTest = rm = rmResult

  val cm =
      Array2.foldi Array2.ColMajor (fn(i,j,e,acc)=>((i,j),e) :: acc) [] upperRight

  val cmResult = foldl dup [] [(0,1), (1,1), (0,2), (1,2)]

  val cmTest = cm = cmResult

Transcript:
Comments:
Fix: (fix supplied)
Test: bug1525.1.sml
Owner: jhr
Status: fixed in 110.0.6 [jhr]
----------------------------------------------------------------------
Number: 1526
Title: double-quote representation in strings and characters
Keywords: strings, chars
Submitter: Michael Siff   msiff@mail.slc.edu
Date: 11/03/99
Version: 110.0.3
System: Sparc Solaris 2.7
Subsystem: SML basis library
Severity: minor
Problem:
  I am getting different behavior from Char.fromString on the string
  "\"" depending on how I generate it:

  Compare:

  - Char.fromString "\"";
  val it = NONE : char option

  - Char.fromString (Char.toString (#"\""));
  val it = SOME #"\"" : char option

  - String.sub ("\"", 0);
  val it = #"\"" : char

Code:
  (* all three tests should result in SOME(#"\""). they do not *)
  val test1 = Char.fromString "\""
  val test2 = SOME(String.sub ("\"", 0))
  val test3 = Char.fromString (Char.toString #"\"")

Transcript:
val test1 = NONE : char option
val test2 = SOME #"\"" : char option
val test3 = SOME #"\"" : char option

Comments:
 [jhr, 11/7/99]
  This is a "feature" of the specification.  The double quote character
  must be escaped in a character literal, which is why you get NONE from
  Char.fromString "\"".  Note that Char.toString(#"\"") produces the
  string "\\\"" (using ML escape syntax), which is a valid SML escape
  sequence.

Fix: clarify documentation of Char.fromString

Test: bug1526.1.sml
Owner: jhr
Status: not a bug
----------------------------------------------------------------------
Number: 1527
Title: assertion failure and unknown tag
Keywords: runtime, gc, arrays
Submitter: David B. Benson <dbenson@eecs.wsu.edu>
Date: 11/04/99
Version: 110.0.3
System:  x86-linux, hppa-hpux
Severity: serious
Problem:
ihppa-hpux: Assertion failure
x86-linux:  Fatal error -- unknown tag
Code: In 3c.tar.gz in ftp ftp.eecs.wsu.edu pub/dbenson
      See the instuctions at the end of this email message.
Transcript:  There are two.
The different errors in the linux code are a result of using different
amounts of printing into the report files, given below.  The two good runs each
involved producing 49Mbyte report files, which I have snipped out essentially
everything. The fatal error messages occur BEFORE the last new line above them,
so they resided on the end of the dying line, which I have snipped.  Notice that
the last newline finally does come out.

---------- hppa-hpux -----------------------------------------------------------
time.stats start:  Tue Nov 2 16:26:14 PST 1999
Tue Nov  2 16:26:17 PST 1999
/net/local/sml/bin/sml: Assertion failure (arena->nextw <= arena->tospTop) at "major-gc.c:830"
time.stats stop :  Tue Nov 2 16:30:44 PST 1999

---------- x86-linux ------------------------------------------------------------
time.stats start:  Sun Oct 31 13:51:57 PST 1999
/usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0 @ 0x402c0000 in array arena

time.stats stop :  Sun Oct 31 13:57:12 PST 1999

time.stats start:  Sun Oct 31 14:21:15 PST 1999
Sun Oct 31 14:21:15 PST 1999
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188
[snip]
starting on file /users/dbenson/3c/rca/stats/stats.rca.90.20000.3.6.acqn1290
/usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xa @ 0x409f0000 in array arena

time.stats stop :  Sun Oct 31 14:27:03 PST 1999

GOOD RUN
time.stats start:  Sun Oct 31 14:45:52 PST 1999
Sun Oct 31 14:45:52 PST 1999
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188
<<full info>>[snip]<<full info>>
starting on file /users/dbenson/3c/rca/stats/stats.rca.95.20000.3.6.acqn1306
starting on fakes
Sun Oct 31 14:58:53 PST 1999
time.stats stop :  Sun Oct 31 14:58:53 PST 1999

time.stats start:  Sun Oct 31 16:18:55 PST 1999
Sun Oct 31 16:18:56 PST 1999
/usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xa @ 0x409f0000 in array arena

time.stats stop :  Sun Oct 31 16:24:53 PST 1999

time.stats start:  Sun Oct 31 16:33:56 PST 1999
Sun Oct 31 16:33:56 PST 1999
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188
[snip]
starting on file /users/dbenson/3c/rca/stats/stats.rca.75.20000.3.4.acqn1247
/usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xa @ 0x407f0004 in array arena

time.stats stop :  Sun Oct 31 16:37:00 PST 1999

time.stats start:  Sun Oct 31 16:44:13 PST 1999
Sun Oct 31 16:44:13 PST 1999
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188
t[snip]
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.2.acqn1189
[snip]
starting on file /users/dbenson/3c/rca/stats/stats.rca.70.20000.3.4.acqn1233
/usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xa @ 0x40550008 in array arena

time.stats stop :  Sun Oct 31 16:47:09 PST 1999

time.stats start:  Sun Oct 31 16:55:32 PST 1999
Sun Oct 31 16:55:32 PST 1999
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188
t[snip]g
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.8.acqn1193
/usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xc @ 0x405f0004 in array arena

time.stats stop :  Sun Oct 31 16:55:58 PST 1999

time.stats start:  Sun Oct 31 17:05:01 PST 1999
Sun Oct 31 17:05:01 PST 1999
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188
tg[snip]gt
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.8.acqn1193
/usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xc @ 0x405f0004 in array arena

time.stats stop :  Sun Oct 31 17:05:27 PST 1999

time.stats start:  Sun Oct 31 17:18:38 PST 1999
Sun Oct 31 17:18:38 PST 1999
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188
trialinformation[snip]graphinformation
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.8.acqn1193
/usr/share/smlnj/bin/sml: Fatal error -- unknown tag 0xc @ 0x405f0004 in array arena

time.stats stop :  Sun Oct 31 17:19:09 PST 1999

GOOD RUN
time.stats start:  Sun Oct 31 17:41:08 PST 1999
Sun Oct 31 17:41:08 PST 1999
starting on file /users/dbenson/3c/rca/stats/stats.rca.55.20000.3.0.acqn1188
<<full info>>[snip]<<full info>>
starting on file /users/dbenson/3c/rca/stats/stats.rca.95.20000.3.6.acqn1307
Sun Oct 31 17:52:40 PST 1999
time.stats stop :  Sun Oct 31 17:52:40 PST 1999
------------------------------------------------------------------------------------------------
Comments:
  ---When I use the LONG report format, I get this to run on x86-linux, but
         this is not a fix.
How to install:
 (1) ftp ftp.eecs.wsu.edu 
      cd pub/dbenson
      get [binary] 3.tar.gz         (almost 28Mbyte)
 (2) in your HOME directory, uncompress with zcat or whatever.  Obtain 3c.tar (almost 86Mbyte file)
 (3) tar xf 3c.tar will create the entire directory structure, 3c
 (4) cd 3c/src and read the README.
 Note: runs relative to HOME environment variable.
 --- if there are problems with any of these directions or directories of files, please let me know.

Comments:
 [Lal, 11/3/99]
  Before investigating this further, it would be worth checking if
  110.0.5 also exhibits the same problem. If the bug persists and is
  repeatable it may be possible to thin it down to a small test case. 

Fix: -
Test: ???
Owner: jhr?
Status: open
----------------------------------------------------------------------
Number: 1528
Title: Compiler bug: LtyKernel: unexpected TC_FIX freevars in tc_aux
Keywords: FLINT, lambda types
Submitter: Chris Burdorf <chris@disney.com>
Date: 10/27/99
Version: 110.23
System: ?
Severity: major
Problem: 
  When compiling under 110.23, I get the following error
  message.  Previously I was compiling with 110 with the
  109.29 basis library loaded, because I couldn't get
  the 110 basis library to work.  Can you give me
  any suggestions? Version(s) to revert back to?

  Error: Compiler bug: LtyKernel: unexpected TC_FIX freevars in tc_aux

Code: ???
Transcript: ???
Comments:

  > (1) 110.23 is a developmental or "working" version, and these versions
  > tend to be more buggy and less stable than the release version, so I
  > am curious what features you need that are not available in the
  > 110.0.3 Release version (by the way, a patch version 110.0.6 of the
  > release will be available in a few days).

  I had problems with the 110.3 release version, because some
  code I got from a guy that no longer works here uses Array2 in
  a way that won't compile under 110.3.  So I changed his usage
  of Array2 to use the new definition (as I understood it), but then
  it gronked elsewhere when compiling the program (a tesselator that
  takes NURBS -> polygons).  So, after being unable to find a fix,
  I just included the smlnj-109.29 basis library and compiled it
  under 110.3 and it worked.    I stuck with it until we got
  this new high powered linux renderfarm, so I decided to port
  it to linux, but I couldn't find a 109.29 version for linux, so
  I decided to try 110.3.  I had the same problem on 110.3 as before, so I tried
  110.23 and got the reported error.
  >
  > (2) 110.23 comes with a version of smlnj-lib that should work with it.
  > We'd be interested in hearing about the problem you had with the 110
  > version of the basis library, since this may indicate a bug that needs
  > to be fixed.  When you say "110 basis library" in your message, do you
  > mean the 110.23-smlnj-lib.tar.Z package that comes with 110.23, or the
  > package (actually patch version 110.0.3) that comes with the 110
  > Release?

  The one I use on Linux is 110.23 basis. on Irix I use 109.29 basis.

  >
  > (3) This looks like a new and serious bug, so it would be very helpful
  > if we could reproduce it.  If you can't isolate it in a compact piece
  > of code, is there any chance we could temporarily borrow your code to
  > isolate it ourselves?

  Disney won't let me send out code, and the file the bug appears in is several
  thousand lines long.  Is there any way to get the compiler to
  print what function it is working on?  I could probably send you the function
  that it erros on without problems.
  >
  > I guess my advice is to try using 110.0.3 (or 110.0.6 in a few days),
  > with the version of smlnj-lib that comes with it, unless you have a
  > strong reason why you need to use a later working version.  Among the
  > post-110.0.3 working versions, 110.9.1 is probably the most stable.
  >

 [jhr, 10/28/99]
  Can you elaborate on the problem you are having with Array2?  It should
  be easy to figure out a work-around or fix, and I'm glad to try to help
  you do that.  I would strongly recommend using 110.0.6, which should be
  out in a day or so.  Among other things, it has several bug fixes in the
  Array2 implementation (and it builds under RedHat 6.0).

 [dbm, 10/28/99]
  It's possible that you tripped over a bug in the array2 module, as
  John Reppy mentioned in his reply.  These bugs have been fixed in the
  110.0.6 release, but I don't think the fix got into 110.23.

  The current interface of the Array2 module (signature ARRAY2) is
  documented by the following web page.

    http://www.cs.bell-labs.com/~jhr/sml/basis/pages/array2.html

  The source code for the ARRAY2 signature is the same in 109.29, 
  110.0.6, and 110.23 (although the file name changes from
  array2-sig.sml to array2.sig in 110.23), and I presume the official
  semantics is still as described in the ARRAY2 web page.  The source
  code for the Array2 implementation (array2.sml) differs in all three
  versions, and presumably the 110.0.6 version is now correct.

Fix:
Test: -
Owner: jhr, Zhong
Status: open
----------------------------------------------------------------------
Number: 1529
Title: The sign of ~0.0
Keywords: "zero","sign","inf"
Submitter: Jan Egil Kristiansen   janegil@stones.com
Date: 10/10/99
Version: 110.0.3
System: x86 Windows NT 4.0sp4
Subsystem: Other
Severity: 
Problem:

  There must be a difference between 0.0 and ~0.0. How else can the 
  result of a division by zero have a sign?
  (also see 
    http://lbk.olivant.fo/janegil/datanomps2/mlcomments/zerosign.html)

Code:
  1.0/0.0;
  1.0/(~0.0);
  (~1.0)/0.0;

Transcript:
  - 1.0/0.0;
  val it = inf : real
  - 1.0/(~0.0);
  val it = inf : real
  - (~1.0)/0.0;
  val it = ~inf : real

Comments:
  I expected the 2nd result to equal the 3rd, not the first.

  (Rather than fixing nan and inf, I'd like to see them scrapped. Neat 
  idea, but it does not work.)

  Output from MLWorks:
  MLWorks> 1.0/0.0;
  1.0/(~0.0);
  (~1.0)/0.0;
  val it : real = inf
  val it : real = ~inf
  val it : real = ~inf

Fix:

Test: bug1529.1.sml
Owner: jhr, Lal
Status: open
----------------------------------------------------------------------
Number: 1530
Title:  ListSetFn should have opaque result [smlnj-lib]
Keywords: utility library: ListSetFn
Submitter: David B. Benson dbenson@eecs.wsu.edu
Date: 11/05/99
Version: 110.0.3
System:  x86-linux
Severity: serious [scariest problem I've come across]
Problem:
  The following code compiles!  ...and then, except for the counter that
  I put in, loops forever at run time.
  The difficulty, I believe, is that both of the types are derived from 
		      int list,
  so somehow the compiler thinks that the first argument
  to union is, in fact a set.  But it is not, as it is not ordered,
  and union then makes a mess for the result.

  In ugraph.sml, locate HERE in a comment in the code.  This shows
  the problem and a correct call.

Code: In src.tar.gz.uu at the end of the message
Transcript:

Comments:
  Perhaps SML is supposed to work this way.  If so, then the
  problem is that the utility library code is using transparent types.
  To avoid breaking working code, I suppose you don't want to change
  these to opaque signatures.  However, it seems sensible to have a
  OpaqueListSetFn, etc., which does.  If you make this change, then
  I'll have students use the opaque versions of the library code.

  Up until this, I've always thought of sml, via the type system, as
  protecting programmers from type errors.  This is the only example
  I have which I consider to be a failure in this regard.

Fix:
 [dbm, 11/4/99]
  Looks to me like ListSetFn should have an opaque result signature
  constraint.
Test:
Owner: jhr, dbm
Status: fixed in 110.0.6, 110.0.25 [jhr, 11/7/99]
----------------------------------------------------------------------
Number: 1531
Title:	     Basis library discrepancies in IntInf and POSIX_FLAGS
Keywords:    IntInf, Posix.TTY
Submitter:   Stephen Weeks <sweeks@acm.org>
Date:        11/04/99
Version:     110.9.1
System:      x86-linux
Severity:    
Problem:     

The following changes are needed to make SML/NJ more compliant with
the Basis Library spec.
	in POSIX_FLAGS  
		fromWord -> wordTo
	in IntInf
		quotrem -> quotRem
		divmod -> divMod

Comments:    
 [jhr, 11/7/99]
  Actually, the Basis spec was revised to use the "fromWord" convention (a new
  version of the spec will be out as soon as the legal issues are settled).

  We should fix this, but our IntInf structure is not really basis compliant in
  a number of ways.

 [dbm, 11/7/99]
  We need to bring the IntInf implementation into conformance with the
  spec, and make it a regular part of the Basis environment.

Fix: correct Basis documentation
Test: -
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1532
Title:  Date:DATE missing fromString
Keywords: date, parsing, from string
Submitter: David B. Benson dbenson@eecs.wsu.edu
Date: 11/07/99
Version: 110.0.3
System:  x86-linux
Severity: very minor, but a chance to complain about the sml standard for dates.
Problem:  signature DATE is missing fromString, hence not in compliance with the standard.
Code: 
Transcript:
Comments:
 I will have to process some dates of type string produced by my linux box.
 These do not agree with exact format given in the standard for string dates 
 given in the standard as produced by Date.toString.  The difference is only
 that leading zeros do not appear for days of the month.  Later I will need
 to process dates from software which gives them as

   1999 Nov 07 14:54:08

 I conclude that the sml standard for Date.fromString is simply much too
 restrictive.  One simply needs the idempotence property that

   fromString o toString = SOME id

 while date strings in other formats are certainly also possible and it would be
 quite useful to have a method to read these in the basis library.

 A date consists of

   year:  at least four digits
   month:  "Jan" or else "JAN", etc.
   day:   int in the approprate range
   hours:minutes:seconds in the Unix-style format, except that in the
	   seconds field an optional decimal point followed by one or
	   more digits ought to be allowed, for people who need more
	   precision than I do.  Furthermore, some may wish to keep
	   track of leap seconds (or leap milliseconds) as being between
	   midnight and 00:00:00, the beginning of the next day.  Hence
	   24:00:00.002 is a 2 millisecond leap interval.  I suppose one
	   might check with the WWV folks at NIST before going to this
	   effort, since they might have a standard.
   dayofweek:  optional: 3 characters
   timezone:   optional: 3 characters

 and different poeple put these 4 to 6 tokens in different orders.

 Thinking about this suggests that the basis definition is also wrong in thinking
 of seconds as an int, at least with providing for milliseconds -- and maybe in the
 future microseconds, ...  I don't need this accuracy but people working on global
 positioning software, etc., might.

 Anyway, here is the DateExtension.fromString which I hacked out today.  Rather
 crude, but it'll be enough for my purposes.
--------------------------DateExtension.sml-----------------------------------
(* DateExtension.sml *)

structure DateExtension :
   sig
      val fromString: string -> Date.date option
   end =
struct
   fun monthOption s =
       let val m = 
             String.implode(
	       let val [c1,c2,c3] = String.explode(s)
		   val (isUpper2,c2') = 
		       if Char.isUpper(c2) then (true,Char.toLower(c2))
			  else (false,c2)
		   val (isUpper3,c3') =
		       if Char.isUpper(c3) then (true,Char.toLower(c3))
			  else (false,c3)
		in if (isUpper2 andalso isUpper3)
                      orelse (not isUpper2 andalso isUpper3)
		   then [c1,c2',c3']
		   else [#"n",#"o",#"t"]
	       end)
       in
	  (case m of
	       "Jan" => SOME Date.Jan
	     | "Feb" => SOME Date.Feb
	     | "Mar" => SOME Date.Mar
	     | "Apr" => SOME Date.Apr
	     | "May" => SOME Date.May
	     | "Jun" => SOME Date.Jun
	     | "Jul" => SOME Date.Jul
	     | "Aug" => SOME Date.Aug
	     | "Sep" => SOME Date.Sep
	     | "Oct" => SOME Date.Oct
	     | "Nov" => SOME Date.Nov
	     | "Dec" => SOME Date.Dec
	     |   _   => NONE)
       end

   fun scanMonth [] = []
     | scanMonth (m :: ms ) =
	let val mOption = monthOption(m)
	 in if isSome(mOption)
	    then valOf(mOption) :: (scanMonth ms)
	    else (scanMonth ms)
	end

   fun scanForMonth ms =
	let val [month] = scanMonth ms
	 in month
	end

   fun scanForDay [dd] = valOf(Int.fromString(dd))

   fun longFirst(s1,s2) = (String.size(s1) < String.size(s2))

   fun fromString s =
       let val toks = ListMergeSort.sort (longFirst) (String.tokens Char.isSpace s)
	   val numberOfTokens = List.length toks
       in
	  if numberOfTokens < 7 then
	     let val time :: yy :: toks = (toks)
		 val [hh, mm, ss] = String.tokens (fn(c) => (#":" = c)) time
		 val hours   = valOf(Int.fromString(hh))
		 val minutes = valOf(Int.fromString(mm))
		 val seconds = valOf(Int.fromString(ss))
		 val year    = valOf(Int.fromString(yy))
		 val (possibleMonths,possibleDays) =
		      List.foldl
			 (fn(a,(ms,ds))=> if String.size(a) = 3 then (a :: ms,ds)
					  else 
					  if String.size(a) < 3 then (ms,a :: ds)
					  else raise Fail "not a date")
			 ([],[]) toks
		 val month = scanForMonth(possibleMonths)
		 val day   = scanForDay(possibleDays)
	     in
		SOME(Date.date{year=year,month=month,day=day,
			       hour=hours,minute=minutes,second=seconds,
			       offset=NONE})
	     end
	  else NONE
       end
       handle _ => NONE

end (* structure DateExtension *) ;

Fix:
Test:
Owner: 
Status: open
----------------------------------------------------------------------
Number: 1533
Title:       installation failure on Solaris 2.7
Keywords:    installation, Solaris, library
Submitter:   Simon Helsen, shelsen@acm.org
Date:        12/2/99
Version:     110.0.6
System:      sparc-solaris2.7
Severity:    major
Problem:     installation-script breaks on compiling poll.c
Code:        NONE

Transcript:  

Machine "leia.informatik.uni-freiburg.de", Solaris 2.7, 96 Mb.

>>>>
gcc -O -D__STDC__=0 -DHOST_SPARC -DTARGET_SPARC -DOPSYS_UNIX
-DOPSYS_SOLARIS -DCALLEESAVE=3
-DUNBOXEDFLOAT=1 -I../../objs -I../../include -I.. -c posix-os-lib.c
gcc -O -D__STDC__=0 -DHOST_SPARC -DTARGET_SPARC -DOPSYS_UNIX
-DOPSYS_SOLARIS -DCALLEESAVE=3
-DUNBOXEDFLOAT=1 -I../../objs -I../../include -I.. -c poll.c
In file included from /usr/include/stropts.h:22,
                 from poll.c:20:
/usr/include/sys/stropts.h:315: parse error before `t_uscalar_t'
/usr/include/sys/stropts.h:315: warning: no semicolon at end of struct or
union
/usr/include/sys/stropts.h:334: parse error before `t_uscalar_t'
/usr/include/sys/stropts.h:334: warning: no semicolon at end of struct or
union
/usr/include/sys/stropts.h:337: parse error before `}'
*** Error code 1
<<<<

Comments:
  I realise that SML/NJ does not explicitely support Solaris 2.7,
  but our new Compute Server runs on 2.7. Would be nice if you could take a
  look. Btw, We have succesfully installed the compiler on Solaris 2.6. I
  haven't looked into it closely, but it might also be a bug on the Solaris
  side. stropts.h is quite different in Solaris 2.7. Below, you find the
  code-part related to the above errors. It suggests that t_uscalar_t is not
  defined, so perhaps some ordering is wrong (or more includes are needed?).
  Anyway, our system administrator has also contacted our Sun provider and
  they're taking a look if something is wrong in their libraries.

  /usr/include/sys/stropts.h Solaris 2.7 (lines 309 - 340) :
  ==========================================================
  /*
   * Stream I_PEEK ioctl format
   */
  struct strpeek {
	  struct strbuf   ctlbuf;
	  struct strbuf   databuf;
	  t_uscalar_t     flags;
  };

  #if defined(_SYSCALL32)

  struct strpeek32 {
	  struct strbuf32 ctlbuf;
	  struct strbuf32 databuf;
	  uint32_t        flags;
  };

  #endif /* _SYSCALL32 */

  /*
   * Stream I_FDINSERT ioctl format
   */
  struct strfdinsert {
	  struct strbuf   ctlbuf;
	  struct strbuf   databuf;
	  t_uscalar_t     flags;
	  int             fildes;
	  int             offset;
  };

  #if defined(_SYSCALL32)

 [jhr, 12/03]
  We don't have access to a 2.7 machine, but it would help if you could grep
  for t_uscalar_t in the header files (it looks like that type is not defined).
  Generally, system header files ought to be self contained, so I would call this
  a Solaris bug :).

Fix: 
Test: -
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1534
Title:		polymorphic equality for concrete eqtypes ...
Keywords:	polymorphic equality, concrete eqtypes 
Submitter:	Lal George and Dave MacQueen
Date:		11/23/99
Version:	110.24
System:		all
Severity:	major
Problem:	
	polymorphic equality is being generated for concrete eqtypes.
	e.g. Symbol.symbol list.

Code:

	file			type			line numbers
	-----			------------		--------------
    ml-yacc/lib/parser2.sml	LrTable.term		435, 439, 129
    Implementation/Unix/unix.sml file_desc		76
    Semant/basics/stamps.sml    PersStamp.persstamp	19
    Semant/basics/sympaths.sml  Symbol.symbol list	36
    FLINT/kernel/ltykernel.sml  tycI, fflag and rflag	300

Transcript:
Comments:
Fix:
Test: <need isolated test cases>
Owner: Zhong, dbm, ?
Status: open
----------------------------------------------------------------------
Number: 1535
Title:       Large ml-yacc generated file fails to compile on HP-UX
Keywords:    <optional - e.g. "modules", "types", "IO", "reals">
Submitter:   David J. King, David.King@motorola.com
Date:        11/18/1999
Version:     110.0.3
System:      HP-UX 10.20
Severity:    major
Problem:     After lots of garbage collecting there is a fatal error
Code:        Included in attachment
Transcript:
Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload
enabled]
- CM.make();
:
:
[compiling ttcn.grm.sml -> CM/hppa-unix/ttcn.grm.sml.bin]
:
:
GC #11.153.174.217.480.14379:   (890 ms)
GC #11.154.175.218.481.14399:   (1350 ms)
GC #11.155.176.219.482.14412:   (910 ms)
GC #11.156.177.220.483.14420:   (980 ms)
GC #11.157.178.221.484.14438:   (1940 ms)
GC #11.158.179.222.485.14446:   (860 ms)
GC #11.159.180.223.486.14466:   (940 ms)
GC #12.160.181.224.487.14474:   (4980 ms)
GC #12.161.182.225.488.14495:   (870 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 101187584
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #13.162.183.226.489.14503:   (4810 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 173080576
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #14.163.184.227.490.14510:   (3850 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 181403648
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #15.164.185.228.491.14531:   (5020 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 186253312
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #16.165.186.229.492.14552:   (4980 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 194314240
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #17.166.187.230.493.14573:   (5200 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 197328896
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #18.167.188.231.494.14594:   (4890 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 200605696
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #19.168.189.232.495.14615:   (5360 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 207683584
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #20.169.190.233.496.14636:   (5740 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 214630400
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #21.170.191.234.497.14657:   (5940 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 221708288
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #22.171.192.235.498.14678:   (5690 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 228786176
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #23.172.193.236.499.14699:   (6370 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 235732992
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #24.173.194.237.500.14720:   (6420 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 242810880
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #25.174.195.238.501.14741:   (6330 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 249888768
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
GC #26.175.196.239.502.14752:   (6970 ms)
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 256835584
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to allocate
to-space for generation 5; trying smaller size
/org/erl/projects/ptk/sml-97/bin/sml-cm: Error -- unable to map 52559872
bytes, errno = 12
/org/erl/projects/ptk/sml-97/bin/sml-cm: Fatal error -- unable to allocate
minimum size

Comments:
  The same code has worked on a sparc-sun-solaris2 machine.
  Perhaps a space leak?

 [Allen, 11/22/99]
     I found out what the problem with this bug is.  It is not space leak, but 
  because huge compilation units are passed to the graph coloring 
  register allocator.  If you have enough memory eventually the allocator 
  will get to a point where all spill space has run out.  

     Here are the main culprits:

		 Basic blocks Max Block Size   Interference graph
      Cluster 1: 287          >16K instrs    nodes=16942 edges=4212732 moves=6
      Cluster 2: 9907                        nodes=22369 edges=162292 moves=11767

      Actually, your program exposes a few performance problems 
  in the register allocator.  Some algorithmic improvements will be in 
  release 110.25, which will improve cluster 2's compilation time.

     For cluster 1, graph coloring will always be slow because the huge number of
  interferences.  (Hmmm... perhaps a linear scan allocator should be implemented
  for these special cases.)  The interferences is created by 
  a piece of code like this:

       datatype foo = T of int | ...

       val terms =
	   (T 0)::
	   (T 1)::
	   (T 2)::
	   (T 3)::
	   (T 4)::
	   (T 5)::
	   ...
	   (T 625)::
	    nil

  which is generated by ml-yacc.  The problem is the right associatitivity of ::
  and left-to-right evaluation rule of ML.

      I think this particular problem can be fixed by modifying ml-yacc so that
  it generates code like:

       infix $$
       fun x $$ y = y::x
	 val terms =
	   nil $$
	   (T 625) $$
	   ...
	   (T 4) $$
	   (T 3) $$
	   (T 2) $$
	   (T 1) $$
	   (T 0)

     Here's patch to do this.  The original file is from release 110.24.

 [David King]
  Thanks for the fix.  After lots of GCs ttcn.grm.sml now compiles.  But alas
  the next file "ttcn_keywords.sml" fails!  It is attached with the others
  below.
  The file contains a large list, and it fails in the same way as before.  So
  I guess a workaround is to use the $$ operator instead of [....].

 [Allen, 11/23]
      Yes, I think that's the thing to do now.  This sounds like a pretty
  annoying problem, but I think it can be easily fixed.

      In ttcn.grm.sml, I suspect if you add some non-trivial actions (like print
  statements) to the parser it'll actually speed up the compilation.  
  The slow compilation is because everything is grouped into one huge 
  compilation unit after CPS conversion.  

 [Allen, 2/17/00]
  Bug 1535 is a spilling problem.  Because of the way (huge) lists 
  are generated in mlyacc, the ra has to keep spilling.  I changed the
  lists generation code so that lists are consed in reversed, which
  makes the ra terminate much faster.  But then I ran into value polymophism 
  restriction problems in the generated code, which is bug 1538.   
  In any case 110.26 is already using these fixes; I think there should not 
  be any problem.

Fix:
Test: -
Owner: Lal, Allen
Status: open
----------------------------------------------------------------------
Number: 1536
Title: ml-lex, ml-yacc path compiled into .heap/sml-cm.x86-win32 dump.
Keywords: CM, ml-lex, ml-yacc
Submitter: Michael Sofka   sofkam@rpi.edu
Date: 12/05/99
Version: 110.0.6
System: x86 Windows 95 any
Subsystem: Installation
Severity: major
Problem:
When running CM.make(), c:/sml-build/110.0.6/bin/ml-lex, instead
of just ml-lex.  If SML (or at least ml-lex.bat and ml-yacc.bat)
are not installed in c:/sml-build/110.0.6/bin CM does not remake
the *.lex.sml and *.grm.sml files.


Code:
This can be tested by running CM.make(); in the chap2 directory
of the tiger source.

Transcript:
E:\users\mike\source\tiger\chap2>sml
Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM&CMB]
- CM.make();
[starting dependency analysis]
[scanning sources.cm]
[checking CM\x86-win32\sources.cm.stable ... not usable]
[c:/sml-build/110.0.6/bin/ml-lex tiger.lex]
[scanning H:\sml\lib\smlnj-lib.cm -> H:\sml\src\smlnj-lib\Util\smlnj-lib.cm]
[checking H:\sml\src\smlnj-lib\Util\CM\x86-win32\smlnj-lib.cm.stable ...GC #0.0.
0.0.1.14:   (60 ms)
 ok - stable]
[dependency analysis completed]
[recovering CM\x86-win32\tokens.sig.bin...GC #0.0.0.0.2.59:   (60 ms)
 done]
[recovering CM\x86-win32\tokens.sml.bin... done]
[recovering CM\x86-win32\errormsg.sml.bin... done]
[recovering CM\x86-win32\tiger.lex.sml.bin... done]
[recovering CM\x86-win32\driver.sml.bin... done]
[introducing new bindings into toplevel environment...]
val it = () : unit
-

Comments:

Fix:
Define new MLLex, MLYacc, etc groups.  However, the c:/sml-build/...
path is pervasive enough in the sml-cm.x86-win32 heap that I
back-leveled to 110.0.3 for now. :-)

Test: 
Owner: 
Status: open
----------------------------------------------------------------------
Number: 1537
Title: compiler blowup with large andalso expression
Keywords: compiler, performance, boolean expressions
Submitter: Dave MacQueen <dbm@research.bell-labs.com>
Date: 1/9/00
Version: 110.26-
System: -
Severity: critical
Problem: compilation time (and space?) blows up when compiling
  a large andalso expression
Code:

  val x1 = true;
  val x2 = true;
  val x3 = true;
  val x4 = true;
  val x5 = true;
  val x6 = true;
  val x7 = true;
  val x8 = true;
  val x9 = true;
  val x10 = true;
  val x11 = true;
  val x12 = true;
  val x13 = true;
  val x14 = true;
  val x15 = true;
  val x16 = true;
  val x17 = true;
  val x18 = true;
  val x19 = true;
  val x20 = true;

  val x = x1 andalso x2 andalso x3 andalso x4 andalso x5 andalso
	  x6 andalso x7 andalso x8 andalso x9 andalso x10 andalso
	  x11 andalso x12 andalso x13 andalso x14 andalso x15 andalso
	  x16 andalso x17 andalso x18 andalso x19 andalso x20;

Transcript:
  - use "andalso20.sml";
  GC #5.19.20.22.23.626:   (0 ms)
  [opening andalso1.sml]
  val x1 = true : bool
  val x2 = true : bool
  val x3 = true : bool
  val x4 = true : bool
  val x5 = true : bool
  val x6 = true : bool
  val x7 = true : bool
  val x8 = true : bool
  val x9 = true : bool
  val x10 = true : bool
  val x11 = true : bool
  val x12 = true : bool
  val x13 = true : bool
  val x14 = true : bool
  val x15 = true : bool
  val x16 = true : bool
  val x17 = true : bool
  val x18 = true : bool
  val x19 = true : bool
  val x20 = true : bool
  GC #5.19.21.23.24.650:   (10 ms)
  GC #5.19.21.23.25.661:   (20 ms)
  GC #5.19.22.24.26.698:   (50 ms)
  ... <many minutes>
  GC #22.546.549.553.556.12401:   (100 ms)
  GC #22.547.550.554.557.12424:   (130 ms)
  GC #22.548.551.555.558.12447:   (120 ms)
  GC #22.549.552.556.559.12470:   (120 ms)
  GC #22.550.553.557.560.12493:   (110 ms)
  GC #22.551.554.558.561.12516:   (130 ms)
  GC #23.552.555.559.562.12539:   (16580 ms)

  Interrupt
  GC #23.553.556.560.563.12541:   (10 ms)
  - GC #23.553.556.561.564.12542:   (10 ms)
Comments:
  A version with 10 variables takes about 4 seconds to compile.
  A version with 12 variables takes about 18 seconds to compile.
  A version with 15 variables fails afer 7 minutes with a
  "too many instructions" error:

    - use "andalso15.sml";
    ... <7 minutes later>
    GC #24.765.779.810.1071.34149:   (400 ms)
    GC #24.766.780.811.1072.34169:   (390 ms)
    Error: MLRisc bug: ClusterRA.mkNodes: too many instructions

  110.25 compiles all these test cases (10, 12, 20 variables) almost
  instantly.

  Clearly there is an exponential blowup going on, probably involving
  the construction of a humungous data structure.  It appears the
  blowup is caused by the FLINT-related changes in 110.26, perhaps
  involving an interaction with the recent MLRISC changes.

  This problem might account for the compilation slowdown between
  110.25 and 110.26 (I hope so).

  This was discovered when one of the regression tests failed to
  terminate (coresml/tests/d001a-ac.sml).

Fix:
Test:
Owner: Zhong, Stefan, Lal, Allen
Status: open
----------------------------------------------------------------------
Number: 1538
Title: mlyacc generates bad code
Keywords: 
Submitter: Allen Leung   leunga@cs.nyu.edu
Date: 12/06/99
Version: 110.25
System: Any/All Any Unix 
Subsystem: Installation
Severity: major
Problem:
  A previous performance hack I submitted to mlyacc turns out to
  cause problems.  The hack was to replace x :: y with y $$ x, making
  the compiler spill less.

  But sometimes code like this is generated:

  infix 5 $$
  fun x $$ y = y::x
  val preferred_change = (nil, nil $$ (T 9)):: nil

  The problem is that $$ fails the value polymorphism test.

Code:
  Recompile the compiler
Transcript:
  [compiling $cm-lib.cm/parse/cm.grm.sml]
  ../cm/parse/cm.grm.sml:419.1-423.4 Warning: type vars not generalized because of
     value restriction are instantiated to dummy types (X1,X2,...)
  GC #18.560.763.1133.3954.155244:   (20 ms)

  ignature spec
      name: preferred_change
    spec:   (Token.LrTable.term list * Token.LrTable.term list) list
    actual: (?.X1 list * Token.LrTable.term list) list

Comments:
 [Lal, 12/7/99]
  I tried the fix for both cm.grm and ml.grm and it seemed to work fine.
Fix:
In file ml-yacc/src/yacc.sml, make the following changes.
Note: I'm not sure it is 100% correct but it seems to work for me so far.

*** yacc-old.sml        Thu Dec  2 12:26:11 1999
--- yacc.sml    Mon Dec  6 22:48:51 1999
***************
*** 238,244 ****
  
  
         fun printChange () =
!           (sayln "val preferred_change = ";
             app (fn (d,i) =>
                    (say"("; printTermList d; say ","; printTermList i; 
                     sayln ")::"
--- 238,244 ----
  
  
         fun printChange () =
!           (sayln "val preferred_change : (term list * term list) list = ";
             app (fn (d,i) =>
                    (say"("; printTermList d; say ","; printTermList i; 
                     sayln ")::"
***************
*** 297,303 ****
            printBoolCase noshift;
            printNames ();
            printErrValues value;
!           say "val terms = ";
            printTermList ecTerms;
            sayln "end"
        end
--- 297,303 ----
            printBoolCase noshift;
            printNames ();
            printErrValues value;
!           say "val terms : term list = ";
            printTermList ecTerms;
            sayln "end"
        end

Test: 
Owner: Leung, Andrew
Status: open (?)
----------------------------------------------------------------------
Number: 1539
Title: Array equality uses polyEqual
Keywords: polyEqual, array
Submitter: Allen Leung <leunga@cs.nyu.edu>
Date: 12/06/99
Version: 110.25
System: Any/All Any Unix 
Subsystem: Installation
Severity: minor
Problem:
  Array equality is object identity so it can probably be handled
  better.  I suppose the reason why this is not optimized is because
  of the change to the new array representation.
Code:
  Standard ML of New Jersey v110.25 [FLINT v1.5], December 1, 1999
  - fun f(a: int Array.array, b : int Array.array) = a = b;
  [autoloading]
  GC #0.0.0.0.1.2:   (30 ms)
  [autoloading done]
  stdIn:1.52 Warning: calling polyEqual
  val f = fn : int array * int array -> bool

Comments:
 [jhr, 12/6/99]
  This is not optimized because there is no primop for comparing
  arrays.  Pointer equality on the headers is not correct; you've got
  to do pointer equality on the data objects.
Fix:
Test: 
Owner: 
Status: open
----------------------------------------------------------------------
Number: 1540
Title: FreeBSD compilation
Keywords: 
Submitter: Peter   housel@acm.org
Date: 12/13/99
Version: 110.25
System: Any/All FreeBSD 4.0-CURRENT
Subsystem: Installation
Severity: critical
Problem:
  When linking the runtime on FreeBSD-4.0 the linker can't find
  the assembly-language primitives.

Comments:

Fix:
  The check for GLOBALS_HAVE_UNDERSCORE in src/runtime/include/asm-base.h
  needs to change from

  ... || defined(OPSYS_FREEBSD) || ...

  to

  ... || (defined(OPSYS_FREEBSD) && !defined(__ELF__)) || ...

  since the ELF-format toolset doesn't prepend an underscore.

Fix:
  [jhr] I believe that this is fixed in 110.0.6 (by assuming that all FREEBSD
   systems are ELF systems).  I'll merge the fix into the 110.25 branch.

  [jhr] I've committed a change to include/asm-base.h for this problem.

Test: 
Owner: jhr
Status: fixed in 110.25 (and 110.0.6)
----------------------------------------------------------------------
Number: 1541
Title:       Array2.array equality type incorrect
Keywords:    
Submitter:   Stephen Weeks <sweeks@acm.org>
Date:        1/1/2000
Version:     110.9.1
System:      x86-linux
Severity:    major 
Problem:     
  The basis library spec for Array2.array states that
  "type t array admits equality even if ty does not".
  Thus, the following transcript is in error.

Transcript:  
  - Array2.fromList[[1.0]] = Array2.fromList[[2.0]];
  stdIn:13.1-13.48 Error: operator and operand don't agree [equality type required]
    operator domain: ''Z * ''Z
    operand:         real Array2.array * real Array2.array
    in expression:
      Array2.fromList ((1.0 :: nil) :: nil) =
	Array2.fromList ((2.0 :: nil) :: nil)

Comments:    
Fix:         
Test: bug1541.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1542
Title:       No syntax error when the equals identifier ("=") is re-bound
Keywords:    "syntax", "equals", "=", "re-bound"
Submitter:   Gary Fuehrer (fuehrer@seabase.com)
Date:        1/11/2000
Version:     110.26 and earlier
System:	     any
Severity:    minor
Problem:
  When an attempt is made to re-bind the equals identifier ("=")
  in a datbind, conbind, or exbind, no syntax error is generated.
Code:
  datbind & conbind: "datatype = = ="
  exbind: "exception = of int"
Transcript:  
Comments:    
Fix:	     
Test: bug1542.1.sml, bug1542.2.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1543
Title: DivZero exception in FreeBSD-current
Keywords: exception FreeBSD installation
Submitter: Thomas Crimi <tcrimi@andrew.cmu.edu>
Date: 1/21/00
Version: 110.0.6
System: x86, Any/All FreeBSD 4.0
Subsystem: Installation
Severity: major
Problem:
  The installation compilation raises a fatal exception.

  I've noted this also bootstrapping 110.9.1, the version FreeBSD
  installs by default.  I switched it to 110.0.6 removing the one
  patched the FreeBSD project included to support ELF.

Code:
  ./install.sh  (or FreeBSD's 'make install' in ports)
Transcript:
  Loading: entity/CM/x86-unix/lexer.sml.bin...failed.
  Trying to compile entity/lexer.sml... GC #0.1.2.4.46.2225:   (6 ms)
  GC #0.1.3.5.47.2278:   (25 ms)
  GC #0.1.3.5.48.2327:   (6 ms)

  uncaught exception divide by zero
    raised at: <file wrapping.sml.bin>
	       translate/wrapping.sml:119.10
  - !!! build of sml-cm.x86-bsd failed
  *** Error code 1

Comments:
  I will test under 3.4-Release that the same exception does not
  occur.

 [Crimi, 1/23/00]
  The FreeBSD signal's interface has changed slightly, while the
  testing hasn't been extensive (only simple 1 div 0 at the command
  line), a patch has been generated to allow sml 110.0.6 to compile
  on FreeBSD-current.  The patches are being submitted to the 
  FreeBSD ports maintainer.

Fix:
  *** src.old/runtime/mach-dep/signal-sysdep.h    Sat Jan 22 18:15:21 2000
  --- src/runtime/mach-dep/signal-sysdep.h        Sun Jan 23 01:46:53 2000
  ***************
  *** 396,403 ****
    #  elif defined(OPSYS_FREEBSD)
	/** x86, FreeBSD **/
    #    define SIG_FAULT1                SIGFPE
  ! #    define INT_DIVZERO(s, c) (((s) == SIGFPE) && ((c) == FPE_INTDIV_TRAP))
  ! #    define INT_OVFLW(s, c)   (((s) == SIGFPE) && ((c) == FPE_INTOVF_TRAP))

    #    define SIG_GetCode(info, scp)    (info)
    #    define SIG_GetPC(scp)            ((scp)->sc_pc)
  --- 396,403 ----
    #  elif defined(OPSYS_FREEBSD)
	/** x86, FreeBSD **/
    #    define SIG_FAULT1                SIGFPE
  ! #    define INT_DIVZERO(s, c) (((s) == SIGFPE) && ((c) == FPE_INTDIV))
  ! #    define INT_OVFLW(s, c)   (((s) == SIGFPE) && ((c) == FPE_INTOVF))

    #    define SIG_GetCode(info, scp)    (info)
    #    define SIG_GetPC(scp)            ((scp)->sc_pc)

Test: 
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1544
Title:       SML/NJ 110.0.3 inlining bug
Keywords:    inlining, nontermination
Submitter:   Allyn Dimock <dimock@deas.harvard.edu>
Date:        02/02/00
Version:     110.03
System:      sparc-solaris2.7
Severity:    critical
Problem:
  Failure to eta-expand within a function body leads to compiler
  space growing to point where machine thrashes virtual memory...

Code: 
  The following code compiles very quickly under CM:

    fun compTyEnv (envs as (env1,env2,assumpts)) =
      let
	  (* partially curried for recursive call *)
	  fun compTySub (t1, t2) = compTyEnv (envs) (t1, t2)
	  fun compTy (t1, t2) = ...
      in
	  compTy
      end

  The following version takes a lot of time (until killed) and space for 
  compilation:

     fun compTyEnv (envs as (env1,env2,assumpts)) =
	let
	    (* partially curried for recursive call *)
	    val compTySub = compTyEnv (envs)
	    fun compTy (t1, t2) = ...
	in
            compTy
        end

Transcript:
 First version:
  - CM.make' ("STcompare.cm");
  [starting dependency analysis]
  GC #0.0.1.2.21.604:   (0 ms)
  [parsing STcompare.sml]
  GC #0.0.1.2.22.692:   (20 ms)
  !% Warning: units not accessible due to filtering:
	  TypInfSTset.sml
	  ../FIL2CIL/SML2CIL/sml-symbol.sml
	  ../FIL2CIL/SML2CIL/Flint2Cildt.sml
	  ConstructorName.sml
	  ExternalOrDeadLabels.sml
  [dependency analysis completed]
  GC #0.0.1.2.23.715:   (10 ms)
  GC #0.0.1.2.24.752:   (10 ms)
  [compiling STcompare.sml -> CM/sparc-unix/STcompare.sml.bin]
  GC #0.0.1.2.25.776:   (10 ms)
  GC #0.0.1.2.26.787:   (10 ms)
  GC #0.0.1.2.27.803:   (0 ms)
  [wrote CM/sparc-unix/STcompare.sml.bin]
  [introducing new bindings into toplevel environment...]
  val it = () : unit
  - 

 Second version:
  - CM.make' ("STcompare.cm");
  [starting dependency analysis]
  GC #0.0.1.2.28.864:   (0 ms)
  [parsing STcompare.sml]
  !% Warning: units not accessible due to filtering:
	  TypInfSTset.sml
	  ../FIL2CIL/SML2CIL/sml-symbol.sml
	  ../FIL2CIL/SML2CIL/Flint2Cildt.sml
	  ConstructorName.sml
	  ExternalOrDeadLabels.sml
  [dependency analysis completed]
  GC #0.0.1.2.29.1000:   (10 ms)
  [compiling STcompare.sml -> CM/sparc-unix/STcompare.sml.bin]
  GC #0.1.2.3.30.1052:   (70 ms)
  GC #0.1.2.3.31.1064:   (10 ms)
  GC #0.1.2.3.32.1098:   (0 ms)
  [wrote CM/sparc-unix/STcompare.sml.bin]
  GC #0.1.2.3.33.1119:   (50 ms)
  GC #1.2.3.4.34.1122:   (270 ms)
  ...
  GC #7.37.38.39.69.1227:   (2470 ms)

  Interrupt  

  (at which point the memory size shown in top had grown by about 50M.
  An earlier attempt had gotten the machine thrashing while climbing to
  over 500M before I killed the process)

Comments:
  Since the val is inside a function, I assume that the
  problem is an inlining bug: unrolling the function an 
  arbitrary number of times.  But I don't know enough of
  SML/NJ internals to be certain.  Note that it claims to
  have written the bin file before it starts to loop.

 [dbm, 2/17/00]
  Need complete test cases.
  [see: /home/sml/Dev/bugs/1544/bug1544.1.sml]

 [dbm, 2/21/99]
  It took me a while to discover the obvious, but it looks to me
  like you have a loop at execution time, rather than at compile
  time.  You can confirm this by turning on the Stats:

    Compiler.Stats.sayBegin := true;

  This will show that the looping doesn't happen until execution
  time, after compilation has finished.

  Here is a small piece of code that I claim is equivalent, for
  the purpose of analyzing the divergence:

    fun compTyEnv x =
	let val compTySub = compTyEnv x 
	    (* following version ok, because compTyEnv doesn't get called *)
	    fun compTySub z = compTyEnv x z
	    *)
	 in (fn _ => ())
	end;

    val compare = compTyEnv ();  (* execution (not compilation!) diverges *)

  Note that the divergence occurs when the defn of compare is evaluated.

Fix: none necessary        
Test: -
Owner: dbm
Status: not a bug
----------------------------------------------------------------------
Number: 1545
Title: Datatypes involving the equality type variables are not treated
       as intended.
Submitter: Sukyoung Ryu, puppy@ropas.kaist.ac.kr
Date: 02/08/00
Version: 110.0.3
System: -
Severity: medium
Problem:
  Datatypes involving the equality type variables are not treated
  as intended. With the definition:

    fun f (x:''a) = x

  the function f has the type 

    ''a -> ''a

  but, with the definition:

    datatype ''a t = A of ''a;

  the datatype constructor A has the type

   'a -> 'a t

Transcript:
  Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
  - fun f (x:''a) = x;
  val f = fn : ''a -> ''a
  - datatype ''a t = A of ''a;
  datatype 'a t = A of 'a
  - A;
  val it = fn : 'a -> 'a t

Comments:
 [dbm, 2/17/00]
  This is not a bug, but the expected behavior.  When using
  a type variable as a formal parameter in a type or datatype
  declaration (or spec), the equality property of the type variable has no
  significance.  In other words, it is not possible to restrict the
  parameter of a type operator to be an equality type, so using an
  equality type variable has no special effect.

  There should probably be a compiler warning when an equality
  type variable is used in this context, since it generally indicates
  that the programmer is confused about this point

 [dbm, 2/18/00]
  In response to a query from Matthias, here is a further explanation.

  The purpose of an equality type variable (''a) in the polymorphic type of
  a function is to indicate that an equality operation may be applied to a
  value of that type when the body of the function is evaluated.

  This isn't relevant to other uses of type variables as formal
  parameters in parametric type/datatype definitions.  For instance,
  in a definition like

    type 'a foo = 'a * int

  you are defining a type operator that maps a type t to the type t *
  int.  One could imagine defining type operators with a restricted
  domain (say only equality types), but I don't see how this would be
  useful.  One might argue that with a definition like 

    type ''a foo = ''a * int

  you could claim that any well-formed type "t foo" was an equality type
  (because t would have to be an equality type for "t foo" to be
  well-formed), but this doesn't seem to differ significantly from the
  current situation, where we can certify that "t foo" is an equality
  type if t is.

  Hence such restricted type operators are not supported in the language
  design, and the second version of the definition of foo is treated as
  equivalent to the first version.

  If I recall correctly, in Haskell one can define type classes that
  require a type parameter to be of a given type class.  But that is so
  that functions defined for the new type class can use functions
  associated with the parameter type (similar to functors in SML).
  Since SML type/datatype declarations don't define functions associated
  with a type (except for simple, pure structural operations like those
  encoded as data constructors), they don't need to require functions to
  be associated with the parameter type.

  If you want to map a type with assocated functions to a new type with
  associated functions, SML provides functors.

Fix: -
Owner: dbm
Status: not a bug
----------------------------------------------------------------------
Number: 1546
Title: Value restriction bug
Keywords: types
Submitter: Andreas Rossberg <rossberg@ps.uni-sb.de>
Date: 2/08/00
Version: 110.0.3
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: major
Problem:
  The value restriction is not implemented properly: in some cases
  involving polymorphic constructors non-expansive expressions seem to
  get analyzed as being expansive.

Code:
  datatype 'a t = C of 'a | D
  val C x = C C

Transcript:
  - datatype 'a t = C of 'a | D;
  datatype 'a t = C of 'a | D
  - val C x = C C;
  stdIn:26.1-26.14 Warning: type vars not generalized because of
     value restriction are instantiated to dummy types (X1,X2,...)
  stdIn:26.1-26.14 Warning: binding not exhaustive
	    C x = ...
  val x = fn : ?.X1 -> ?.X1 t

Comments:
  Strangely enough, the bug does not occur with:

    datatype 'a t = C of 'a
    val C x = C C

 [Matthias, 2/8/00]
  This is not a bug with the compiler but a (well-known) bug in the
  definition.  The thing that makes this binding a non-value is the
  fact that it is (formally) refutable.

 [dbm, 2/17/00]
  SML/NJ is actually more strict than the Definition in this
  instance.

  There is a strict interpretation of the value restriction which
  regards a binding such as

    val C x = C C

  as a nonvalue binding because the pattern matching involved introduces
  a potential "effect": the raising of the Bind exception if the pattern
  doesn't match.  Of course it is clear that the pattern does match in
  this simple case, and the compiler could statically perform the
  matching and transform this into the form

    val x = C

  but in other cases like

    val C x = y

  one can't tell whether there will be an exception raised or not, so
  the compiler treats all such bindings as nonvalue bindings.

 [Matthias, 2/18/00]
  I had some private e-mail exchange with Andreas on this topic, and one
  complaint that came up was that the only mention of this behavior as
  far as the documentation is concerned is deeply buried in the
  "conversion guide".  This is a bit misleading because if I am not
  actually converting old code I am unlikely to look into the conversion
  guide but would rather hunt for "SML/NJ extensions to SML" or "how
  SML/NJ deviates from the Definiton", or some such.  Maybe this is
  worth fixing...

 [dbm, 2/18/00]
  You are right, this should be documented more clearly.  
  We used to have a section of the 0.93 manual devoted to
  language issues (including discrepancies from the Definition),
  but we don't have this in the current Web documentation.  The
  closest analogue is "Special Features of SML/NJ", which could
  have an additional section covering this sort of issue.

Fix:
Test: 
Owner: dbm, Zhong
Status: not a bug (language discrepancy)
----------------------------------------------------------------------
Number: 1547
Title: Treatment of definitional structure specs is bogus
Keywords: modules
Submitter: Andreas Rossberg   rossberg@ps.uni-sb.de
Date: 02/08/00
Version: 110.0.3
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: major
Problem:
  Definitional structure specs seem to get ignored during signature
  matching, rendering the type system unsound. The sample program below
  results in a Representation exception.

Code:
  signature S = sig type t  val x: t  val f: t -> string end;

  structure A :> S = struct type t = int  val x = 1 val f = Int.toString end;
  structure B :> S = struct type t = string  val x = "1"  fun f s = s end;

  signature SS = sig structure X : S = A end;

  structure C :> SS = struct structure X = B end;

  val x = C.X.f(A.x);

Transcript:
  - C.X.f(A.x);

  uncaught exception Representation
    raised at: boot/Unsafe/object.sml:69.19-69.33
	       print/ppobj.sml:354.20
	       print/ppobj.sml:354.20
	       print/ppobj.sml:354.20
	       print/ppobj.sml:354.20
	       util/pp.sml:554.6

 [in 110.0.6]
  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
  - use "tests/bug1547.1.sml";
  [opening tests/bug1547.1.sml]
  signature S =
    sig
      type t
      val x : t
      val f : t -> string
    end
  structure A : S
  structure B : S
  signature SS =
    sig
      structure X :
	sig
	  type t
	  val x : t
	  val f : t -> string
	end
    end
  tests/bug1547.1.sml:10.1-10.47 Error: structure def spec for X not matched

Comments:
  Interestingly, the declaration

    val _ = C.X.f(A.x)

  does not cause an exception. Is the function call optimized away as dead
  code?

  As a side note:
  I would love to see the documentation on NJ extensions to the module
  language be more complete and easier to find (I searched for half an
  hour until I found it as part of the SML'97 conversion guide).

 [jhr, 2/8/00]
  This appears to be fixed in 110.0.6 (at least the compiler issues
  an error on the definition of C).

Fix:
Test: bug1547.1.sml
Owner: dbm
Status: fixed in 110.0.6 (and 110.25)
----------------------------------------------------------------------
Number: 1548
Title:       open and signature matching with polymorphic type constructors
Keywords:    signature matching
Submitter:   Stephen Weeks <sweeks@acm.org>
Date:        02/09/00
Version:     110.9.1 (also 110.0.6 and 110.25)
System:      x86-linux
Severity:    
Problem:     
  The following code should type check.  It does not.

Code:        
  functor F(V: sig
		  type t
		  val v: t
	       end): sig
			type 'a u
			val v: 'a u
		     end =
  struct
    open V
    type 'a u = t
  end

On the other hand, the following *does* type check (as it should).
All I did was add the "val v = v" binding.

  functor F(V: sig
		  type t
		  val v: t
	       end): sig
			type 'a u
			val v: 'a u
		     end =
  struct
    open V
    type 'a u = t
    val v = v
  end

Transcript:  
  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
  - use "tests/bug1548.1.sml";
  [opening tests/bug1548.1.sml]
  tests/bug1548.1.sml:3.9-13.4 Error: value type in structure doesn't match signature spec
      name: v
    spec:   _ V.t
    actual: V.t

Comments:    
 [dbm, 2/17/00]
  This is a rather peculiar corner of the language, and there could be
  some question about whether a monotype (like t) should match a
  polymorphic (albeit degenerate) polytype spec, but given the
  following behavior in the core language, I guess it should work.

    - type 'a u = int;
    type 'a u = int
    - val x : 'a u = 3;
    val x = 3 : _ u

 [Weeks, 2/17/00]
  I would also like to argue that this is a very useful feature of the
  language, since I often write functors that take polymorphic type
  constructors as arguments, and want to instantiate them at monotypes.
  A common case is sequence types, where I have a functor that I want to 
  work on both polymorphic lists and monomorphic strings.

Fix:         
Test: bug1548.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1549
Title: reproducable segmentation violation
Keywords:
Submitter:   swasey@cs.cmu.edu
Date:        2/11/00
Version:     110.9.1 110.25
System:	     x86-linux		(redhat linux 5.2, kernel 2.0.36)
	     sparc-solaris	(SunOS 5.5.1)
	     alpha32-dunix	(OSF1 V4.0 (Rev 878) + patches)
Severity:    critical
Problem:
  SML/NJ 110.9.1 fails when executing the code below.  On linux I
  see a segmentation violation.  On solaris I see a segmentation
  violation and a core file.  On dunix I see an illegal instruction
  and a core file.

  SML/NJ 110.25 fails with a segmentation violation when executing
  the code on linux.  I haven't tried this with 110.25 on any
  other platforms.
Code:	     
  signature NUMBER =
      sig
	  type t
      end

  signature VEC =
      sig
	  structure Number : NUMBER
	  type t
	  val fromSeq : Number.t Vector.vector -> t
	  val toSeq   : t -> Number.t Vector.vector
      end

  functor PointFromVector(structure Vec : VEC) =
      struct
	  structure Vec = Vec
      end

  signature GEOMETRY_PRIMS =
      sig
	  structure Point : sig
				structure Vec : VEC
			    end
      end

  functor GeometryPrims2d (structure Number : NUMBER)
      : GEOMETRY_PRIMS
      =
      struct
	  structure Vec =
	      struct
		  structure Number = Number
		  type t = Number.t * Number.t
		  fun fromSeq #[x, y] : t = (x, y)
		  fun toSeq (x,y) = #[x, y]
	      end

	  structure Point = PointFromVector(structure Vec = Vec)
      end

  structure RealNumber
      =
      struct
	  type t = real
      end

  structure RealGeometryPrims2d = GeometryPrims2d(structure Number = RealNumber)

  local
      (* #[6.0,0.0] avoids errors *)
      val vs = RealGeometryPrims2d.Point.Vec.toSeq (6.0, 0.0)
  in
      val foo = Array.tabulate (Vector.length vs,
				fn i => Vector.sub (vs, i))
  end

Transcript:
  ###
  ### 110.9.1 on linux
  ###
  Script started on Fri Feb 11 23:44:26 2000
  ; uname -a
  Linux pickled.fox.cs.cmu.edu 2.0.36 #1-PENTIUM+MU-002 Wed Dec 16 01:10:20 EST 1998 i686 unknown
  ; sml
  Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 [CM; autoload enabled]
  - use "min.sml";
  [opening min.sml]
  min.sml:31.13-36.16 Warning: match nonexhaustive
	    #[x,y] => ...

  GC #0.0.0.0.1.12:   (10 ms)
  /usr/local/lib/sml/110.9.1/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x40c1dbc1
  status=1
  ; 
  Script done on Fri Feb 11 23:44:34 2000

  ###
  ### 110.25 on linux
  ###
  Script started on Fri Feb 11 23:53:46 2000
  ; uname -a
  Linux burnt.fox.cs.cmu.edu 2.0.36 #1-PENTIUM+MU-002 Wed Dec 16 01:10:20 EST 1998 i686 unknown
  ; sml25
  Standard ML of New Jersey v110.25 [FLINT v1.5], December 1, 1999
  - use "min.sml";
  [opening min.sml]
  [autoloading]
  [autoloading done]
  min.sml:31.13-36.16 Warning: match nonexhaustive
	    #[x,y] => ...

  /usr0/swasey/foxnet/110.25/bin/sml: Fatal error -- unexpected fault, signal = 11, code = 0x4061c78b
  status=1
  ; 
  Script done on Fri Feb 11 23:54:00 2000
Comments:
  110.0.3 doesn't fail.  Sorry the code snippet is so long.
  When I try to take anything else away, the bug doesn't show up.
  The workaround we're using is to avoid #[].

 [dbm, 2/17/00] Also doesn't fail under 110.0.6/(sparc or x86).

 [dbm, 6/11/01] Now doesn't fail under 110.33 (x86-linux, alpha-dunix,
  or sparc-solaris8).  Assumed fixed by some change since 110.25.

Fix:
Test: bug1549.1.sml
Owner: Zhong
Status: fixed (110.33 or earlier)
----------------------------------------------------------------------
Number: 1550
Title: type error message open to misinterpretation
Keywords: 
Submitter: David B. Benson <dbenson@eecs.wsu.edu>
Date: 2/13/00
Version: 110.0.6
System: x86-linux
Severity: quite minor
Problem:
  In the "operator is not a function" type error message, the operator
  type specification might be misconstrued as specifying the operator
  itself.

Transcript:
  - datatype d = A;
  datatype d = A
  - A 3;
  stdIn:26.1-26.4 Error: operator is not a function [tycon mismatch]
    operator: d
    in expression:
      A 3
Fix: 
 [dbm, 2/17/00]
  The message could be made unambiguous by using "operator type" in
  place of "operator", as in

  stdIn:26.1-26.4 Error: operator is not a function [tycon mismatch]
    operator type: d
    in expression:
      A 3
Test:
Owner: dbm
Status: not a bug
----------------------------------------------------------------------
Number: 1551
Title: unexpected behavior with bogus escape sequence in a string
Keywords: strings, escape sequence
Submitter: "Son Vu" <sonvu@uiuc.edu>
Date: 2/10/00
Version: 110.0.6, 110.25
System: -
Severity: minor
Problem: 
  When an improper escape sequence appears in a string literal, an
  "unclosed string" error message occurs (in fact, a pair of such messages
  occurs).
Transcript:
  - val x = "\c";
  stdIn:29.9-29.11 Error: unclosed string
  stdIn:29.12-29.14 Error: unclosed string
  - val x = "\d";
  stdIn:2.4-2.6 Error: unclosed string
  stdIn:2.7-2.9 Error: unclosed string
  - val x = "abc\def";
  stdIn:2.4-2.9 Error: unclosed string
  stdIn:31.3-31.5 Error: unclosed string

Comments:
 [dbm]
  What is the expected treatment of undefined escape sequences?
  Perhaps a more precise error message could be provided (e.g.
  "bad escape sequence in string").

 [jhr, 2/17/00]
  It should report "illegal string escape".  Actually, ml.lex looks like
  it is supposed to do this, but clearly it doesn't for some reason.

Fix:
Test: bug1551.1.sml
Owner: ?
Status: open
----------------------------------------------------------------------
Number: 1552
Title: Nonexaustive match failure during compilation
Keywords: 
Submitter: David B. Benson <dbenson@eecs.wsu.edu>
Date: 2/17/00
Version: 110.0.6
System: x86-linux
Severity: quite minor
Problem: Compiler has a Match failure.
Code: Heap.sml
      OptionQueue.sml
      sources.cm
----------------------------Heap.sml----------begin
(* Heap.sml *)

nonfix == ~= ; val == = (op =) and ~= = (op <>) ; infix 4 == ~= ;
fun id x = x ;

signature PRIORITY_QUEUE =
sig
   structure Priority : REP_KEY
   type 'a heap
   val empty : 'a heap
   val isEmpty : 'a heap -> bool
   val insert : 'a heap -> 'a * Priority.ord_key -> 'a heap
   val min : 'a heap -> ('a GriesBurton.queue * Priority.ord_key) option
   val remove : 'a heap -> 'a heap option
end (* signature PRIORITY_QUEUE *) ;

functor HeapFn(structure Priority : REP_KEY) : PRIORITY_QUEUE =
struct
   structure Priority : REP_KEY = Priority

   open GriesBurton;

   abstype 'a heap = Lf
                   | Br of ('a queue * Priority.ord_key) * 'a heap * 'a heap
   with
   val empty = Lf

   fun isEmpty Lf = true
     | isEmpty _  = false

   local
      fun enqueues(ontoq,fromq) =
             let val fromqXOption = dequeue(fromq)
             in
                if isSome(fromqXOption) then
                   let val (fromq,x) = valOf fromqXOption
                   in
                      enqueues(enqueue(SOME(x,ontoq)),fromq)
                   end
                else ontoq
             end
      fun insert' Lf datas = (print("inserting notequal: "^Priority.toString(priority)^"\n");
                              Br(datas,Lf,Lf)
                             )
        | insert' (Br(v as (xq,priority),t1,t2)) (w as (yq,priority')) =
             let val which = Priority.compare(priority',priority)
             in
                if (which == LESS) then Br(w,insert' t2 v,t1)
                else if (which == EQUAL) then
                        (print("inserting equal: "^Priority.toString(priority)^"\n");
                         Br((enqueues(xq,yq),priority),t1,t2)
                        )
                else (* which == GREATER *)
                   Br(v,insert' t2 w,t1)
             end
   in
   fun insert heap (x,priority) = insert' heap (enqueue(SOME(x,enqueue NONE)),priority)
   end(*local*)

   fun min (Br(data,_,_)) = SOME data
     | min       _        = NONE

   local
      fun leftrem (Br(v,Lf,Lf)) = (v,Lf)
        | leftrem (Br(v,t1,t2)) =
             let val (w,t) = leftrem t1
             in
                (w,Br(v,t2,t))
             end
      fun siftdown (v,Lf,Lf) = Br(v,Lf,Lf)
        | siftdown (w as (_,priority),t as Br(v as (_,priority'),Lf,Lf),Lf) =
             let val which = Priority.compare(priority,priority')
             in
                if (which == LESS) then Br(w,t,Lf)
                else if (which == EQUAL) then raise Fail "Heap.siftdown: EQUAL 1"
                else (* priority > priority' *) Br(v,Br(w,Lf,Lf),Lf)
             end
        | siftdown (w as (_,priority),t1 as Br(v1 as (_,priority1),p1,q1),
                                      t2 as Br(v2 as (_,priority2),p2,q2)) =
             let val w1 = Priority.compare(priority,priority1)
                 val w2 = Priority.compare(priority,priority2)
             in
                if (w1 ~= GREATER) andalso (w2 ~= GREATER) then
                   if (w1 == EQUAL) orelse (w2 == EQUAL) then 
                      raise Fail "Heap.siftdown: EQUAL 2"
                   else  Br(w,t1,t2)
                else
                   let val w12 = Priority.compare(priority1,priority2)
                   in
                      if (w12 == LESS) then Br(v1,siftdown(w,p1,q1),t2)
                      else if (w12 == EQUAL) then raise Fail "Heap.siftdown: EQUAL 3"
                      else (* priority1 > priority2 *)
                         Br(v2,t1,siftdown(w,p2,q2))
                   end
             end
   in
   fun remove Lf = NONE
     | remove (Br(_,Lf,_))  = SOME Lf
     | remove (Br(_,t1,t2)) = SOME(
          let val (w,t) = leftrem t1
          in
             siftdown(w,t2,t)
          end) handle Match => raise Fail "Heap.remove: Match"
   end(*local*)
   end(*abstype*)
end (* functor HeapFn *) ;
----------------------------Heap.sml----------end
----------------------------OptionQueue.sml----------begin
(* OptionQueue.sml *)
(* copyright 2000 by David B. Benson *)
(* licensed under the provisions of the Open Software Foundation license, 2000 Jan 01 *)

nonfix == ~= ; val == = (op =) and ~= = (op <>) ; infix 4 == ~= ;
fun id x = x ;

signature OPTION_QUEUE =
sig
   type 'x queue
   val enqueue : ('x * 'x queue) option -> 'x queue
   val dequeue : 'x queue -> ('x queue * 'x) option
   val toList : 'x queue -> 'x list
end (* signature QUEUE *) ;

structure GriesBurton : OPTION_QUEUE =
struct
   datatype 'x queue = GB of 'x list * 'x list
   fun enqueue  NONE                    = GB([],[])
     | enqueue (SOME(x,GB(front,back))) = GB(front,x::back)
   fun dequeue (GB([],[]))              = NONE
     | dequeue (GB([],back as (x::xs))) = dequeue(GB(rev back, []))
     | dequeue (GB(x::xs,back))         = SOME(GB(xs,back),x)
   fun toList queue =
          let val xqXOption = dequeue queue
          in
             if isSome xqXOption then 
                let val (xq,x) = valOf xqXOption
                in
                   x :: (toList xq)
                end
             else []
          end
end (* structure GriesBurton *) ;
----------------------------OptionQueue.sml----------end
----------------------------sources.cm----------begin
Group

signature PRIORITY_QUEUE
signature OPTION_QUEUE

functor HeapFn

structure GriesBurton

is

smlnj-lib.cm
OptionQueue.sml
Heap.sml
----------------------------sources.cm----------end
Transcript:
----------------------------bug.transcript-------------begin
Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
- CM.make();
[starting dependency analysis]
[scanning sources.cm]
[checking CM/x86-unix/sources.cm.stable ... not usable]
[scanning /hard/local/sml110.0.6/lib/smlnj-lib.cm -> /hard/local/sml110.0.6/src/smlnj-lib/Util/smlnj-lib.cm]
[checking /hard/local/sml110.0.6/src/smlnj-lib/Util/CM/x86-unix/smlnj-lib.cm.stable ... ok - stable]
[parsing OptionQueue.sml]
OptionQueue.sml:5.1-5.13: declaration not tracked by CM
OptionQueue.sml:5.16-5.48: declaration not tracked by CM
OptionQueue.sml:5.51-5.64: declaration not tracked by CM
OptionQueue.sml:6.1-6.13: declaration not tracked by CM
[Creating directory CM/DEPEND ...]
[parsing Heap.sml]
Heap.sml:3.1-3.13: declaration not tracked by CM
Heap.sml:3.16-3.48: declaration not tracked by CM
Heap.sml:3.51-3.64: declaration not tracked by CM
Heap.sml:4.1-4.13: declaration not tracked by CM
[dependency analysis completed]
[compiling OptionQueue.sml -> CM/x86-unix/OptionQueue.sml.bin]
[Creating directory CM/x86-unix ...]
[wrote CM/x86-unix/OptionQueue.sml.bin]
[compiling Heap.sml -> CM/x86-unix/Heap.sml.bin]
Heap.sml:8.4-14.43 Error: unbound signature: REP_KEY
Heap.sml:17.16-17.44 Error: unbound signature: REP_KEY
Heap.sml:19.25-19.32 Error: unbound signature: REP_KEY
Heap.sml:42.78-42.86 Error: unbound variable or constructor: priority

uncaught exception nonexhaustive match failure
  raised at: modules/sigmatch.sml:845.14
             modules/sigmatch.sml:884.25
             modules/sigmatch.sml:966.24
             elaborate/elabmod.sml:1223.8
             elaborate/elabmod.sml:1328.33
             util/stats.sml:164.40
             sched/recompile.sml:206.38-206.41
- 
----------------------------bug.transcript-------------end
Comments: This version of the standard heap code is seriously broken, but
          the bug issue is only the small matter of the compiler giving up.
          Correcting the sources.cm to locate REP_KEY and fixing the
          problem on line 42 resulted in the compiler generating code,
          but this isn't a priority queue implementation!
Fix: 
Test:
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1553
Title: "dependency cycle in instantiate" insufficiently informative
Keywords: signatures, sharing, rigid types, error messages
Submitter: David B. Benson <dbenson@eecs.wsu.edu>
Date: 2000 Feb 18
Version: 110.0.6
System: x86-linux
Severity: minor
Problem:
  With a 109 line signature, it will be difficult to
  determine the problem -- which ought not exist
  as this is a minor variation on a signature
  for the basis library. [see line marked bug BUG]
  (It appears that this might be an actual bug
  in sml110.0.6, since the marked line occurs
  in the basis library signature.)
Code:
  structure S :
    sig
      type flags
      val toWord : flags -> Word32.word
      val fromWord : Word32.word -> flags
      val flags : flags list -> flags
      val allSet : flags * flags -> bool
      val anySet : flags * flags -> bool
      type mode = flags
      val irwxu : mode
      val irusr : mode
      val iwusr : mode
      val ixusr : mode
      val irwxg : mode
      val irgrp : mode
      val iwgrp : mode
      val ixgrp : mode
      val irwxo : mode
      val iroth : mode
      val iwoth : mode
      val ixoth : mode
      val isuid : mode
      val isgid : mode
      (**** Comment out the following line to obtain a compilation.  bug BUG ****)
      sharing type flags = mode
    end

Transcript:
  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
  - [starting dependency analysis]
  [scanning sources.cm]
  [checking CM/x86-unix/sources.cm.stable ... not usable]
  [dependency analysis completed]
  [recovering CM/x86-unix/LittleChi.sml.bin... done]
  [recovering CM/x86-unix/Path.sml.bin... done]
  [compiling PosixPath.sml -> CM/x86-unix/PosixPath.sml.bin]
  PosixPath.sml:8.1-118.4 Error: dependency cycle in instantiate

  !* CM error: compile: elaboration failed

Comments:
 [dbm, 2/21/00]
  Thanks for the bug report (#1553). You are right that the error message is
  not informative, and we should fix this somehow.  In my opinion
  (though maybe not in Mads Tofte's) there is an actual
  problem with your code.  You have a signature

    structure S :
      sig
	type flags
	...
	type mode = flags
	...
	(**** Comment out the following line to obtain a compilation.  bug BUG ****)
	sharing type flags = mode
      end

  In SML '97, one can't have a sharing constraint involving a "rigid"
  type (one which has an explicit definition).  My interpretation is
  that 

    type mode = flags

  makes mode a "rigid" type, and therefore it can't appear in a sharing
  spec (the error message should say this clearly).  Mads Tofte's
  interpretation is that an "identity" spec like that for mode doesn't
  count as a rigid type, it has to be something like

    type mode = int * flag

  where the rhs is not a simple type identifier.  I find this pedantic.

  You could argue that your redundant specifications (in the mode type
  spec and the sharing spec) are consistent with one another and should
  be allowed, but dealing with consistent but redundant specs in full
  generality would be a fairly major hassle, for little or no gain.

  So I consider this a cosmetic bug relating to the obscurity of the
  error message.

 [dbm, 2/21/00]
  The signature above was derived by doing

    - open Posix.FileSys;

  and capturing the printout.  Thus the signature prettyprinting
  code is producing bogus signatures that cannot serve as valid 
  input to the compiler.  This should be fixed.

Fix: 
Test: bug1553.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1554
Title: CM stale cache problem
Keywords: CM
Submitter: Norman Ramsey <nr@eecs.harvard.edu>
Date: 2/18/00
Version: 110.0.6
System: -
Severity: minor 
Problem: 
  When I ask CM to make' a file that no longer exists, but that existed
  earlier, it uses the version in its cache instead of complaining that
  the version on disk has been removed.  For example,
  I got this message even though there is no primop.cm:

  !* CM error: ML file NW/primop.sml occurs in more than one group: absrtl.cm, pr
  imop.cm

Comments:
 [Matthias, 2/22/00]
  While I don't think it will be easy to fix in 110.0.x, this sort of
  thing should not occur anymore in the new CM.
Fix:
Test: -
Owner: Matthias
Status: fixed in 110.20 (?)
----------------------------------------------------------------------
Number: 1555
Title: should check for degenerate sharing
Keywords: signatures, sharing constraints
Submitter: John Reppy
Date: 2/25/00
Version: 110.x
System: -
Severity: minor
Problem: 
  A degenerate sharing constraint like

    sharing T = T

  should generate a warning.

Comments:
Fix:
Test: bug1555.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1556
Title: signal race condition
Keywords: signals, interval timer
Submitter: Allen Stoughton <allen@cis.ksu.edu>
Date: 3/1/2000
Version: 110.0.6 (and earlier and later)
System: various unix
Severity: major
Problem: 
  A simple program using I/O and the interval timer causes an
  uncaught Match exception.

Code:

  structure Test =
  struct

  fun print s =
	(Signals.maskSignals Signals.MASKALL;
	 TextIO.print s;
	 Signals.unmaskSignals Signals.MASKALL)

  fun handler(_, _, k) = k

  fun loop() = (print "."; loop())

  fun doit() =
	let val slice = Time.fromMilliseconds 50
	in Signals.setHandler(Signals.sigALRM, Signals.HANDLER handler);
	   SMLofNJ.IntervalTimer.setIntTimer(SOME slice);
	   loop()
	end

  end;

Transcript:
  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload 
  enabled]
  - - use "test.sml";
  [opening test.sml]
  GC #0.0.0.0.1.6:   (10 ms)
  structure Test :
    sig
      val doit : unit -> 'a
      val handler : 'a * 'b * 'c -> 'c
      val loop : unit -> 'a
      val print : string -> unit
    end
  val it = () : unit
  - Test.doit();
  stdIn:18.1-18.12 Warning: type vars not generalized because of
     value restriction are instantiated to dummy types (X1,X2,...)
  ...............................................................................
  ...............................................................................
  ...............................................................................
  ...............................................................................
  ...............................................................................
  .............................
  /usr/local/bin/sml: Fatal error -- Uncaught exception Match with 0
   raised at boot/NJ/internal-signals.sml:287.30
Comments:
 [jhr, 3/1/2000]
  Caused by a race condition in the code that sets masking/unmasking
  of signals.
Fix:
  New version of file sml-nj/boot/NJ/internal-signals.sml (in 110.0.x, or
  system/Basis/Implementation/NJ/internal-signals.sml in 110.26).
Test: (test code would loop in absence of bug)
Owner: jhr
Status: fixed in 110.0.7, 110.0.26+
----------------------------------------------------------------------
Number: 1557
Title: OS.Path.toString raises no exception InvalidArc; InvalidArc not implemented
Keywords: 
Submitter: David B. Benson <dbenson@eecs.wsu.edu>
Date: 2000 Feb 13
Version: 110.0.6
System: x86-linux
Severity: quite, quite minor
Problem:
  bad paths are translated to strings by OS.Path.toString.
  The documentation of OS.Path claims an exception InvalidArc
  which is not implemented.
  The documentation states that this exception is raised by 
  OS.Path.toString.
  Is the implementation or the documentation correct?
Code: NONE, see transcript
Transcript:
  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
  - OS.Path.Path;
  val it = Path(-) : exn
  - val badpath = {isAbs=false,vol="",arcs=["a/b"]};
  val badpath = {arcs=["a/b"],isAbs=false,vol=""} : {arcs:string list, isAbs:bool, vol:string}
  - val pathString = OS.Path.toString{isAbs=false,vol="",arcs=["a/b"]};
  val pathString = "a/b" : string
  - val path = OS.Path.fromString pathString;
  val path = {arcs=["a","b"],isAbs=false,vol=""} : {arcs:string list, isAbs:bool, vol:string}
  - if ( path = badpath ) then print "EQUAL" else print "VIOLATION";
  VIOLATIONval it = () : unit
  - OS.Path.InvalidArc;
  stdIn:6.1-6.19 Error: unbound variable or constructor: InvalidArc in path OS.Path.InvalidArc
  - 
Comments: 
 [jhr, 2/27/2000]
  Probably the documentation.
Fix: 
  Correct the documentation(?).
Test:
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1558
Title:       Char.isCntrl #"\ddd" where ddd >= 128 should be true
Keywords:    Char.isCntrl
Submitter:   Stephen Weeks <sweeks@acm.org>
Date:        03/17/00
Version:     110.9.1
System:      x86-linux
Severity:    
Problem:     

Char.isCntrl #"\ddd" where ddd >= 128 should be true.  It currently
is false.  This behavior is also inconsistent with the Basis Library
Spec, which states that Char.isCntrl is equivalent to 
not o Char.isPrint.

- Char.isCntrl #"\128";
val it = false : bool
- Char.isPrint #"\128";
val it = false : bool

Code:        
Transcript:  
Comments:    
 [jhr, 4/10/00]
  We have resolved that this bug is a mistake in the specification.  The
  Char.isCntrl predicate should return true for ASCII control characters,
  so the SML/NJ implementation is correct.  There will be a new version
  of the Basis specification out RSN, which will correct this mistake.
Fix:         
  Amend Basis documentation.
Test: *
Owner: jhr
Status: specification bug
----------------------------------------------------------------------
Number: 1559
Title: non-empty string matches regular expression only in a non-empty way
Keywords: Regexp, DFA backend
Submitter: Ed Osinski   osinski@cs.nyu.edu
Date: 03/30/00
Version: 110.0.6
System: Any/All Solaris 2.6
Subsystem: SML/NJ Library
Severity: minor
Problem:
Using the DFA backend, a non-empty string will never generate 
an empty match with a regular expression.  For example, the string "a"
will not match regular expression "(ab)?", but the string ""
will.
Code:
structure Test = 
struct

    structure RegExp = RegExpFn (structure P = AwkSyntax
                                 structure E = DfaEngine)
                       
    fun scanString s = (case String.size s of
                            0 => NONE
                          | 1 => SOME (String.sub (s, 0), "")
                          | _ => SOME (String.sub (s, 0), 
                                       String.extract (s, 1, NONE)))

    fun test regStr str = 
        (case RegExp.prefix (RegExp.compileString regStr) scanString str of
             SOME (MatchTree.Match (SOME {pos,len}, _), src') => 
                 let fun readN src 0 cs = String.implode (rev cs)
                       | readN src n cs = 
                         let val (c,src') = Option.valOf (scanString src)
                         in  readN src' (n-1) (c::cs)
                         end
                 in  SOME (readN pos len [], src')
                 end
           | NONE                                             => NONE)

end
Transcript:
$ sml
Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
- CM.make ();
...
- open Test;
...
- test "(ab)?" "";
val it = SOME ("","") : (string * string) option
- test "(ab)?" "ab";
val it = SOME ("ab","") : (string * string) option
- test "(ab)?" "ac";
val it = NONE : (string * string) option
- test "(ab)?" "x";
val it = NONE : (string * string) option
Comments:
The problem seems to be that once it is determined that the string to
be matched is non-empty, attempting to perform an empty match are
irrevocably abandoned.
Fix:
I think the following is a fix, involving only the `loop' function in
dfa-engine.sml:

diff dfa-engine.sml dfa-engine.sml.orig:

--------------------------------------------------------------------------
28c28
<               fun loop (state,p,inits,lastAccepting) = 
---
>               fun loop (state,p,inits,lastP,lastS,lastN) = 
30c30
<                      of NONE        => lastAccepting
---
>                      of NONE => (lastP,lastS,lastN)
33c33
<                             of NONE       => lastAccepting
---
>                             of NONE => (lastP,lastS,lastN)
36,45c36,37
<                                   of SOME n => loop (new,p+1,s',
<                                                        SOME (p+1,s',n))
<                                    | NONE   => loop (new,p+1,s',
<                                                        lastAccepting)))
<                 fun try0 stream = 
<                     (case (accepting 0)
<                       of SOME n => SOME (n,
<                                          M.Match (SOME {pos=stream,len=0},[]),
<                                          stream)
<                        | NONE   => NONE)
---
>                                   of SOME n => loop (new,p+1,s',p+1,s',n)
>                                    | NONE => loop (new,p+1,s',lastP,lastS,lastN)))
48,56c40,53
<                 of NONE        => try0 stream
<                  | SOME (c,s') => 
<                          (case loop (0,p,stream,NONE)
<                            of NONE             => try0 stream
<                             | SOME (last,cs,n) => 
<                                   SOME (n, 
<                                         M.Match (SOME {pos=stream, len=last-p},
<                                                  []),
<                                         cs))
---
>                 of NONE => (case (accepting 0)
>                               of SOME n => SOME (n,M.Match (SOME {pos=stream,len=0},[]),stream)
>                                | NONE => NONE)
>                  | SOME (c,s') =>
>                     if (canStart c) 
>                         then let val (last,cs,n) = loop (0,p,stream,~1,stream,0)
>                              in
>                                  if (last<0) 
>                                      then NONE
>                                  else SOME (n,M.Match (SOME {pos=stream,
>                                                              len=last-p},
>                                                        []),cs)
>                              end
>                     else NONE 
--------------------------------------------------------------------------

Test: 
Owner: Riccardo
Status: open
----------------------------------------------------------------------
Number: 1560
Title: Compiler bug: Reconstruct: rator in profiling mode
Keywords: profiler, compiler bug
Submitter: Larry Paulson <Larry.Paulson@cl.cam.ac.uk>
Date: 3/21/00
Version: 110.0.3
System: x86-linux
Severity: medium
Problem: 
  I added the line

	  Compiler.Profile.setProfMode true;

  to line 21 of Pure/ML-Systems/smlnj.ML, and compiled with Version 110.0.3, 

  I tried to recompile by

Code: isabelle
Transcript:
  perch: cd HOL
  /homes/lcp/isabelle/Repos/HOL

  perch: nice isatool make
  make[1]: Entering directory `/Nfs/heaton/usr28/lcp/isabelle/Repos/Pure'
  Building Pure ...
  Finished Pure (0:04:30 elapsed time)
  make[1]: Leaving directory `/Nfs/heaton/usr28/lcp/isabelle/Repos/Pure'
  Building HOL ...
  HOL FAILED
  (see also /homes/lcp/isabelle/heaps/smlnj-110/log/HOL)

			    -> theory
			       -> theory * thm list list * thm list list
				  * thm list list * DatatypeAux.simproc_dist list
				  * thm
    end
  Error: Compiler bug: Reconstruct: rator
  *** Error
  *** At command "theory" (line 5 of "/Nfs/heaton/usr28/lcp/isabelle/Repos/HOL/In
  ductive.thy").
Comments:
  [dbm] Not yet reproduced here.
Fix:
Test: -
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1561
Title: modulo operator (mod) causes a crash on Alpha
Keywords: mod
Submitter: Hongwei Xi  <hwxi@ececs.uc.edu>
Date: 04/14/00
Version: 110.0.3
System: Alpha, ** linux **
Subsystem: SML basis library
Severity: major
Problem:
  Do the following

    4 mod 2;

  And you get:

    Fatal error: unexpected fault, signal = 8, code = 0
Code:
  4 mod 2;

Transcript:
  Fatal error: unexpected fault, signal = 8, code = 0

Comments:
 [jhr, 4/14/00]
  Works ok in 110.0.6.
 [Lal, 4/14/00]
  I just discovered that this is an alpha running Linux; a port that was 
  done by one of the local systems people.
Fix:
Test: 
Owner: Lal
Status: open?
----------------------------------------------------------------------
Number: 1562
Title: CM complains about unrecognized file extension ".fun"
Keywords: CM, file extensions, CM plug-ins
Submitter: Simon Helsen <helsen@informatik.uni-freiburg.de> 
Date: 4/20/00
Version: 110.27
System: -
Severity: minor
Problem: 
  CM tries to load a library (fun-ext.cm) which is not there.

Transcript:
  ...
  [parsing ./library/array/../basic/pair.sig]
  [attempting to load plugin fun-ext.cm]
  [scanning ./library/array/../basic/fun-ext.cm]
  [unable to load plugin fun-ext.cm]
  [parsing ./library/array/../basic/pair.fun]
  ...

  It tries to load fun-ext.cm several times.

Comments:
 [Matthias, 4/20/00]
  My guess is that Simon has a file named <something>.fun in his pe system.
  CM does not know about a filename extension "fun", so it goes and tries to
  load a tool for it.  After failing to find one, it falls back to the old
  behavior of treating unknown files as ML files...

  The solution is to rename the file to <something>.sml or to add an explicit
  class specification:

      <something>.foo : sml

  Another solution would be to make a "fun-ext.cm" tool class that, when
  loaded, has the effect of registering "fun" as an extension that maps to
  the "sml" class...  In this case I think that would be overkill, though.

 [Simon Helsen, 4/25]
  yes, I have loads of files which have extension ".fun". Every file in my
  system contains either a signature (.sig) a structure (.sml) or a functor
  (.fun) This distinction is very practical and I don't want to change that.
  So, you are saying that to solve this, I have to add "blabla.fun : sml"
  for every blabla functor? I don't think this is an improvement for CM. I
  understand you can't make an exception just for my convention (which is
  actually Steven Weeks' convention - he uses this in his MLTon compiler),
  but it would be nice if I could tell CM at just one place that extensions
  .fun should be treated like .sig or .sml

Fix:
  .fun added to the set of extensions that imply class sml
Test:
Owner: Matthias
Status: fixed in 110.28
----------------------------------------------------------------------
Number: 1563
Title: redundant pathconfig contents with multiple builds
Keywords: CM, pathconfig, installation
Submitter: Dave MacQueen
Date: 4/27/00
Version: 110.27
System: -
Severity: medium
Problem: 
  If installation is performed for several architectures in the
  same directory, multiple redundant copies of the pathconfig
  contents are created in the lib/pathconfig file.
Code:
Transcript:
Comments:
  Fortunately, the contents don't vary with platform, so the path
  config bindings all agree.
Fix:
Test:
Owner: Matthias
Status: open
----------------------------------------------------------------------
Number: 1564
Title: signature prettyprinting not correct
Keywords: pretty printing, signatures, modules
Submitter: Dave MacQueen
Date: 5/1/2000
Version: 110.27
System: -
Severity: medium 
Problem: 
  When the top level prints signatures, the "end" keywords are not
  lined up with the corresponding "sig".
Code:
Transcript:
arran$ sml
  Standard ML of New Jersey v110.27 [FLINT v1.5], April 10, 2000
  - use "tests/bug1420.1.sml";
  [opening tests/bug1420.1.sml]
  signature CAT = sig eqtype cat
		      val c : cat end
  signature L_F =
    sig eqtype t
	structure Cat : sig type cat = t
			    val c : cat end
	val r : t end
  signature S =
    sig
      structure Cat : sig eqtype cat
			  val c : cat end
      structure LF : sig eqtype t
			 structure Cat : <sig>
			 val r : t end
    end
  val it = () : unit
  - 
  arran$ /home/sml/Versions/110.9.1/bin/sml
  Standard ML of New Jersey v110.9.1 [FLINT v1.41], October 19, 1998 [CM; autoload enabled]
  - use "tests/bug1420.1.sml";
  [opening tests/bug1420.1.sml]
  signature CAT =
    sig
      eqtype cat
      val c : cat
    end
  signature L_F =
    sig
      eqtype t
      structure Cat :
	sig
	  type cat = t
	  val c : cat
	end
      val r : t
    end
  signature S =
    sig
      structure Cat :
	sig
	  eqtype cat
	  val c : cat
	end
      structure LF :
	sig
	  eqtype t
	  structure Cat : <sig>
	  val r : t
	end
    end

Comments:
  Probably caused by the replacement of the old Compiler.PrettyPrint
  by its emulation using the smlnj-lib prettyprinter.  Possibly a bug
  in the emulation of the old prettyprinter.

Fix:
Test: bug1420.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1565
Title: Overflow exception while loading IntInf
Keywords: IntInf
Submitter: Daniel C. Wang   danwang@cs.princeton.edu
Date: 05/18/00
Version: 110.0.6
System: x86 Other (describe below) Windows 98
Subsystem: SML/NJ Library
Severity: major
Problem:
  Using the most recent self-installing executable 
  (I downloaded it last night) any code that uses IntInf from the SML-NJ 
  library dies with an exception when loading the code.


Code:
  --sources.cm--
  Group is
  smlnj-lib.cm
  test.sml
  ----test.sml--
  val x =  IntInf.+(IntInf.fromInt 1,IntInf.fromInt 2)

Transcript:
  - CM.make();
  ...
  [recovering c:\local\src\src\smlnj-lib\Util\CM\x86-win32\int-inf-sig.sml.bin... done]
  [recovering c:\local\src\src\smlnj-lib\Util\CM\x86-win32\int-inf.sml.bin...GC #0.0.0.1.3.71:   (0 ms)
   done]

  !* CM error: c:\local\src\src\smlnj-lib\Util\int-inf.sml: exception raised in user code

  uncaught exception overflow
    raised at: <file c:\local\src\src\smlnj-lib\Util\int-inf.sml>
	       util/stats.sml:164.40

Comments:
  The reference to util/stats.sml suggests that this bug is related 
  to the profiling code. Perhaps the smlnj-lib was shipped with profiling 
  turned on? 

  In fact destablizing the library and recompiling int-inf.sml seems 
  to solve the problem.
Fix:
  Recompile the libraries with the shiped compiler. 
Test: 
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1566
Title: GetOpt library not handling option parameters
Keywords: GetOpt, command line
Submitter: Fermin Reig <reig@dcs.gla.ac.uk>
Date: 5/31/00
Version: 110.?
System: -
Severity: medium 
Problem: 
  I've observed the following when using the GetOpt library:

	  prog -o /tmp/foo.out ....

  The string that getOpt returns is " /tmp/foo.out", including leading
  white space. In the example above, I get a "SysErr: No such file or
  directory", whereas everything works fine if I type:

	  prog -o/tmp/foo.out ....

  man getopt says that required arguments can be separated by white
  space:

	 A simple short option is a `-' followed by a short option character. If
	 the  option  has  a required argument, it may be written directly after
	 the option character or as the next parameter (ie. separated by whites-
	 pace  on  the command line). If the option has an optional argument, it
	 must be written directly after the option character if present.
Comments:
 [jhr, 6/22/00]
  I've looked into this bug, and I cannot reproduce your problem.
  In fact, looking at the GetOpt code, the only explanation I can think
  of for this problem is a bug in the shell script that you are using
  to invoke your sml program.  Specifically, I suspect that the

	  -o /tmp/foo.out

  is getting passed to sml as a single argument, instead of as two
  distinct arguments.  If that is the case, then seeing the leading
  space on /tmp/foo.out is the desired behaviour.

 [Riccardo, 6/22/00]
  I concur with John. If "-o /tmp/foo.out" would be passed to sml as two 
  arguments, then the separating white space would have been eaten by
  the code to transform the command-line into a list of strings, and it
  would have been passed to GetOpt as two different elements in the
  list, with no leading whitespace (which works for options with
  required arguments). 

  John: it may be good to change the header comment in getopt-sig.sml to
  reflect the fact that now we don't use exceptions to  report errors
  anymore but rely on a errFn provided to getOpt, and to also reflect
  that in the comment after the signature of the getOpt function. (I'm
  look at version 110.0.6 of smlnj-lib).    - R
Owner: jhr
Status: not a bug
----------------------------------------------------------------------
Number: 1567
Title:       Error: Compiler bug: InlInfo: Wrong field in INL_STR !
Keywords:    elabmod, signature
Submitter:   Allyn Dimock <dimock@deas.harvard.edu>
Date:        06/13/00
Version:     110.05
System:      -
Severity:    major
Problem:
  In compiling a file with multiple errors,
  just after an error diagnostic about the input:
  Error: value type in structure doesn't match signature spec
  message, the compiler prints:

Error: Compiler bug: InlInfo: Wrong field in INL_STR !
             SML/NJ hangs waiting for input, then when <CR> is pressed
             prints
uncaught exception Error
  raised at: util/errormsg.sml:54.14-54.19
             elaborate/elabmod.sml:1223.8
             util/stats.sml:164.40
             sched/recompile.sml:206.38-206.41
- Error: Compiler bug: InlInfo: Wrong field in INL_STR !
             and returns to command loop.

             Repeating with the same input yields the same error
             except for no pause between error message and exception backtrace.

             Partial fix to errors in the source file yields same SML/NJ
             error after: Error: constructor and argument don't agree.

             fixing the following error in the source code caused SML/NJ
             to report all remaining errors in the source code and return
             correctly with !* CM error: compile: elaboration failed
../reps/TypInfST.sml:7.3-119.2 Error: duplicate specifications for variable or constructor multiAbs in signature
change in signature to fix:
  val multiAbs : TypeVariable.tVar list -> Typ -> Typ
  val multiAbs : Typ list -> Typ -> Typ
to
  val multiAbs : TypeVariable.tVar list -> Typ -> Typ
  val multiApp : Typ list -> Typ -> Typ


Code:        If you need it, remind me to send you the buggy version of
             TypInfSt.sml and all files that it depends on.
Transcript:  
Standard ML of New Jersey, Version 110.0.5, September 1, 1999 [CM&CMB]
- CM.make'("../reps/TypInfST.cm");
[starting dependency analysis]
[scanning ../reps/TypInfST.cm]
[checking ../reps/CM/sparc-unix/TypInfST.cm.stable ... not usable]
...
[recovering ../../src/minimal-graph/stable/CM/sparc-unix/minimal-graph-fn-jef.sml.bin... done]
[recovering ../reps/CM/sparc-unix/TypeDataDefns.sml.bin... done]
[compiling ../reps/TypInfST.sml -> ../reps/CM/sparc-unix/TypInfST.sml.bin]
../reps/TypInfST.sml:26.25-26.29 Error: unbound type constructor: fVar
../reps/TypInfST.sml:66.23-66.27 Error: unbound type constructor: fVar
../reps/TypInfST.sml:7.3-119.2 Error: duplicate specifications for variable or constructor multiAbs in signature
../reps/TypInfST.sml:339.26-339.29 Error: unbound type constructor: Typ
../reps/TypInfST.sml:338.24-338.27 Error: unbound type constructor: Typ
../reps/TypInfST.sml:325.37-325.40 Error: unbound type constructor: Typ
../reps/TypInfST.sml:325.26-325.29 Error: unbound type constructor: Typ
../reps/TypInfST.sml:323.35-323.38 Error: unbound type constructor: Typ
../reps/TypInfST.sml:317.59-317.62 Error: unbound type constructor: Typ
../reps/TypInfST.sml:317.43-317.46 Error: unbound type constructor: Typ
../reps/TypInfST.sml:304.37-304.40 Error: unbound type constructor: Typ
../reps/TypInfST.sml:298.65-298.68 Error: unbound type constructor: Typ
../reps/TypInfST.sml:296.67-296.70 Error: unbound type constructor: Typ
../reps/TypInfST.sml:294.51-294.54 Error: unbound type constructor: Typ
../reps/TypInfST.sml:292.52-292.55 Error: unbound type constructor: Typ
../reps/TypInfST.sml:291.36-291.39 Error: unbound type constructor: Typ
../reps/TypInfST.sml:291.27-291.30 Error: unbound type constructor: Typ
../reps/TypInfST.sml:956.11-998.51 Error: constructor and argument don't agree in pattern [tycon mismatch]
  constructor: {fvar:fVar, tags:Label list, types:_ list} -> typm
  argument:    {fvar:'Z, tag:'Y, tags:'X, types:'W}
  in pattern:
    VariantType {fvar=fvar,tag=tag,tags=tags,types=types}
../reps/TypInfST.sml:956.11-998.51 Error: constructor and argument don't agree in pattern [tycon mismatch]
  constructor: {fvar:fVar, tags:Label list, types:_ list} -> typm
  argument:    {fvar:'Z, tag:'Y, tags:'X, types:'W}
  in pattern:
    UnionType {fvar=fvar,tag=tag,tags=tags,types=types}
Error: Compiler bug: InlInfo: Wrong field in INL_STR !

uncaught exception Error
  raised at: util/errormsg.sml:54.14-54.19
             elaborate/elabmod.sml:1223.8
             util/stats.sml:164.40
             sched/recompile.sml:206.38-206.41
- 
Comments:    
Fix:         
Test: 
Owner: dbm, Zhong
Status: open
----------------------------------------------------------------------
Number: 1568
Title: installing under digital unix (tru64) 5.0
Keywords: installation, digital unix
Submitter: Yichen Xie <yichen.xie@yale.edu>
Date: 6/14/00
Version: 110.28?
System: alpha32, dunix (5.0)
Severity: major
Problem: 
  Using the configuration for dgux 4.0d, sml fails during installation (when
  trying to write heap image, I think) with:

  /home/xie/sml2/bin/.run/run.alpha32-dunix: Fatal error -- unexpected
  fault, signal = 8, code = 0x1
  config/install.sh !!! Boot code failed, no heap image (sml.alpha32-dunix).

  The reason turns out to be that dgux 5.0 handles SIGFPE differently as for
  dgux 4.0*. Instead of sending FPE_INTOVF_FAULT (0xf), the system sends
  FPE_INTOVF_TRAP (0x1) when there's an integer overflow.

Comments:
Fix:
  The fix is to replace FPE_INTOVF_FAULT w/ FPE_INTOVF_TRAP in
  runtime/mach-dep/signal-sysdep.h. Or (unrecommended) do

	      #  sysconfig -r generic use_faulty_fpe_traps=1

  as root. Of course, the following line also needs to be added to
  config/_arch-n-opsys undef the OSF1) case:

	    V5.*) ARCH=alpha32; OPSYS=dunix ;;

  Relevant portion of /usr/include/machine/signal.h is attached below.

  Yichen

  /usr/include/machine/signal.h
  =============================

  /* FPE signal code usage note:  In some previous releases, FAULT codes
  were incorrectly used when TRAP codes should have been.  But, both then
  and now, true TRAPs and FAULTs could be distinguished by comparing the
  sc_pc and the sc_trap_pc fields of the signal context block.  With a true
  FAULT, the sc_pc field contains the trigger PC of the faulting
  instruction.  With a true TRAP, sc_pc contains the trap PC where the
  exception was realized (and so it will be the same as sc_fp_trap_pc).
  See the ieee(3) man page for details.

  To continue from a FAULT (with the default IEEE result for the
  exceptional operation), a signal handler might look something like:

      void fpe_handler(int sig, int code, struct sigcontext *scp)
      {
	  . . . .
	  if (scp->sc_pc != scp->sc_fp_trap_pc)
	      scp->sc_pc += 4;
	  . . . .
      }

  If it is a true FAULT, incrementing sc_pc by 4 is necessary to advance
  the PC beyond the exceptional instruction.  (Or, the handler could
  correct the exceptional condition and allow the faulting instruction to
  re-execute).

  For existing executables which cannot handle correct TRAP codes, the old,
  incorrect behavior of always using FAULT codes can be restored by setting
  a configurable system parameter:

      #  sysconfig -r generic use_faulty_fpe_traps=1

  which will cause the system to continue to incorrectly use FAULT codes
  when TRAP codes should be produced.  */

Test:
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1569
Title: segfault in BuildLiterals
Keywords: runtime
Submitter: Daniel C. Wang   danwang@cs.princeton.edu
Date: 06/15/00
Version: 110.28
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: major
Problem:
  A bug in src/runtime/build-literals.c causes the runtime to segfault
  when the first generation is set to a size less than 64k.

Code:
  Load some code with @SMLalloc=x
  for x < 64k

Comments:
  I've tested a fix that sets availspace to the actual amount of free
  space and it seems to work, but perhaps an expert can do a better job
  of it.

 [Matthias, 6/15/00]
  I am the one who set alloc to 32k on Celerons.  This is because I
  found that my Celeron at home runs fastest this way. (Tiny
  second-level cache.)  When I did this, I also noticed that the boot
  sequence crashes when (at bootstrap time) alloc is set so low.  But I
  never saw a crash once the system had already booted.  That's why the
  boot scripts (install.sh, makeml) do not set alloc to such a low
  value.

  Anyway, a fix is highly appreciated.  Performance on Celerons really
  hurts when alloc is set higher.

 [jhr, 6/19/00]
  The proposed fix is not quite right.  If you are trying to support
  heaps smaller than 64Kb (68Kb actually), then you should use the heap
  size as the argument to NeedGC.

Fix:
  The bogus code is in line: 100 (of latest CVS version)
  if (NeedGC(msp, 64*ONE_K))
    InvokeGCWithRoots (msp, 0, (ml_val_t *)&lits, &stk, NIL(ml_val_t *));
  availSpace = 64*ONE_K;

  This code incorrectly assumes the available space after the GC is equal to
  the requested 64*k which isn't true if the first generation size is 
  set to less than 64k.

  BTW On Linux boxes running on Celerons the current .run-sml script 
  sets @SMLalloc=32k by default.

  Here's a patch against the latest CVS sources. It be nice if you could
  verify it fixes the problems you noticed. I ran into the bug when trying to
  compile the C-- compiler with the version 110.28. If I only new what
  BuildLiterals did, maybe I could construct a smaller test program to
  exercise the bug. In anycase here's the patch

Index: gc/build-literals.c
===================================================================
RCS file: /home/cvs/sml-dist/src/runtime/gc/build-literals.c,v
retrieving revision 1.2
diff -c -r1.2 build-literals.c
*** gc/build-literals.c	2000/06/01 18:33:49	1.2
--- gc/build-literals.c	2000/06/15 15:22:18
***************
*** 97,105 ****
  	ASSERT(pc < len);
  	availSpace -= 3*WORD_SZB;	/* space for stack cons cell */
  	if (availSpace < ONE_K) {
! 	    if (NeedGC(msp, 64*ONE_K))
! 		InvokeGCWithRoots (msp, 0, (ml_val_t *)&lits, &stk, NIL(ml_val_t *));
  	    availSpace = 64*ONE_K;
  	}
  	switch (lits[pc++]) {
  	  case I_INT:
--- 97,108 ----
  	ASSERT(pc < len);
  	availSpace -= 3*WORD_SZB;	/* space for stack cons cell */
  	if (availSpace < ONE_K) {
! 	  if (NeedGC(msp, 64*ONE_K)) {
! 	    InvokeGCWithRoots (msp, 0, (ml_val_t *)&lits, &stk, NIL(ml_val_t *));
! 	    availSpace = GCSpaceFree(msp);
! 	  } else {
  	    availSpace = 64*ONE_K;
+ 	  }
  	}
  	switch (lits[pc++]) {
  	  case I_INT:
Index: gc/call-gc.c
===================================================================
RCS file: /home/cvs/sml-dist/src/runtime/gc/call-gc.c,v
retrieving revision 1.3
diff -c -r1.3 call-gc.c
*** gc/call-gc.c	2000/06/01 18:33:49	1.3
--- gc/call-gc.c	2000/06/15 15:22:18
***************
*** 354,359 ****
--- 354,369 ----
  
  } /* end of NeedGC */
  
+ Word_t GCSpaceFree (ml_state_t *msp)
+ {
+   Word_t nbytes;
+ #if defined(MP_SUPPORT) 
+      nbytes = ((Addr_t)(msp->ml_limitPtr)) - ((Addr_t)(msp->ml_allocPtr));
+ #else
+      nbytes = ((Addr_t)HEAP_LIMIT(msp->ml_heap)) - ((Addr_t)(msp->ml_allocPtr));
+ #endif
+      return nbytes;
+ }
  
  #ifdef SOFT_POLL
  /* ResetPollLimit:
Index: include/gc.h
===================================================================
RCS file: /home/cvs/sml-dist/src/runtime/include/gc.h,v
retrieving revision 1.2
diff -c -r1.2 gc.h
*** include/gc.h	2000/06/01 18:33:50	1.2
--- include/gc.h	2000/06/15 15:22:18
***************
*** 19,24 ****
--- 19,25 ----
  extern void InvokeGC (ml_state_t *msp, int level);
  extern void InvokeGCWithRoots (ml_state_t *msp, int level, ...);
  extern bool_t NeedGC (ml_state_t *msp, Word_t nbytes);
+ extern Word_t GCSpaceFree(ml_state_t *msp);
  
  extern int GetObjGen (ml_val_t obj);
  extern ml_val_t RecordConcat (ml_state_t *msp, ml_val_t r1, ml_val_t r2);

Test: 
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1570
Title:       RecoverLty exception
Keywords:    RecoverLty, mutually recursive functions
Submitter:   Matthias Blume <blume@kurims.kyoto-u.ac.jp>
Date:        2000/06/23 11:15:00 JST
Version:     110.28.1
System:      ALL
Severity:    critical
Problem:

This concerns 110.28.1 + recent CVS updates (on the main trunk).
The CVS tag is blume-20000619-manual.

The problem is that the compiler dies with an exception RecoverLty
when compiling a certain set of mutually recursive functions.
This seems to be a FLINT problem.  There is a "flint.core" file
afterwards.

The sample code (see below) implements a glorified factorial function.
(It serves as a test case for my new BTrace stuff.)

Code:

  structure X = struct
      fun main n = let
	  fun a (x, 0) = d x
	    | a (x, n) = b (x, n - 1)
	  and b (x, n) = c (x, n)
	  and c (x, n) = a (x, n)
	  and d x = e (x, 3)
	  and e (x, 0) = f x
	    | e (x, n) = e (x, n - 1)
	  and f 0 = 1
	    | f n = n * g (n - 1)
	  and g n = a (n, 3)
      in
	  f n
      end
  end

Transcript:

  Standard ML of New Jersey v110.28.1 [FLINT v1.5], June 5, 2000
  - use "x.sml";
  [opening x.sml]

  while in specialize phase
    raised at:    ../MLRISC/library/intmap.sml:29.41-29.44
		  ../compiler/MiscUtil/util/stats.sml:190.40

  uncaught exception RecoverLty
    raised at: ../MLRISC/library/intmap.sml:29.41-29.44
	       ../compiler/MiscUtil/util/stats.sml:190.40
	       ../compiler/FLINT/main/flintcomp.sml:179.13
	       ../compiler/MiscUtil/util/stats.sml:190.40
	       ../compiler/TopLevel/interact/evalloop.sml:60.55
	       ../compiler/TopLevel/interact/evalloop.sml:243.25-243.28
	       ../compiler/TopLevel/interact/evalloop.sml:60.55
	       ../compiler/TopLevel/main/compile.sml:244.13-244.58
	       ../compiler/MiscUtil/util/stats.sml:190.40
	       ../compiler/TopLevel/interact/evalloop.sml:60.55

Comments:

  I noticed this while experimenting with by "BTrace" module which does
  an Absyn->Absyn transformation before sending the stuff to FLINT.
  However, to my initial surprise, the problem occurs when I DO NOT use
  my new phase (and also occurs in an unmodified) version of SML/NJ but
  goes away when I turn BTrace on...  (In other words, the problem
  is not mine.)

Fix:
Test: bug1570.1.sml
Owner: Zhong, Stefan
Status: open
----------------------------------------------------------------------
Number: 1571
Title: drastic slowdown of startup on alpha
Keywords: startup, performance, alpha32
Submitter: Dave MacQueen
Date: 6/23/00
Version: 110.28.1+ (CVS version as of about 6/19?), but not 110.28.1
System: alpha32-dunix
Severity: critical
Problem: 
  There has been a drastic slowdown on the alpha caused by some change
  that was introduced recently in the repository (before yesterday, I
  think).

  Here is the startup time for 110.28:

    trappist$ cd /home/sml/Versions/110.28
    trappist$ time bin/sml <<XXX
    > XXX
    Standard ML of New Jersey v110.28 [FLINT v1.5], May 1, 2000
    - 

    real	0m0.86s
    user	0m0.08s
    sys		0m0.18s

  Here is the startup after compiling to a fixpoint with the current
  repository state:

    trappist$ cd /home/sml/Dev/dbm/110.26/smlnj
    trappist$ time bin/sml <<XXX
    > XXX
    Standard ML of New Jersey v110.28.1 [FLINT v1.5], June 5, 2000
    - 

    real	0m53.36s
    user	0m1.58s
    sys		0m7.91s

  Similar but less drastic slowdown has occured for sparc-solaris. 

    vex$ cd /home/sml/Versions/110.28
    vex$ time bin/sml <<XXX
    > XXX
    Standard ML of New Jersey v110.28 [FLINT v1.5], May 1, 2000
    - 

    real	0m0.65s
    user	0m0.29s
    sys		0m0.29s
    vex$ cd /home/sml/Dev/dbm/110.26/smlnj
    vex$ time bin/sml <<XXX
    > XXX
    Standard ML of New Jersey v110.28.1 [FLINT v1.5], June 5, 2000
    - 

    real	0m7.12s
    user	0m1.80s
    sys		0m3.28s

  ... but apparently not for x86-linux:

    arran$ cd /home/sml/Versions/110.28
    arran$ time ../../bin/sml <<XXX
    > XXX
    /bin/ksh: ../../bin/sml: not found

    real	0m0.05s
    user	0m0.01s
    sys		0m0.00s
    arran$ cd /home/sml/Dev/dbm/110.26/smlnj
    arran$ time ../../bin/sml <<XXX
    > XXX
    /bin/ksh: ../../bin/sml: not found

    real	0m0.04s
    user	0m0.00s
    sys		0m0.01s

Code:
Transcript:
Comments:
  I am pretty sure this slowdown predates Matthias's checkin of
  2000/06/23, and I think it started fairly recently, since I have
  been doing updates and booting to fixpoints on a regular basis and
  noticed this slowdown for the first time yesterday (6/22).

  A quick check indicates that the benchmarks have not slowed down
  significanly, though we haven't compared 110.28.1+ with 110.28 yet.

  One planned experiment is to build the 110.28.1 version and check
  its startup timing.

  This slow start problem does _not_ exist in 110.28.1
  (tag blume-20000606-lazierpickle), as tested on alpha32-dunix,
  sparc-solaris, x86-linux.  So it is due to some change since 6/6/00.

 [dbm, 6/23/00]
  On sparc/solaris, the truss command will print out a trace of
  all system calls.  This can be used to test whether the system
  calls have gone wild.  Results:

    vex$ cd /home/sml/Dev/dbm/110.26/smlnj
    vex$ truss bin/sml > truss.out 2>&1 <<XXX
    > XXX
    vex$ wc truss.out
       85584  308451 2885212 truss.out
    vex$ cd /home/sml/Versions/110.28
    vex$ pwd
    /home/sml/Versions/110.28
    vex$ truss bin/sml > truss.out 2>&1 <<XXX
    > XXX
    vex$ wc truss.out
	2204   12251   94638 truss.out

  So 110.28 does 2204 system calls on startup, while 110.28.1+ does
  85584.  This would seem to account for the slowdown

  There is a similar ratio of system calls on x86 (using strace instead
  of struss), though there isn't a noticeable slowdown for the x86.

    arran$ cd ../../110.26/smlnj
    arran$ strace bin/sml > strace.out 2>&1 <<XXX
    > XXX
    arran$ wc strace.out
       78895  366131 4488303 strace.out
    arran$ pwd
    /home/sml/Dev/dbm/110.26/smlnj
    arran$ bin/sml
    Standard ML of New Jersey v110.28.1 [FLINT v1.5], June 5, 2000
    - 
    arran$ cd ../../110.28.1/smlnj
    arran$ strace bin/sml > strace.out 2>&1 <<XXX
    > XXX
    arran$ wc strace.out
	1271    6897   75257 strace.out

 [jhr, 6/23/00]
  If you look at the two truss.out files, it appears that the extra work in
  110.28.1 has to do with CM.  The two files have a fairly common prefix,
  but the longer one has many sequences of the following form:

  stat("/n/bopp/shome/sml/Dev/dbm/110.26/smlnj/src/system/sml.boot.sparc-unix/smlnj/int
  ernal/cm-lib.cm", 0xEFFFF570) Err#2 ENOENT
  pathconf(".", _PC_PATH_MAX)                     = 1024
  stat("./", 0xEFFFF10C)                          = 0
  stat("/n/bopp/shome/sml/Dev/dbm/110.26/smlnj", 0xEFFFF084) = 0
  chdir("/")                                      = 0
  lstat("n", 0xEFFFF570)                          = 0
  chdir("n")                                      = 0
  lstat("bopp", 0xEFFFF570)                       = 0
  chdir("bopp")                                   = 0
  lstat("shome", 0xEFFFF570)                      = 0
  chdir("shome")                                  = 0
  lstat("sml", 0xEFFFF570)                        = 0
  chdir("sml")                                    = 0
  lstat("Dev", 0xEFFFF570)                        = 0
  chdir("Dev")                                    = 0
  lstat("dbm", 0xEFFFF570)                        = 0
  chdir("dbm")                                    = 0
  lstat("110.26", 0xEFFFF570)                     = 0
  chdir("110.26")                                 = 0
  lstat("smlnj", 0xEFFFF570)                      = 0
  chdir("smlnj")                                  = 0
  lstat("src", 0xEFFFF570)                        = 0
  chdir("src")                                    = 0
  lstat("system", 0xEFFFF570)                     = 0
  chdir("system")                                 = 0
  lstat("sml.boot.sparc-unix", 0xEFFFF570)        = 0
  chdir("sml.boot.sparc-unix")                    = 0
  lstat("smlnj", 0xEFFFF570)                      = 0
  chdir("smlnj")                                  = 0
  lstat("internal", 0xEFFFF570)                   = 0
  chdir("/n/bopp/shome/sml/Dev/dbm/110.26/smlnj") = 0

  I assume these are being generated by CM.

 [Matthias, 6/24/00]
  I agree, this looks very much like a CM bug.  I recently changed (=
  rewrote from scratch) the pathname handling that is central to all of
  CM's operation.  I think that it is basically sound, but there was a
  chdir-related bug, and I have the feeling that I got the fix for it
  wrong.  I'll look into it ASAP.

Fix: 
Test: 
Owner: Matthias
Status: fixed in 110.28.1+ [Matthias, 6/24/00]
----------------------------------------------------------------------
Number: 1572
Title: performance slowdown, pequal?
Keywords: performance, pequal
Submitter: Stefan Monnier <monnier+yale/systems/flint@flint.cs.yale.edu>
Date: 6/12/00
Version: 110.28.1?
System: x86-linux
Severity: major 
Problem: 
I have a strange performance issue here on x86.
When running with the latest version checked out of the CVS repository,
but using the old CPS-optimizer, I get considerably slower code than
with 110.25 (whereas I can't see such a slowdown on SPARC).

I figured I might have screwed something up, so I checked further.

110.26 (as defined by the tag v110_26_0 at least) run with FLINTopt
turned off and replaced by the old cpsopt is just as fast as 110.25
(unsurprisingly).

That means that the slowdown has been introduced between v110_26_0
(the revision that I tagged last December with the intention of making
it 110.26) and now.

So I checked all the changes I've made since then.
They touched (ignoring ml-yacc and sml-mode changes):

smlnj/src/compiler/FLINT/ChangeLog
smlnj/src/compiler/FLINT/cpsopt/cpsopt.sml
smlnj/src/compiler/FLINT/opt/fcontract.sml
smlnj/src/compiler/FLINT/opt/switchoff.sml
smlnj/src/compiler/FLINT/opt/fixfix.sml
smlnj/src/compiler/FLINT/opt/abcopt.sml
smlnj/src/compiler/FLINT/main/control.sml
smlnj/src/compiler/FLINT/main/flintcomp.sml
smlnj/src/compiler/FLINT/reps/equal.sml
smlnj/src/compiler/FLINT/reps/typeoper.sml
smlnj/src/compiler/FLINT/kernel/primop.sml
smlnj/src/compiler/FLINT/kernel/primop.sig
smlnj/src/compiler/FLINT/plambda/flintnm.sml
smlnj/src/system/testml
smlnj/src/cm/semant/semant.sml
smlnj/src/compiler/Parse/parse/ml.grm
smlnj/src/compiler/TopLevel/viscomp/control.sml 
smlnj/src/compiler/TopLevel/interact/evalloop.sml

The semant.sml change was just fixing a typo that prevented compilation
(a missing parenthesis).  The evalloop change was to prevent the interactive
loop from hiding useful exception information.

So I checked out a fresh copy of the latest smlnj and then did:

cvs update -r v110_26_0 src/compiler/FLINT
cvs update -A src/compiler/FLINT/trans
cvs update -r v110_26_0 src/compiler/TopLevel/viscomp/control.sml
cvs update -r v110_26_0 src/compiler/Parse/parse/ml.grm

[ the v110_26_0 of FLINT/trans/pequal.sml posed problem during compilation
  because of changes in the environments. ]

So, unless I missed a change, this should have reverted all the FLINT
changes to v110_26_0.  Yet, the performance of that hybrid version
(again with FLINTopt turned off and replaced by the old cpsopt) is
still the same as that of 110.28.1.

Allen tells me that 110.25 with MLRISC updates is _fast_, so I'm
tempted to believe that the problem might have been introduced by
CM changes.  Maybe this new FLINT/trans/pequal.sml code does not do
quite the same as before (such as using more registers, which could
explain that it impacted x86 but not SPARC) ?

I intended to try to go back in time with CVS to see which change
introduced this misbehavior, but there's been many tricky bootstrapping
steps over those months and the auto-fetched binfiles have all
disappeared.

So if a bootstrap-wizard could look into it (starting by trying to
revert the pequal change, maybe).  My tests are carried with the
repository's benchmark suite like this:

(echo 'Compiler.Control.FLINT.phases := ["lcontract", "lcontract", "specialize", "lcontract", "wrap", "reify"]; Compiler.Control.CG.cpsopt := ["first_contract", "eta", "uncurry", "etasplit", "cycle_expand", "eta", "last_contract"];'; bin/runit 10 /dev/tty b-hut ) | sh -x ../trunk/src/system/testml

(echo 'CM.autoload "host-compiler.cm";'; echo 'Compiler.Control.FLINT.phases := ["lcontract", "lcontract", "specialize", "lcontract", "wrap", "reify"]; Compiler.Control.CG.cpsopt := ["first_contract", "eta", "uncurry", "etasplit", "cycle_expand", "eta", "last_contract"];'; bin/runit 10 /dev/tty b-hut ) | sh -x ../110.26/src/system/testml

With the above example (i.e. barnes-hut), I get a run time of
around 2.3 seconds for 110.26 and 2.7 for 110.28.

I'd also love to hear just if someone else can or cannot reproduce this
problem.  To turn off the flint optimizer (revert it back to what it was
in 110.25), do:

	Compiler.Control.FLINT.phases := ["lcontract", "lcontract", "specialize", "lcontract", "wrap", "reify"];

To turn the cps optimizer back on, do:

	Compiler.Control.CG.cpsopt := ["first_contract", "eta", "uncurry", "etasplit", "cycle_expand", "eta", "last_contract"];

Code:
Transcript:
Comments:
 [Lal, 6/12/00]
  Stefan wrote:
   > 110.26 (as defined by the tag v110_26_0 at least) run with FLINTopt
   > turned off and replaced by the old cpsopt is just as fast as 110.25
   > (unsurprisingly).

  This should not be surprising as the only change to 110.26 was the 
  newFLINT (unless I am mistaken).

   > That means that the slowdown has been introduced between v110_26_0
   > (the revision that I tagged last December with the intention of making
   > it 110.26) and now.

  Looking at the performance numbers in your next message, it should be
  the case  that 110.28+cpsopt-newFLINT should be identical to
  110.25+newMLRISC.  What is the pequal change you are referring to?

   > I'd also love to hear just if someone else can or cannot reproduce this
   > problem.  To turn off the flint optimizer (revert it back to what it was
   > in 110.25), do:
   > 
   > 	Compiler.Control.FLINT.phases := ["lcontract", "lcontract", "specialize", "lcontract", "wrap", "reify"];
   > 
   > To turn the cps optimizer back on, do:
   > 
   > 	Compiler.Control.CG.cpsopt := ["first_contract", "eta", "uncurry", "etasplit", "cycle_expand", "eta", "last_contract"];
   > 

  I presume this is using 110.28 and the x86.

 [Stefan, 6/12/00]
  > ...What is the pequal change you are referring to?
  A patch committed as part of "let's get rid of CMStaticEnv".
  It doesn't seem to do much more than re-format parts of the code and
  do trivial adaptation between old datastructures and new ones.

 [Matthias, 6/13/00]
  Second, I don't think that changes to CM have anything to do with the
  quality of generated code.  However, Stefan seems to have found
  something regarding polyequal where I may have accidentally broken
  previously working code during my "CMStaticEnv" trials and
  tribulations.  If some knowledgeable person could have a closer look
  there, I'd appreciate it!

 [Stefan, 6/23/00]
  It's solved, actually.
  It turned out (embarassingly enough) to be a heap-size problem
  (Matthias' change to .run-sml was for the worst on processors
  with 512KB of cache (at least the Pentium-II machine I use for
  testing).
  I'd been careful to use the same runtime (which I thought was the
  place where default heap size was decided), but not the same .run-sml
  script.

Fix:
Test:
Owner: -
Status: not a bug 
----------------------------------------------------------------------
Number: 1573
Title:       ARRAY array tycon should be an eqtype
Keywords:    array
Submitter:   Stephen Weeks <sweeks@acm.org>
Date:        6/26/2000
Version:     110.0.6, 110.9.1, 110.28.1
System:      x86-linux
Severity:    
Problem:     
	The basis library spec for ARRAY states that array is an
	eqtype.  Thus the following code should type check.  It does
	not in SML/NJ.
Code:        

  functor F(A: ARRAY) =
  struct
    val _ = A.fromList [] = A.fromList []
  end

Comments:
 [dbm, 6/27/00]
   Changing the array spec from "type 'a array" to "eqtype 'a array"
   will not be a complete fix, since the array constructor, like ref,
   should produce an eqtype regardless of the equality property of
   its argument.  We don't have any way to declare this property of
   a type constructor.  For instance

	functor F(A: ARRAY) =
	   struct
	      val _ = A.fromList ([]: (int->int) list) = A.fromList []
	   end

   would still fail to type check.

   This is a fundamental hole in the SML type specification mechanism
   (see "An Abstract Interpretation of ML Equality Kinds" in TACS '91
   for further discussion of this point).

Fix:     
  src/compiler/PervEnv/Basis/array.sig should be changed  [partial fix]

Test: bug1573.1.sml
Owner: jhr, dbm
Status: open
----------------------------------------------------------------------
Number: 1574
Title:       Segmentation fault in gc, alpha dunix only
Keywords:    GC, core dump, alpha
Submitter:   Allyn Dimock <dimock@deas.harvard.edu>
Date:        9/6/00
Version:     Version 110.0.6, October 31, 1999
System:      [newcoke.eecs.harvard.edu 36]  uname
             OSF1
             [newcoke.eecs.harvard.edu 37]  uname -m
             alpha
             [newcoke.eecs.harvard.edu 38]  uname -r
             V4.0
Severity:    critical
Problem:     
  I reported a seg fault in garbage collection on the aplha.
  In the initial report I mentioned that the RTS had been modified with
  the addition of a routine "BlastSizeStat" similar to BlastWrite, and that
  the new routine was being called.

  I have re-run the test with
  (1) the call to the new routine replaced by "SMLofNJ.Internals.GC.doGC 100000;"
  (2) an unmodified copy of the RTS.

  The seg fault persists:

  sml @SMLload=CIL-NOSIZES @SMLrun=/a/bob/vol/vol1/home/mds/dimock/languages/ml/sm
  l-nj/bin/.run/run-unmodified.alpha32-dunix >&! ../test/bench/boyer2.sml.sd-us <<
  EOF
   Controls.dotSFilename := SOME("../test/bench/boyer2.s.sd-us");
   SimpleTop.compileFile Controls.simple Controls.Uniform "../test/bench/boyer2.sm
  l";
  EOF
  Segmentation fault (core dumped)

  gdb /a/bob/vol/vol1/home/mds/dimock/languages/ml/sml-nj/bin/.run/run-unmodified.alpha32-dunix core
  GNU gdb 4.18
  Copyright 1998 Free Software Foundation, Inc.
  GDB is free software, covered by the GNU General Public License, and you are
  welcome to change it and/or distribute copies of it under certain conditions.
  Type "show copying" to see the conditions.
  There is absolutely no warranty for GDB.  Type "show warranty" for details.
  This GDB was configured as "alphaev56-dec-osf4.0e"...
  (no debugging symbols found)...
  Core was generated by `run-unmodified.a'.
  Program terminated with signal 11, Segmentation fault.
  #0  0x2002c734 in NewDirtyVector ()
  (gdb) backtrace
  #0  0x2002c734 in NewDirtyVector ()
  #1  0x20031e20 in Flip ()
  #2  0x2002d430 in MajorGC ()
  #3  0x20027f08 in InvokeGC ()
  #4  0x2001e578 in _ml_RunT_gc_ctl ()
  #5  0x2001b4c4 in RunML ()
  #6  0x2001b0d0 in LoadML ()
  #7  0x20019ec0 in main ()
  (gdb) 

  At this point the program is vanilla SML/NJ.
  Here is the outline of the program that was exported to create the SML
  heap "CIL-NOSIZES.alpha-dunix":


  ... 
  get name for heap from command line 
  ...
  Compiler.Control.Print.printDepth := 1;
  CM.make' ("SimpleTop.cm") handle _ => OS.Process.exit (OS.Process.failure);
  ...
  set some refs in the newly built image
  ...
  ignore (SMLofNJ.Internals.CleanUp.addCleaner
	  ("quiet", 
	   [SMLofNJ.Internals.CleanUp.AtInit], 
	   (fn (_) => SMLofNJ.Internals.GC.messages(false))));
  if SMLofNJ.exportML (imageName) handle _ => OS.Process.exit(OS.Process.failure)
      then ("CIL interactive compiler running on "
	    ^ MLsh.Command.collect (MLsh.Command.exec ("hostname", [])))
  else OS.Process.exit (OS.Process.success);

Code:        Way too much, but see below for additional code in RTS.
Transcript:  
Comments:
  I have run the program interactively -- so no addCleaner,
  no exportML.  I have left GC messages enabled.  Same Seg Fault error
  in NewDirtyVector ()

  One interesting thing to note is the last CG messages:
  GC #64.4526.5852.12306.99513.2929451:   (5425 ms)
  GC #64.4526.5853.12307.99514.2929476:   (5 ms)
  GC #64.4526.5853.12307.99515.2929507:   (6 ms)
  GC #64.4527.5854.12308.99516.2929539:   (15 ms)
  GC #64.4527.5854.12308.99517.2929571:   (9 ms)
  GC #64.4527.5855.12309.99518.2929602:   (20 ms)
  GC #64.4527.5855.12309.99519.2929635:   (9 ms)
  GC #64.4527.5855.12309.99520.2929665:   (9 ms)
  GC #64.4527.5855.12309.99521.2929674:   (8 ms)
  GC #64.4528.5856.12310.99522.2929750:   (33 ms)
  GC #64.4528.5856.12310.99523.2929792:   (7 ms)
  GC #64.4528.5856.12310.99524.2929825:   (5 ms)
  GC #64.4528.5856.12310.99525.2929853:   (4 ms)
  GC #64.4528.5856.12310.99526.2929882:   (4 ms)
  GC #64.4528.5856.12310.99527.2929910:   (4 ms)
  GC #64.4528.5856.12310.99528.2929925:   (3 ms)
  GC #64.4528.5856.12310.99529.2930051:   (3 ms)
  GC #64.4528.5856.12310.99530.2930052:   (4 ms)
  GC #64.4528.5856.12310.99531.2930058:   (16 ms)
  GC #64.4529.5857.12311.99532.2930192:   (46 ms)
  Segmentation fault (core dumped)

  The fact that the last working GCs were #64 makes me wonder about the
  length of a field for counting GCs in the oldest generation.

 [Dimock, 9/13/00]
  John H. Reppy writes:

   > I think that it makes more sense to see what is causing the core
   > dump, before doing this [trying 110.29].  My guess is that the call
   > to malloc to allocate a new dirty vector is failing (if so, there
   > is not much we can do about it, but we could fail more gracefully).

  Unfortunately it is malloc, needing to allocate a larger dirty vector
  at gc-util.c line 152.

  Has there been a space leak fix since 110.0.6 that I might put in?
  Somewhere around we have some software for detecting possible memory
  leaks.  When I next get a few hours, I can try to find the software
  and see if it helps.

  Since it doesn't seem to be running up against my memory limit is
  there another constraint on memory that is causing malloc to run out?
  Is malloc allocating out of a fixed chunk of memory somewhere -- it
  seems unlikely -- In which case how could I expand that memory.

  here is some gdb output -- do the numbers seem unusual?
  (gdb under emacs: 
  M-x gdb
  /a/bob/vol/vol1/home/mds/dimock/languages/ml/sml-nj/bin/.run/run-debugging.alpha32-dunix

  (gdb) core ~/codefest/top-level/core
  Core was generated by `run-debugging.al'.
  Program terminated with signal 11, Segmentation fault.
  #0  0x2002f4e8 in NewDirtyVector (gen=0x4002ae80) at gc-util.c:153
  153	gc-util.c: No such file or directory.
  (gdb) backtrace
  #0  0x2002f4e8 in NewDirtyVector (gen=0x4002ae80) at gc-util.c:153
  #1  0x200351d0 in Flip (heap=0x4002ce80, min_gc_level=5) at flip.c:160
  #2  0x200301c4 in MajorGC (msp=0x40026a80, roots=0x1ffff488, level=5)
      at major-gc.c:196
  #3  0x2002a4ac in InvokeGC (msp=0x40026a80, level=5) at call-gc.c:211
  #4  0x2001edc8 in DoGC (msp=0x40026a80, arg=33751156) at gc-ctl.c:104
  #5  0x2001ebe8 in _ml_RunT_gc_ctl (msp=0x40026a80, arg=33751176) at gc-ctl.c:45
  #6  0x2001b824 in RunML (msp=0x40026a80) at ../kernel/run-ml.c:196
  #7  0x2001b390 in LoadML (loadImage=0x1ffff9e4 "CIL-NOSIZES", 
      heapParams=0x40026000) at ../kernel/load-ml.c:38
  #8  0x20019c60 in main (argc=3, argv=0x1ffff7c8) at ../kernel/main.c:86
  (gdb) dir ~/languages/ml/sml-nj/src/runtime/gc
  Source directories searched: /home/mds/dimock/languages/ml/sml-nj/src/runtime/gc:$cdir:$cwd
  (gdb) print gen.dirty
  $1 = (card_map_t *) 0x0
  (gdb) print allocSzB
  $2 = 396308
  (gdb) frame
  #0  0x2002f4e8 in NewDirtyVector (gen=0x4002ae80) at gc-util.c:153
  (gdb) print *gen
  $3 = {heap = 0x4002ce80, genNum = 5, numGCs = 29, lastPrevGC = 547, ratio = 5, 
    arena = {0x4002af00, 0x4002af80, 0x4002b000, 0x4002b080}, bigObjs = {
      0x4006e2c0}, toObj = 0x4002cf40, fromObj = 0x40069980, cacheObj = 0x0, 
    dirty = 0x0}
  (gdb) up
  #1  0x200351d0 in Flip (heap=0x4002ce80, min_gc_level=5) at flip.c:160
  (gdb) print g
  $5 = (gen_t *) 0x4002ae80
  (gdb) print *g
  $6 = {heap = 0x4002ce80, genNum = 5, numGCs = 29, lastPrevGC = 547, ratio = 5, 
    arena = {0x4002af00, 0x4002af80, 0x4002b000, 0x4002b080}, bigObjs = {
      0x4006e2c0}, toObj = 0x4002cf40, fromObj = 0x40069980, cacheObj = 0x0, 
    dirty = 0x0}
  (gdb) print *ap
  $7 = {id = 21504, nextw = 0x5be80000, tospBase = 0x5be80000, 
    tospSizeB = 101449728, tospTop = 0x61f40000, sweep_nextw = 0x5be80000, 
    repairList = 0x0, frspBase = 0x18690000, frspSizeB = 23068672, 
    frspTop = 0x199e7550, oldTop = 0x18690000, nextGen = 0x4002b080, 
    needsRepair = 0, reqSizeB = 0, maxSizeB = 245760000}
  (gdb) print *heap
  $8 = {allocBase = 0x2030000, allocSzB = 524288, baseObj = 0x4002cdf0, 
    numGens = 5, cacheGen = 2, numMinorGCs = 223429, gen = {0x4002f380, 
      0x4002f700, 0x4002a980, 0x4002ac00, 0x4002ae80, 0x4002b100, 0x4002b380, 
      0x4002b600, 0x40032080, 0x40032300, 0x40032580, 0x40032800, 0x40032a80, 
      0x40032d00}, numBORegions = 4, bigRegions = 0x2e90000, 
    freeBigObjs = 0x40032f80, weakList = 0x0}
  (gdb) print min_gc_level
  $9 = 5
  (gdb) up
  #2  0x200301c4 in MajorGC (msp=0x40026a80, roots=0x1ffff488, level=5)
      at major-gc.c:196
  (gdb) print level
  $10 = 5
  (gdb) print *msp
  $11 = {ml_heap = 0x4002ce80, ml_vproc = 0x4002f400, ml_allocPtr = 0x20300a0, 
    ml_limitPtr = 0x20af000, ml_roots = {78613176, 41625368, 1, 536992876, 
      41625368, 78578392, 276758572, 78613184, 55314616, 536993040, 176478928, 
      354, 55183720, 34271104, 152146372, 54790836, 54791460, 624, 104, 1, 
      78577672, 1}, ml_pseudoRegs = {1, 1}, ml_storePtr = 1, 
    ml_liveRegMask = 124, ml_faultExn = 1073911152, ml_faultPC = 0}
  (gdb) print *roots
  $12 = (unsigned int *) 0x40017a80
  (gdb) print **roots
  $13 = 276758532
  (gdb) 

 [Dimock, 9/15/00]
  John H. Reppy writes:
   > 
   > I think that it makes more sense to see what is causing the core
   > dump, before doing this.  My guess is that the call to malloc to
   > allocate a new dirty vector is failing (if so, there is not much
   > we can do about it, but we could fail more gracefully).

   > The function memory/malloc.c is not being used.  What ever your
   > OS provides as malloc is what gets used.

  It looks like bug 1574 remains open after all:

  (1) Ths swapon info on swap size was correct.
  (2) A C program can use all that swap space (400GB !) when built
  with the same switches as run.alpha32-dunix

  Example:

  [newcoke.eecs.harvard.edu 18]  cc -std -non_shared -T 20000000 -D 40000000 -o flood flood.c
  [newcoke.eecs.harvard.edu 19]  ./flood 6000 1000000

  malloc failed after 4109 chunks (4109000000 bytes).
  [newcoke.eecs.harvard.edu 20]  ./flood 4000 1000000

  No problem with 4000 chunks (4000000000 bytes).
  [newcoke.eecs.harvard.edu 21] 



  flood.c is as follows:
  #include <stdio.h>

  int
  main(int argc, char **argv)
  {
      int chunkcount, chunksize;
      int i;

      if (argc != 3)
      {
	  fprintf(stderr, "Usage: %s: chunkcount chunksize\n", argv[0]);
	  exit(1);
      }

      chunkcount = atoi(argv[1]);
      chunksize  = atoi(argv[2]);

      for (i = 0; i < chunkcount; ++i)
      {
	  if (0 == malloc(chunksize))
	  {
	      fprintf(stderr, "\nmalloc failed after %d chunks (%ld bytes).\n",
		     i, (long) i * chunksize);
	      exit(1);
	  }
      }
      fprintf(stderr, "\nNo problem with %d chunks (%ld bytes).\n",
	     chunkcount, (long) chunkcount * chunksize);

      return 0;
  }

Fix:
Test:
Owner:
Status:
----------------------------------------------------------------------
Number: 1575
Title:       Bad response to EOF on standard input on Windows 98
Keywords:    IO, EOF, Windows
Submitter:   Allen Stoughton, allen@cis.ksu.edu
Date:        09/02/00
Version:     110.0.6
System:      x86-win32 (Windows 98)
Severity:    minor (?)
Problem:
  On Windows 98, if a top-level expression reads from the standard input,
  and the user types in some characters, followed by CTRL-z, then
  the expression returns the correct value, but this value and its type
  are not correctly printed on the standard output.  The message that
  is printed is a suffix of what should be printed.

  This behavior occurs when running SML/NJ 110.0.6 in the MS-DOS
  window (i.e., SML/NJ was NOT being run in an Emacs buffer).
Transcript:
    Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM&CMB]
    - TextIO.inputAll TextIO.stdIn;
    once upon a time there was a big house on a hill...
    <CTRL-z>
    on a hill...\n"
      : TextIO.vector
  (only part of the normal SML/NJ response was printed)
    - it;
    val it = "once upon a time there was a big house on a hill...\n"
      : TextIO.vector
  (but it was set to the correct value)
    - TextIO.inputAll TextIO.stdIn;
    and on another occasion...
    <CTRL-z>
    vector
  (only part of the normal SML/NJ response was printed)
    -
Comments:
  The problem isn't specific to TextIO.inputAll.  I wrote a similar function
  using input, and got the same behavior.

 [Riccardo, 9/13/00]

  The Ctrl-Z issue under Win98 exists, and I think it's because
  fundamentally every Windows version handles EOF slightly differently
  (WinNT, Win95, Win98, probably Win2K as well). When Lorenz wrote the
  code originally, it was under NT, plus some correction for Win95, and
  I presume that the Win98 OS is different enough to require its own
  slight correction. One short term way of handling the problem is to
  not use TextIO.inputAll and instead do a series of TextIO.inputLine.

 [dbm, 9/13/00]
  The problem doesn't seem to occur on Win NT.

 [Stoughton, 9/15/00]
  Simply reading single lines using TextIO.inputLine works fine.  But,
  if I write a function that reads lines until EOF using TextIO.inputLine,
  then this function suffers from similar problems to TextIO.inputAll.
  Obviously, it seems to have something to do with reading until EOF..

Fix:
Test: *
Owner: Riccardo?
Status: open
----------------------------------------------------------------------
Number: 1576
Title:       buggy Real.!=
Keywords:    reals
Submitter:   Matthew Fluet, fluet@cs.cornell.edu
Date:        9/11/2000
Version:     110.0.6 (also 110.9.1 and 110.29)
System:      x86-unix
Severity:    minor
Problem:     Real.!= is inconsistent with the basis specification
Code:        

val x = 1.0/0.0 + ~1.0/0.0;
val _ = print (concat["x = ", 
		      Real.toString x, "\n",
		      "Real.==(x,x) = ", 
		      Bool.toString (Real.==(x,x)), "\n",
		      "Real.!=(x,x) = ", 
		      Bool.toString (Real.!=(x,x)), "\n",
		      "Real.?=(x,x) = ", 
		      Bool.toString (Real.?=(x,x)), "\n",
		      "Real.==(x,1.0) = ", 
		      Bool.toString (Real.==(x,1.0)), "\n",
		      "Real.!=(x,1.0) = ", 
		      Bool.toString (Real.!=(x,1.0)), "\n",
		      "Real.?=(x,1.0) = ", 
		      Bool.toString (Real.?=(x,1.0)), "\n",
		      "Real.==(1.0,1.0) = ", 
		      Bool.toString (Real.==(1.0,1.0)), "\n",
		      "Real.!=(1.0,1.0) = ", 
		      Bool.toString (Real.!=(1.0,1.0)), "\n",
		      "Real.?=(1.0,1.0) = ", 
		      Bool.toString (Real.?=(1.0,1.0)), "\n"]);

Transcript:

x = nan
Real.==(x,x) = false
Real.!=(x,x) = false
Real.?=(x,x) = true
Real.==(x,1.0) = false
Real.!=(x,1.0) = false
Real.?=(x,1.0) = true
Real.==(1.0,1.0) = true
Real.!=(1.0,1.0) = false
Real.?=(1.0,1.0) = true

Comments:

According to the basis library spec:

== (x, y) 
!= (x, y) 
    The first returns true if and only if neither y nor x is NaN, and y
and x are equal, ignoring signs on zeros. This is equivalent to the IEEE =
operator. 

    The second function != is equivalent to not o op == and the IEEE ?<>
operator.

So, I'd expect
Real.!=(x,x) = true
Real.!=(x,1.0) = true

Fix:
[Allen]
  It seems that in [sml-nj|FLINT]/cps/convert.sml, the line

               | c AP.NEQ  = P.fLG

  should read:

               | c AP.NEQ  = P.fULG

Test: bug1576.1.sml
Owner: jhr
Status: fixed in 110.0.7, 110.29+ [Leung, jhr]
----------------------------------------------------------------------
Number: 1577
Title: Stack Fault during install on Windows 2000
Keywords: Stack Fault ISSET_SE
Submitter: Vince Kovarik   vkovarik@acm.org
Date: 07/24/00
Version: 110.0.6
System: x86 Windows NT 5.00.2195
Subsystem: Installation
Severity: major
Problem:
Using Windows 2000..

Installation starts - then halts with an application error dialog box. 
The message is: 
ISSET_SE caused a Stack Fault in
module <unknown> 14C7:0128****ISSET_SE will close

where **** are some graphical symbols I couldn't reproduce in this
form.

After pressing the close button a second dialog comes up with a "Setup
Initialization Erropr" and the message:

"Setup has detected that unInstallShield is in use.  Please close
unInstallShield and restart setup.

Error 432."

unInstallShield had not been started and the same error occurs if the
machine is booted and a fresh install is attempted.


Comments:
 [dbm, 9/13/00]
  We now have a local Windows 2000 installation, and I have confirmed
  the bug.  It looks like we'll have to get an upgrade to InstallShield
  to correct this, but a new Windows 2000 compatible smlnj.exe should be
  available with a 110.0.7 patch release soon.

Fix: rebuild smlnj.exe with newer version of InstallShield?

Test: 
Owner: dbm, riccardo
Status: fixed in 110.0.7
----------------------------------------------------------------------
Number: 1578
Title:       invalid datatype replication causes compiler bug
Keywords:    
Submitter:   Stephen Weeks <sweeks@acm.org>
Date:        8/18/00
Version:     110.9.1
System:      x86-linux
Severity:    
Problem:     

  The following code causes the compiler bug "Error: Compiler bug: TypesUtil:
  extractDcons" instead of an error message.

Code:        

type u = int

fun f() =
   let
      datatype t = datatype u
   in ()
   end

Transcript:  
Comments:    
Fix:         
Test: bug1578.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1579
Title: Duplicate printing of syntax error messages
Keywords: error messages
Submitter: John Reppy   jhr@research.bell-labs.com
Date: 08/30/00
Version: 110.29
System: Any/All Any Unix 
Subsystem: Compilation manager (CM)
Severity: cosmetic
Problem:
  Duplicate printing of syntax error messages when using CM
  to compile a program.

Transcript:
  [parsing (sources.cm):scene.sml]
  scene.sml:143.20 Error: syntax error: inserting  LPAREN
  sources.cm:37.3-37.12 Error: syntax error
  scene.sml:143.20 Error: syntax error: inserting  LPAREN
  val it = false : bool

Comments:

Fix:

Test: 
Owner: Matthias
Status: fixed in 110.29+ [Matthias]
----------------------------------------------------------------------
Number: 1580
Title: uncaught exception ltUnbound
Keywords: vectors + recursion?
Submitter: Andreas Rossberg   rossberg@ps.uni-sb.de
Date: 09/08/00
Version: 110.0.6
System: x86 Linux 
Subsystem: SML compiler
Severity: major
Problem:
Internal lookup error during compilation.

Code:
  (* bug1580.1.sml *)

  datatype a = A1 | A2 of a
  datatype b = B1 | B2 of b vector

  fun f A1    = B1
    | f(A2 a) = B2(#[f a])

  -------------------------------------
  (* bug1580.2.sml *)

  fun vector2List v = Vector.foldr (fn (e,l) => (e::l)) [] v;

  fun concatVectors v = Vector.concat (vector2List v);

  fun f d = concatVectors #[concatVectors (Vector.map f #[])];

Transcript:
  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
  - use "nj-bug.sml";
  [opening nj-bug.sml]
  **** hmmm, I didn't find the variable 1

  uncaught exception ltUnbound
    raised at: basics/ltyenv.sml:251.32-251.41

Comments:
  If the expression #[f a] is replaced by vector[f a] everything
  works fine.

  Note that bug 1396 also involves the same "hmmm..." message, but
  in the context of a bad use of the # record selector notation.  
  This is also marked as open.

  See also bug 1549.

Fix:

Test: bug1580.1.sml, bug1580.2.sml
Owner: dbm, Zhong
Status: open
----------------------------------------------------------------------
Number: 1581
Title:       Problem with constant strings in ML-Lex
Keywords:    ML-Lex
Submitter:   Neophytos Michael (nmichael@cs.princeton.edu)
Date:        7/19/2000
Version:     Standard ML of New Jersey, Version 110.0.3, January 30, 1998
System:      sparc-solaris2.7
Severity:    minor
Problem:
  It appears that any constant string that contains an oper
  parenthesis causes ML-Lex to raise an exception and error out.  I have a
  relatively small lexer file that contains the following production:
  --------------------------------------------------------------------
  <INITIAL>"("      => (print "Found (\n";Tokens.LPAREN(yypos, yypos + 1));
  ---------------------------------------------------------------------
  Note that the constant string given as an argument to print function,
  contains an open parenthesis.  This causes ML-Lex to report:

Transcript:
  - CM.make();
  [starting dependency analysis]
  [/cmnusr/local/sml/sml-110.0.3/bin/ml-lex mcSyntax.lex]
  ml-lex: syntax error, line 73:
  /cmnusr/local/sml/sml-110.0.3/bin/ml-lex: uncaught exception Error

  !* CM error: ML-Lex failed: /cmnusr/local/sml/sml-110.0.3/bin/ml-lex
  mcSyntax.lex
  -

  If I remove the parenthesis '(' from the string, the error goes away.

Code:        See above
Transcript:  See above
Comments:
  The above is trivial to reproduce but if you need a self
  contained example let me know and I can provide it.
Fix:
Test: -
Owner: ?
Status: open
----------------------------------------------------------------------
Number: 1582
Title: SysErr exception connecting to socket
Keywords: sockets
Submitter: A. Mattox Beckman, Jr.  <beckman@cs.uiuc.edu>
Date: 10/31/00
Version: 110.29
System: -
Severity: major
Problem: 
  I have a process which listens to port 9999 which I'd like to have
  communicate with my SML program.  Here's what I tried to do:

  ----------------------------------------
  use "sock-util-sig.sml";
  use "sock-util.sml";

  val thePort = SockUtil.PortNumber 9999;
  val SOME hostIP = NetHostDB.fromString "128.174.246.77";
  val SOME localhostIP = NetHostDB.fromString "127.0.0.1";

  (* val s1 = SockUtil.connectINetStrm {addr=hostIP, port=9999}; *)
  vla s2 = SockUtil.connectINetStrm {addr=localhostIP, port=9999};
  ----------------------------------------

  For both s1 and s2 I get 

	  uncaught exception SysErr: Invalid argument [inval]

Code:
  use "sock-util-sig.sml";
  use "sock-util.sml";

  val thePort = SockUtil.PortNumber 9999;
  val SOME hostIP = NetHostDB.fromString "128.174.246.77";
  val SOME localhostIP = NetHostDB.fromString "127.0.0.1";

  (* val s1 = SockUtil.connectINetStrm {addr=hostIP, port=9999}; *)
  vla s2 = SockUtil.connectINetStrm {addr=localhostIP, port=9999};
Transcript:
Comments:
 [jhr]
  This appears to be a bug in 110.29, since the same example works in
  110.0.6 and 110.0.7.  I have an idea of what might be broken, so
  we can probably fix this problem for 110.30.
 [dbm]
  See also bugs 1480 and 1514, which involve similar sockets problems.
  1480 is listed as fixed in 110.19, while 1514 is open.
Fix:
Test: -
Owner: jhr
Status: fixed in 110.31
----------------------------------------------------------------------
Number: 1583
Title: datatype foo = datatype bar raises Unbound exception
Keywords: datatype replication
Submitter: Allen Leung   leunga@cs.nyu.edu
Date: 11/22/00
Version: 110.30
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
Datatype definitions of the following form:

    type bar = ...
    datatype foo = A | B | C of bar

raises exception Unbound when later used in:

    datatype baz = datatype foo

Also, the Unbound exception is caught by CM and CM aborts
without printing an error message.

The bug in is also in 110.25 but not in 110.0.6 

Code:
(* This code causes the bug *)
signature FOO = sig type bar = string datatype foo = A | B | C of bar end
structure Foo = struct type bar = string datatype foo = A | B | C of bar end
signature BAR = sig structure Foo : FOO datatype foo = datatype Foo.foo end
functor Bar() : BAR = struct
   structure Foo = Foo
   datatype foo = datatype Foo.foo
end

(* But this doesn't *)
signature FOO = sig type bar = string datatype foo = A | B | C of string end
structure Foo = struct type bar = string datatype foo = A | B | C of string end
signature BAR = sig structure Foo : FOO datatype foo = datatype Foo.foo end
functor Bar() : BAR = struct
   structure Foo = Foo
   datatype foo = datatype Foo.foo
end         
                             
Transcript:
- use "BUG2.sml";
[opening BUG2.sml]

uncaught exception Unbound
  raised at: ../compiler/Semant/elaborate/elabmod.sml:1328.39-1328.49
             ../compiler/MiscUtil/util/stats.sml:190.40
             ../compiler/TopLevel/interact/evalloop.sml:61.55
             ../compiler/TopLevel/interact/evalloop.sml:243.25-243.28
             ../compiler/TopLevel/interact/evalloop.sml:61.55
             ../compiler/TopLevel/main/compile.sml:300.13-300.58
             ../compiler/MiscUtil/util/stats.sml:190.40
             ../compiler/TopLevel/interact/evalloop.sml:61.55
- use "BUG4.sml";
GC #0.0.1.2.8.202:   (0 ms)
[opening BUG4.sml]
signature FOO = sig type bar = string
                    datatype foo = A | B | C of string end
structure Foo : sig type bar = string
                    datatype foo = A | B | C of string end
signature BAR =
  sig
    structure Foo :
      sig type bar = string
          datatype foo = A | B | C of string end
    type foo = Foo.foo
  end
functor Bar : <sig>
val it = () : unit
-                              
Comments:

Fix:

Test: tests/bug1583.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1584
Title: Premature Overloading Resolution
Keywords: types, overloading
Submitter: Andreas Rossberg   rossberg@ps.uni-sb.de
Date: 11/23/00
Version: 110.0.6
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
Some overloaded types are resolved to early, making overloading
resolution overly restrictive.

Code:
fun derive(f,dx) = fn x => (f(x + dx) - f(x)) / dx
(* This should type check. *)

Transcript:
Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
- fun derive(f,dx) = fn x => (f(x + dx) - f(x)) / dx;
stdIn:17.47 Error: overloaded variable not defined at type
  symbol: /
  type: int
- 
Comments:
 [jhr, 11/27/00]
  I think that this example is a bit more subtle than you realize.
  In the full SML definition, "/" is also overloaded (since there
  can be multiple real types), thus there is a conflict between the
  default overloading of "+" and "-" (which is int) and the default
  overloading of "/" (real).

 [Andreas Rossberg, 11/27/00]
  If I understand correctly you refer to the fact that the intersection
  between the overloading classes Num (for + and -) and Real (for /) is
  neither empty nor singular, but their default elements are different.

  I see your point. It's a pity that the Definition does not formalize
  overloading to explain what should happen under these circumstances.
  There seem to be several possible solutions:

  (1) always flag an error (is this what NJ does?),
  (2) if only one of both defaults is in the intersection,
      take this as the intersection's default type,
  (3) allow for intermediate overloading classes without defaults
      (i.e. flag an error only if we actually have to do defaulting).

  Both (2) and (3) would fix the example. They could work in combination
  as well.

  The more general problem however seems to be that the validity of SML
  programs depends on the overloading the given implementation provides.
  This is rather ugly and not in the spirit of SML. One possible fix for
  this might be that overloading is not considered to be resolved simply
  because an intermediate overloading class becomes singular. Then the
  example would behave the same on all implementations, regardless of
  their number of real types.

  Are there more detailed overloading rules in the Std Basis spec,
  possibly addressing these problems? (The online version refers to some
  Appendix C, but that does not seem to be accessible online.) I really
  would be interested in this, because I'm currently finalizing an SML
  frontend.

 [jhr, 11/27/00]
  I don't think that there is a formal specification of overloading and that
  fact is a significant weakness of the SML definition.  I believe that the
  way overloading is resolved in SML/NJ is as follows:

    1) Any overloaded operator or literal that can be resolved uniquely
       is done so.

    2) Any outstanding overloaded literals are resolved to their default
       types.

    3) repeat step 1

    4) assign an outstanding overloaded operators their default type.

  The code you sent fails on step 4, since mapping + to Int.+ and / to
  Real./ results in an incompatibility.

Fix:

Test: tests/bug1584.1.sml
Owner: dbm
Status: not a bug
----------------------------------------------------------------------
Number: 1585
Title: getpeername in sockets
Keywords: sockets, getpeername
Submitter: John Reppy <jhr@research.bell-labs.com>
Date: 11/21/00
Version: 110.0.7 and (probably) 110.30
System: -
Severity: medium 
Problem: getpeername doesn't work (symptoms?)
Comments:
Fix:
*** ORIGgetpeername.c	Fri Dec  3 14:59:28 1999
--- getpeername.c	Tue Nov 21 16:08:24 2000
***************
*** 15,40 ****
  #include "cfun-proto-list.h"
  #include "sock-util.h"
  
! /* _ml_Sock_getpeername : sock -> (af * addr)
   */
  ml_val_t _ml_Sock_getpeername (ml_state_t *msp, ml_val_t arg)
  {
!     char	    data[MAX_SOCK_ADDR_SZB];
!     struct sockaddr *addr;
!     int		    addrLen;
  
!     addr = (struct sockaddr *)data;
!     addrLen = MAX_SOCK_ADDR_SZB;
!     if (getpeername (INT_MLtoC(arg), addr, &addrLen) < 0)
  	return RAISE_SYSERR(msp, sts);
!     else {
! 	ml_val_t	af = ML_SysConst (msp, &_Sock_AddrFamily,
! 				ntohs(addr->sa_family));
! 	ml_val_t	cdata = ML_CData(msp, addr, addrLen);
! 	ml_val_t	res;
! 
! 	REC_ALLOC2 (msp, res, af, cdata);
! 	return res;
!     }
  
  } /* end of _ml_Sock_getpeername */
--- 15,30 ----
  #include "cfun-proto-list.h"
  #include "sock-util.h"
  
! /* _ml_Sock_getpeername : sock -> addr
   */
  ml_val_t _ml_Sock_getpeername (ml_state_t *msp, ml_val_t arg)
  {
!     char	    addr[MAX_SOCK_ADDR_SZB];
!     int		    addrLen = MAX_SOCK_ADDR_SZB;
  
!     if (getpeername (INT_MLtoC(arg), (struct sockaddr *)addr, &addrLen) < 0)
  	return RAISE_SYSERR(msp, sts);
!     else
! 	return ML_CData(msp, addr, addrLen);
  
  } /* end of _ml_Sock_getpeername */

Test:
Owner: jhr
Status: fixed in 110.0.8 and 110.31
----------------------------------------------------------------------
Number: 1586
Title: Windoze 9X installation exe has undefined parameters
Keywords: Windows installation bug
Submitter: Warren Ferguson warren_e_ferguson@hotmail.com
Date: 11/05/00
Version: 110.0.7
System: x86 Windows 95 Win98 
Subsystem: Installation 
Severity: minor
Problem: 
  Installation announces several parameter names are undefined,
  starting with PRODUCT_NAME!

Transcript: Error dialog boxes containing messages of the form:

  String PRODUCT_NAME was not found in string table

Comments:
 [dbm, 2/21/01]
  Complete list of undefined strings is
  PRODUCT_NAME, TITLE_CAPTIONBAR, FOLDER_NAME, COMPANY_NAME, PRODUCT_VERSION,
  PRODUCT_KEY, UNINST_KEY.

  Installation sometimes succeeds after dispatching these warning messages,
  but apparently sometimes fails.

  "... so far everything seems to work. The shortcut in the start-program menu 
  isn't set right, but a quick edit sets it to right. The path and set of 
  cm_path are there too, although that might be a carry-over from my previous 
  installation of smlnj."

 [Rob Hasker, hasker@uwplatt.edu, 1/18/2001, Win98]
  During install, I get a number of errors of the sort
  "No setting for PRODUCT_NAME".  SML seems to install ok,
  but the start menu is messed up, there is no uninstall, etc.

Fix:
  Revised contents of is-gen generated InstallShield project files.
Test: -
Owner: dbm
Status: fixed (new 110.0.7 smlnj.exe)
----------------------------------------------------------------------
Number: 1587
Title: Problem with Real.rem
Keywords: reals, rem, mod
Submitter: Steve Sims   sims@reactive-systems.com
Date: 11/27/00
Version: 110.0.7
System: x86 Linux Red Hat 7.0
Subsystem: SML basis library
Severity: minor
Problem:
Real.rem does not conform to Basis Definition
Code:

Transcript:
 $ sml
  Standard ML of New Jersey, Version 110.0.7, September 28, 2000 ...
  - 1.0 - Real.rem(10.0,3.0);
  val it = ~4.4408920985E~16 : real

(* Expected: val it = 0.0 *)
Comments:
 [jhr, 11/27/00]
  The problem is that Real.rem(10.0, 3.0) is not 1.0.

    - 1.0 - Real.rem(10.0,3.0);
    val it = ~4.4408920985E~16 : real

  so Real.== is returning the correct answer.

 [Steve Sims, 11/27/00]
  I am a novice at the subtleties of floating point arithmetic
  and rounding error, so please forgive me if I'm missing something
  basic.  The documentation for the Basis Library defines rem as follows:

  rem (x, y) 

	 returns the remainder x - n*y, where n = trunc ( x / y). The
	 result has the same sign as x and has absolute value less than the
	 absolute value of y.

	 If x is an infinity or y is 0, rem returns NaN. If y is an
	 infinity, rem returns x.

  Which to me looks like:

    fun myRem(r1,r2) = 
	let val n = Real.fromInt(Real.trunc(r1 / r2))
	in
	    r1 - (n * r2)
	end

  When I use this function I get

  - 1.0 - myRem(10.0,3.0);
  val it = 0.0 : real

 [jhr, 11/27/00]
  I think that you are correct, so this example should be viewed
  as a bug in Real.mod.

 [Steve Sims, 11/27/00]
  - Real.rem(10.0,3.0);
  val it = 1.0 : real
  - Real.==(it,1.0);
  val it = false : bool

Fix:
Test: bug1587.1.sml
Owner: jhr?
Status: open
----------------------------------------------------------------------
Number: 1588
Title: BinIO.inputAll raises Subscript (Windows)
Keywords: BinIO inputAll Subscript
Submitter: Tom 7   twm@andrew.cmu.edu
Date: 11/30/00
Version: Version 110.0.7, September 28, 2000 [CM&CMB]
System: x86 Windows NT 2000
Subsystem: SML basis library
Severity: minor
Problem:
  BinIO.inputAll raises Subscript in almost all circumstances. (See code
  and transcript.) I was able to make it succeed when reading "con" (a
  special file on Win2000), but never for any regular files.

Code:
(* does not work *)
  fun readfile f =
      let val inf = BinIO.openIn f
          val dat = BinIO.inputAll inf
       in BinIO.closeIn inf;
          dat
      end;

(* works *)
  fun readfile' f =
      let val inf = BinIO.openIn f
          fun rd vs =
              let val v = BinIO.input inf
               in case Word8Vector.length v
                    of 0 => Word8Vector.concat (rev vs)
                       | _ => rd (v :: vs)
              end
          val dat = rd nil
       in BinIO.closeIn inf;
          dat
      end;

Transcript:
  - readfile "sources.cm";

  uncaught exception Io: inputAll failed on "sources.cm" with exception subscript out of bounds
    raised at: boot/IO/bin-io-fn.sml:96.14-96.56

  - readfile' "sources.cm";
  val it = - : Word8Vector.vector

Comments:
 [jhr, 11/30/00]
  This bug appears to be windows specific, since the same code works on a
  Unix machine.  I wonder if the problem might be related to using binary I/O
  on a text file?  Have you tried the TextIO equivalant or tried reading
  a non-text file using this code?

 [Tom 7, 11/30/00]
  TextIO.inputAll works as I'd expect. BinIO.inputAll raises the exception
  on binary files (ie, executables), even a zero-byte file.

Fix:
Test: -
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1589
Title: incorrect implementation for Posix.TTY
Keywords: Posix.TTY
Submitter: Anthony Shipman   felixadv@access.net.au
Date: 11/30/00
Version: N/a
System: Any/All Any Unix 
Subsystem: Other
Severity: 
Problem:
  The basis library documentation for Posix.TTY describes a CF
  structure that no longer exists.  The TC structure no longer contains
  getattr..flow

Comments:
 [jhr, 11/30/00]
  This is a bug in the SML/NJ implementation (which is incomplete).
  The Basis document is the "correct" specification.

Fix:
Test: 
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1590
Title: compilation manager reads tool files from wrong directory
Keywords: compilation manager
Submitter: Matthai Philipose   matthai@cs.washington.edu
Date: 12/01/00
Version: 110.0.6
System: x86 Windows NT 4.0
Subsystem: Installation
Severity: minor
Problem:
  I'm using the compilation manager that comes with (the x86 binary
  distribution of) sml/nj 110.0.6. One of the lines in my .cm file is:
  parsers/c/c.mlyacc:MLYacc

  On doing a  CM.make(), I get the output:
  --------------begin output
  [starting dependency analysis]
  [scanning sources.cm]
  [checking CM\x86-win32\sources.cm.stable ... not usable]
  [c:/sml-build/110.0.6/bin/ml-yacc parsers\c\c.mlyacc]
  The system cannot find the path specified.

  !* CM error: ML-Yacc failed: c:/sml-build/110.0.6/bin/ml-yacc parsers\c\c.mlyacc
  ---------------end output

  The problem is that I have (and never had, AFAIK) no
  c:/sml-build/110.0.6/bin directory on my machine. In fact, the right
  executable for the MLyYacc tool is c:/sml/bin/ml-yacc.bat

  From the documentation, there does not seem any way of resetting this
  tool path, so I'm currently prevented from having CM rules that rely
  on various tools.

Code:
  see above
Transcript:
  see above
Comments:
 [dbm,2/21/01]
  Bad version of smlnj.exe.

Fix:

Test: 
Owner: dbm
Status: fixed
----------------------------------------------------------------------
Number: 1591
Title: Duplicate entries after insert() using IntRedBlackMap, WordRedBlackMap
Keywords: IntRedBlackMap WordRedBlackMap insert duplicate
Submitter: Gary Fuehrer, fuehrer@newmexico.com
Date: 12/1/2000
Version: 110.0.7
System: x86-win32
Severity: minor to most, but major to me ;-)
Problem:
  IntRedBlackMap.insert can result in duplicates.  Same with
  WordRedBlackMap.insert.
Code:
sources.cm:
  Group is
    smlnj-lib.cm
    bug.sml

bug.sml:
  structure Bug =
    struct
      structure RedBlackMapFn_Int = 
        RedBlackMapFn(struct type ord_key = int val compare = Int.compare end)
      structure RedBlackMapFn_Word = 
        RedBlackMapFn(struct type ord_key = word val compare = Word.compare end)

      fun demonstrate() =
        let
          val int_map = IntRedBlackMap.empty
          val int_map = IntRedBlackMap.insert(int_map, 1, "I'm the only one")
          val int_map = IntRedBlackMap.insert(int_map, 0, "I'm the only zero")
          val int_map = IntRedBlackMap.insert(int_map, 0, "I'm the only zero")

          val int_map' = RedBlackMapFn_Int.empty
          val int_map' = RedBlackMapFn_Int.insert(int_map', 1, "I'm the only one")
          val int_map' = RedBlackMapFn_Int.insert(int_map', 0, "I'm the only zero")
          val int_map' = RedBlackMapFn_Int.insert(int_map', 0, "I'm the only zero")

          val word_map = WordRedBlackMap.empty
          val word_map = WordRedBlackMap.insert(word_map, 0w1, "I'm the only one")
          val word_map = WordRedBlackMap.insert(word_map, 0w0, "I'm the only zero")
          val word_map = WordRedBlackMap.insert(word_map, 0w0, "I'm the only zero")

          val word_map' = RedBlackMapFn_Word.empty
          val word_map' = RedBlackMapFn_Word.insert(word_map', 0w1, "I'm the only one")
          val word_map' = RedBlackMapFn_Word.insert(word_map', 0w0, "I'm the only zero")
          val word_map' = RedBlackMapFn_Word.insert(word_map', 0w0, "I'm the only zero")
         in
          print("\nIntRedBlackMap\n");
          IntRedBlackMap.foldli
           (fn (k, v, _) => print(Int.toString(k)^ " - " ^ v ^ "\n")) () int_map;

          print("\nRedBlackMapFn_Int\n");
          RedBlackMapFn_Int.foldli
           (fn (k, v, _) => print(Int.toString(k) ^ " - " ^ v ^ "\n")) () int_map';

          print("\nWordRedBlackMap\n");
          WordRedBlackMap.foldli
           (fn (k, v, _) => print(Word.toString(k) ^ " - " ^ v ^ "\n")) () word_map;

          print("\nRedBlackMapFn_Word\n");
          RedBlackMapFn_Word.foldli 
           (fn (k, v, _) => print(Word.toString(k) ^ " - " ^ v ^ "\n")) () word_map'
        end
    end

Transcript:
Standard ML of New Jersey, Version 110.0.7, September 28, 2000 [CM&CMB]
- CM.make();
[starting dependency analysis]
[scanning sources.cm]
[checking CM\x86-win32\sources.cm.stable ... not usable]
[scanning E:\CygWin\usr\sml_nj\110.0.7-win32\lib\smlnj-lib.cm -> E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnjlib\Util\smlnj-lib.cm]
[checking E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\smlnj-lib.cm.stable ... ok - stable]
[dependency analysis completed]
[recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\ord-key-sig.sml.bin... done]
[recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\lib-base-sig.sml.bin... done]
[recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\lib-base.sml.bin... done]
[recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\ord-map-sig.sml.bin... done]
[recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\redblack-map-fn.sml.bin... done]
[recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\int-redblack-map.sml.bin... done]
[recovering E:\CygWin\usr\sml_nj\110.0.7-win32\src\smlnj-lib\Util\CM\x86-win32\word-redblack-map.sml.bin... done]
[recovering CM\x86-win32\bug.sml.bin... done]
[introducing new bindings into toplevel environment...]
val it = () : unit
- Bug.demonstrate();

IntRedBlackMap
0 - I'm the only zero
0 - I'm the only zero
1 - I'm the only one

RedBlackMapFn_Int
0 - I'm the only zero
1 - I'm the only one

WordRedBlackMap
0 - I'm the only zero
0 - I'm the only zero
1 - I'm the only one

RedBlackMapFn_Word
0 - I'm the only zero
1 - I'm the only one
val it = () : unit

Comments: 
  Can be worked around using RedBlackMapFn (see above code for an
  example).  There may be similar mistakes in other functions of
  IntRedBlackMap and WordRedBlackMap; I haven't examined them yet.

Fix: 
  Corrected the insert function so it matches the one in redblack-map-fn.sml.
  int-redblack-map.sml and word-redblack-map.sml:

    fun insert (MAP(nItems, m), xk, x) = let
          val nItems' = ref nItems
          fun ins E = (nItems' := nItems+1; T(R, E, xk, x, E))
            | ins (s as T(color, a, yk, y, b)) =
                if (xk < yk)
                  then (case a
                     of T(R, c, zk, z, d) =>
                          if (xk < zk)
                            then (case ins c
                               of T(R, e, wk, w, f) =>
                                    T(R, T(B,e,wk,w,f), zk, z, T(B,d,yk,y,b))
                                | c => T(B, T(R,c,zk,z,d), yk, y, b)
                              (* end case *))

BUG 1:                       else if (xk = yk)
FIX 1:                       else if (xk = zk)

BUG 2:                      then T(color, T(R, c, zk, x, d), yk, y, b)
FIX 2:                      then T(color, T(R, c, xk, x, d), yk, y, b)

                            else (case ins d
                               of T(R, e, wk, w, f) =>
                                    T(R, T(B,c,zk,z,e), wk, w, T(B,f,yk,y,b))
                                | d => T(B, T(R,c,zk,z,d), yk, y, b)
                              (* end case *))
                      | _ => T(B, ins a, yk, y, b)
                    (* end case *))
                else if (xk = yk)

BUG 3:            then T(color, a, yk, x, b)
FIX 3:            then T(color, a, xk, x, b)

                  else (case b
                     of T(R, c, zk, z, d) =>
                          if (xk < zk)
                            then (case ins c
                               of T(R, e, wk, w, f) =>
                                    T(R, T(B,a,yk,y,e), wk, w, T(B,f,zk,z,d))
                                | c => T(B, a, yk, y, T(R,c,zk,z,d))
                              (* end case *))
                          else if (xk = zk)

BUG 4:                      then T(color, a, yk, y, T(R, c, zk, x, d))
FIX 4:                      then T(color, a, yk, y, T(R, c, xk, x, d))

                            else (case ins d
                               of T(R, e, wk, w, f) =>
                                    T(R, T(B,a,yk,y,c), zk, z, T(B,e,wk,w,f))
                                | d => T(B, a, yk, y, T(R,c,zk,z,d))
                              (* end case *))
                      | _ => T(B, a, yk, y, ins b)
                    (* end case *))
          val m = ins m
          in
            MAP(!nItems', m)
          end

Test: -
Owner: jhr
Status: fixed (in 110.0.8, 110.33)
----------------------------------------------------------------------
Number: 1592
Title: Math.pow is not accurate
Keywords: "Math.pow" "function" "parameter"
Submitter: Jost Waldmann   jwaldmann@medinews.de
Date: 12/04/00
Version: 110.0.7
System: x86 Windows 95 
Subsystem: SML compiler
Severity: major
Problem:
  If you use the Math.pow function as a parameter in another function 
  the result you get is not right.
Code:
  trunc( Math.pow(2.0,4.0) );       

  Real.==(16.0,Math.pow(2.0,4.0));  


Transcript:
  trunc( Math.pow(2.0,4.0) );       
  val it = 15 :int

  Real.==(16.0,Math.pow(2.0,4.0));  
  val it = false :bool

Comments:
 [jhr, 12/4/00]
  Thanks for the bug report.  The current implementation of many of the
  Math functions leaves a lot to be desired.  We are planning to move
  to using the native C library for these, which should improve their
  accuracy.

Fix:
Test: 
Owner: ?
Status: open
----------------------------------------------------------------------
Number: 1593
Title: Pattern matching on word constants causes overflow in the compiler
Keywords: 
Submitter: Allen Leung  <leunga@cs.nyu.edu>
Date: 12/14/00
Version: 110.31
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
  Pattern matching on large word constants causes overflow in the 
  compiler.  But no problem with int constants.

  It's not restricted to 110.31.  I can't find one version of SML/NJ that
  can handle this code.
Code:
   fun f 0w1073741823 = false
     | f _ = true   

(* 0w1073741823 is 2^30-1 *)
Transcript:

  leunga@react-ilp.cs.nyu.edu:~/SML/src/MLRISC++{5938}> sml
  Standard ML of New Jersey v110.30 [FLINT v1.5], November 3, 2000
  - 0w1073741823;
  val it = 0wx3fffffff : word
  - fun f 0w1073741823 = false | f _ = true;

  uncaught exception overflow
    raised at: <file $smlnj/viscomp/core.cm@2891001(CodeGen/main/mlriscGen.sml)>
	       ../compiler/MiscUtil/util/stats.sml:190.40
	       ../compiler/MiscUtil/util/stats.sml:190.40
	       ../compiler/MiscUtil/util/stats.sml:190.40
	       ../compiler/TopLevel/interact/evalloop.sml:60.55
  -         

  leunga@react-ilp.cs.nyu.edu:~/SML/src/MLRISC++{5939}> ~/SML-110.0.6/sml/bin
  /home/leunga/SML-110.0.6/sml/bin: Command not found.
  leunga@react-ilp.cs.nyu.edu:~/SML/src/MLRISC++{5940}> ~/SML-110.0.6/bin/sml
  use "Standard ML of New Jersey, Version 110.0.6, October 31, 1999 ...
  - fun f 0w1073741823 = false | f _ = true;
  Error: Compiler bug: CPSGen: Overflow in cps/generic.sml
  -      

Comments:

Fix:

Test: bug1593.1.sml
Owner: jhr?
Status: open
----------------------------------------------------------------------
Number: 1594
Title: linker errors on FreeBSD 4.x
Keywords: runtime
Submitter: Brad Knotwell   knotwell@ix.netcom.com
Date: 01/04/01
Version: 110.32
System: x86 FreeBSD 4.2
Subsystem: Installation
Severity: major
Problem:
  Building the runtime on FreeBSD returns a good number of linker
  errors.  The FreeBSD compiler no longer requires globals assembly
  definitions to start with an underscore.  Removing the
  defined(OPSYS_FREEBSD) statement from the asm-base.h resolves the
  problem.

Comments:
 [Brad Knotwell, 1/5/01]
  For fun, I tried compiling up 110.32 on a x86 NetBSD system.  It had
  the identical problem and I resolved it in an identical manner.

 [Lal George, 1/5/01]
  Does the build complete once you fix the assembly definitions?

 [Brad Knotwell, 1/5/01]
  Sorry, I should've been more clear.  Yes, the runtime links correctly
  and the rest of the system builds.  I only had to remove the OPSYS_FREEBSD
  from the pre-processor directive worried about GLOBALS_NEED_UNDERSCORE
  (or somethin' like that, I'm at work).

  FWIW, I have no idea if this will work on FreeBSD3X and below.
Fix:

Test: 
Owner: jhr
Status: open
----------------------------------------------------------------------
Number: 1595
Title: suspicious signatures printed when using datatype replication
Keywords: datatype replication signature structure REPL
Submitter: Tom 7   tom7@cs.cmu.edu
Date: 01/14/01
Version: 110.0.7
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: cosmetic
Problem:

  The top-level loop prints out some suspicious results when using
  datatype replication. In particular, it appears to always report the
  name of the original datatype, as if it were being redeclared. This
  seems acceptable (if strange) at top-level, perhaps:

    - datatype X = datatype bool;
    datatype bool = false | true
    - 

  But the result for a structure is quite misleading:

    - structure Y = struct datatype X = datatype bool end;
    structure Y : sig datatype bool = false | true end
    -

  Structure Y, of course, does not match the signature printed. I'm
  pretty sure this is merely an artifact of the way datatypes are
  pretty-printed (I didn't observe any semantic violations).

Code:
  Above.
Transcript:
  Also above.
Comments:

Fix:

Test: 
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1596
Title:       TransTypes: unexpected FORMAL kind in tycTyc-h
Keywords:    types, functors, where clause
Submitter:   Fermin Reig, reig@dcs.gla.ac.uk
Date:        1/17/2001
Version:     110.32
System:      x86-linux
Severity:    major (?)
Problem:     functor applied inside another functor
Code:        

The context is the C-- compiler, that has an MLRISC-based back
end. I have a file mlriscFuns.sml with this functor:

functor MLRiscFuns
  (structure MLTreeComp : MLTREECOMP
   structure FlowGen    : FLOWGRAPH_GEN
	where T = MLTreeComp.T
	and   I = MLTreeComp.I
   val compile 		: FlowGen.flowgraph -> unit
) =
struct

  structure T : MLTREE  = MLTreeComp.T

  val iStream as T.Stream.STREAM {emit=emitInstr, ...} = 
	FlowGen.newStream {compile = compile, flowgraph = NONE}

end (* MLRiscFuns *)

I have a "functor MLRiscGen" similar in spirit to the one in SML/NJ's
main/mlriscGen.sml. In particular, MLTreeComp, FlowGen and compile are
parameters to the MLRiscGen functor. Inside MLRiscGen, I instantiate,

structure Foo = MLRiscFuns(structure MLTreeComp = MLTreeComp
			  structure FlowGen = FlowGen
			  val compile = compile)

and I get the error. If I remove this clause:

and   I = MLTreeComp.I

the bug does not happen

I assume you should be able to reproduce the error by having
mlriscFuns.sml and instantiating Foo inside SML/NJ's
MLRiscGen. Otherwise, I can send my sources (but they are big).

Transcript:  
- CM.make "sources.cm";
...
Error: Compiler bug: TransTypes: unexpected FORMAL kind in tycTyc-h
val it = false : bool

Comments:

  This is the smallest code I can find that exposes the bug.
  I use my own copy of MLRISC; That is, in my .cm file, rather than this

	  $/MLRISC.cm

  I have

	  MLRISC++/cm/MLRISC.cm

  but I think this should not make a difference with respect to this bug.

 [Fermin, 1/29/01]
  I can now provide a little more information about this bug, in case it
  is useful:

  If I substitute the where clauses by sharing clauses, I can compile
  the code just fine.

  functor MLRiscFuns
    (structure MLTreeComp : MLTREECOMP
     structure FlowGen : FLOWGRAPH_GEN
	  sharing FlowGen.T = MLTreeComp.T
	  sharing FlowGen.I = MLTreeComp.I
     val compile : FlowGen.flowgraph -> unit
  ) =

Fix:

Test: 
Owner: dbm, Zhong
Status: open
----------------------------------------------------------------------
Number: 1597
Title:       CML withNack bug and possible CM bug
Keywords: 
Submitter:   Anthony Shipman, felixadv@access.net.au
Date:        01/25/2001
Version:     110.0.7
System:      i386-Linux
Severity:    major
Problem:    
  The program below tests the CML withNack() function to time out a request
  to a server.  A fatal exception is thrown in the CML.select call within
  the client() function in the code below.  The exception message is

      'Fail: cvar already set'

  Also for some reason, perhaps to do with CM, the program does nothing
  and prints nothing if both of the toErr() and print() function 
  declarations are removed from the program.

Code:

structure Main =
struct
  (*  Unless one of these two functions is present the program prints nothing! *)
  fun toErr msg = TextIO.output(TextIO.stdErr, msg)
  fun print msg = TextIO.output(TextIO.stdOut, msg)

  datatype Msg = Msg of unit CML.event

  val req_chan: Msg CML.chan  = CML.channel()
  val rpl_chan: unit CML.chan = CML.channel()

  fun server t =
      let fun loop() =
              (case CML.recv req_chan
                 of Msg nack =>
	             (delay t; 
		      CML.select [
		        CML.sendEvt(rpl_chan, ()), 
		        CML.wrap(nack, fn () => print "Got a nack\n")];
	      loop()))
       in CML.spawn loop
      end

  and reqEvt () =
      let fun sender nack_evt =
              (CML.send(req_chan, Msg nack_evt);
	      CML.recvEvt rpl_chan)
       in CML.withNack sender
      end

  and client t =
      let fun body() =
              (CML.select[
	        CML.wrap(reqEvt(),   fn () => print "got the reply\n"),
	        CML.wrap(time_out t, fn () => print "client timed out\n")];
	       print "done client\n")
              handle
	        x => print(concat["exception: '", exnMessage x, "' in client\n"])
       in ignore(CML.spawn body)
      end

  and time_out t = CML.timeOutEvt(Time.fromSeconds(Int.toLarge t))
  and delay t    = CML.sync(time_out t)

  fun run() =
      (print "Test\n";
       server 3;   (* send reply after client times out *)
       client 2)

  fun main(arg0, argv) =
      (RunCML.doit(run, NONE);
       OS.Process.success)
      handle
       x => (print(concat["exception: ", exnMessage x, " in main\n"]);
	     OS.Process.failure)

  val _ = SMLofNJ.exportFn("nackbug", main)
end


script to run the program
=========================

heap=`basename $0`
install=.
smlbin=/src/smlnj/current/bin

exec $smlbin/.run-sml @SMLload=$install/${heap}.x86-linux "$@"


Transcript:  
  > nackbug
  Test
  exception: 'Fail: cvar already set' in client
  Got a nack

Comments: 
 [jhr, 1/24/01]
  The second problem has to do with CM (see the CML FAQ), but I'll try
  to track down the first problem.
 [jhr, 1/24/01]
  I've found and fixed the bug.  You can get a new CML tarball at

    ftp://ftp.research.bell-labs.com/dist/smlnj/packages/cml/20010124.tar.gz

  Two coding style comments:  I don't think that you need the LargeInt.fromInt
  conversions, since constants are overloaded.  Also, you should probably use
  RunCML.exportFn (instead of SMLofNJ.exportFn) to create executables.

Fix:
Test: -
Owner: jhr, Matthias
Status: fixed (in latest CML library)
----------------------------------------------------------------------
Number: 1598
Title: IntInf broken on Windows
Keywords: IntInf
Submitter: James C. Alexander  jca10@po.cwru.edu
Date: 1/17/01
Version: 110.0.7?
System: Windows
Severity: major
Problem: 
  We were never able to get Int-Inf to work on pentium machines.  It
  looks like some problem with word length.
Comments:
 [Riccardo, 1/17/01]
  I presume you are running SML/NJ under Windows? Indeed, that is a
  known bug with the implementation under Windows. A quick fix that I
  used in my class follows (directly from one of the assignments):

    READ ME: There is a bug in the current installation of SML/NJ for
    Windows that needs to be corrected before doing the second part of the
    problem set. The fix is simple, you need to delete two files in the
    installation. This assumes that you have installed SML/NJ in the
    default location, c:\sml. If not, then adapt accordingly. The two files
    to delete are: 
       c:\sml\src\smlnj-lib\Util\CM\x86-win32\int-inf-sig.sml.bin 
       c:\sml\src\smlnj-lib\Util\CM\x86-win32\int-inf.sml.bin 

  Basically, deleting these two files will force SML/NJ to recompile the
  IntInf structure, which takes care of that particular bug. - R

Fix:
Test:
Owner: ?
Status: open
----------------------------------------------------------------------
Number: 1599
Title: Nonexhaustive binding failure during compilation of incorrect program
Keywords: 
Submitter: Leif Kornstaedt   kornstae@ps.uni-sb.de
Date: 01/24/01
Version: Standard ML of New Jersey, Version 110.0.6, October 31, 1999
System: x86 Linux RedHat 7.0
Subsystem: SML compiler
Severity: minor
Problem:
  Compiler raises a Bind exception when compiling an erroneous program.

Code:
signature SIG1 =
sig
  type t
end

signature SIG2 =
sig
  type t
  val f: t -> unit
end

signature SIG3 =
sig
  structure S: SIG1
end

functor MkA(structure S1: SIG3): SIG3 =
struct
  open S1
end

functor MkB(structure A: SIG2): SIG3 =
  MkA(structure S1 = struct structure S = A end)

functor MkC(structure Ta: SIG2
            structure B: SIG3 where S = Ta) = struct end

structure A =
struct
  type t = int
  val f = ignore
end

structure B = MkB(structure A = A)

structure C = MkC(structure A = A
                  structure B = B)

Transcript:
  Standard ML of New Jersey, Version 110.0.6, October 31, 1999 [CM; autoload enabled]
  - use "sml-nj-bug-nonexhaustive-binding-failure.sml";
  [opening sml-nj-bug-nonexhaustive-binding-failure.sml]
  sml-nj-bug-nonexhaustive-binding-failure.sml:36.15-37.21 Error: unmatched structure specification: Ta

  uncaught exception nonexhaustive binding failure
    raised at: modules/sigmatch.sml:576.10-576.44
	       modules/sigmatch.sml:728.45
	       modules/sigmatch.sml:884.25
	       modules/sigmatch.sml:728.45
	       modules/sigmatch.sml:884.25
	       modules/sigmatch.sml:966.24
	       elaborate/elabmod.sml:1223.8
	       elaborate/elabmod.sml:1223.8

Comments:

Fix:

Test: bug1599.1.sml
Owner: dbm
Status: open
----------------------------------------------------------------------
Number: 1600
Title: Word literals are not printed correctly in error messages
Keywords: error messages
Submitter: John Reppy   jhr@research.bell-labs.com
Date: 01/24/01
Version: 110+
System: Any/All Any Unix 
Subsystem: SML compiler
Severity: minor
Problem:
  When printing word literals in error messages, the "0w" prefix is not
  included.  This makes the message confusing.

Code:
  0w1 + 1;

Transcript:
  Standard ML of New Jersey, Version 110.0.7, September 28, 2000 ...
  - 0w1 + 1;
  stdIn:25.1-25.8 Error: operator and operand don't agree [literal]
    operator domain: word * word
    operand:         word * int
    in expression:
      1 + 1

Comments:

Fix:

Test: 
Owner: jhr
Status: open
----------------------------------------------------------------------

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0