--- a/doc/changelog
+++ b/doc/changelog
@@ -1,5 +1,20 @@
Here are the changes from version 2010608 to version YYYYMMDD.
+* 2011-06-14
+ - Fixed bug in SSA/SSA2 shrinker that could erroneously turn a
+ non-tail function call with a Bug transfer as its continuation
+ into a tail function call.
+
+* 2011-06-10
+ - Fixed bug in translation from SSA2 to RSSA with case expressions
+ over non-primitive-sized words.
+ - Fixed bug in SSA/SSA2 type checking of case expressions over
+ words.
+
+* 2011-05-03
+ - Fixed a bug with the treatment of as-patterns, which should not
+ allow the redefinition of constructor status.
+
* 2011-02-18
- Fixed bug with treatment of nan in common subexpression
elimination SSA optimization.
--- a/doc/examples/finalizable/finalizable.sml
+++ b/doc/examples/finalizable/finalizable.sml
@@ -8,15 +8,16 @@
end
functor CList (structure F: MLTON_FINALIZABLE
+ structure P: MLTON_POINTER
structure Prim:
sig
- val cons: int * Word32.word -> Word32.word
- val free: Word32.word -> unit
- val sing: int -> Word32.word
- val sum: Word32.word -> int
+ val cons: int * P.t -> P.t
+ val free: P.t -> unit
+ val sing: int -> P.t
+ val sum: P.t -> int
end): CLIST =
struct
- type t = Word32.word F.t
+ type t = P.t F.t
fun cons (n: int, l: t) =
F.withValue
@@ -77,12 +78,13 @@
structure CList =
CList (structure F = MLton.Finalizable
+ structure P = MLton.Pointer
structure Prim =
struct
- val cons = _import "listCons": int * Word32.word -> Word32.word;
- val free = _import "listFree": Word32.word -> unit;
- val sing = _import "listSing": int -> Word32.word;
- val sum = _import "listSum": Word32.word -> int;
+ val cons = _import "listCons": int * P.t -> P.t;
+ val free = _import "listFree": P.t -> unit;
+ val sing = _import "listSing": int -> P.t;
+ val sum = _import "listSum": P.t -> int;
end)
structure S = Test (structure CList = CList
--- a/ide/enscript/sml_all.st
+++ b/ide/enscript/sml_all.st
@@ -88,6 +88,11 @@
*/
state sml_string
{
+ /\\\\(\s|\n)/ {
+ language_print ($0);
+ call (sml_string_gap);
+ }
+
/\\\\./ {
language_print ($0);
}
@@ -96,6 +101,22 @@
language_print ($0);
return;
}
+
+ LANGUAGE_SPECIALS {
+ language_print ($0);
+ }
+}
+
+state sml_string_gap
+{
+ /(\s|\n)/ {
+ language_print ($0);
+ }
+
+ /\\\\/ {
+ language_print ($0);
+ return;
+ }
LANGUAGE_SPECIALS {
language_print ($0);
--- a/ide/enscript/sml_simple.st
+++ b/ide/enscript/sml_simple.st
@@ -77,6 +77,11 @@
*/
state sml_string extends Highlight
{
+ /\\\\(\s|\n)/ {
+ language_print ($0);
+ call (sml_string_gap);
+ }
+
/\\\\./ {
language_print ($0);
}
@@ -85,6 +90,18 @@
language_print ($0);
return;
}
+}
+
+state sml_string_gap extends Highlight
+{
+ /(\s|\n)/ {
+ language_print ($0);
+ }
+
+ /\\\\/ {
+ language_print ($0);
+ return;
+ }
}
/*
--- a/mllex/lexgen.sml
+++ b/mllex/lexgen.sml
@@ -1,3 +1,6 @@
+(* Modified by Matthew Fluet on 2011-06-17.
+ * Use simple file name (rather than absolute paths) in line directives in output.
+ *)
(* Modified by Vesa Karvonen on 2007-12-19.
* Create line directives in output.
*)
@@ -295,7 +298,7 @@
val OutFile = ref ""
fun fmtLineDir {line, col} file =
String.concat ["(*#line ", Int.toString line, ".", Int.toString (col+1),
- " \"", OS.FileSys.fullPath file, "\"*)"]
+ " \"", file, "\"*)"]
val sayPos =
fn SOME pos => say (fmtLineDir pos (!InFile))
| NONE => (say (fmtLineDir {line = !LexOutLine, col = 0} (!OutFile));
@@ -1284,7 +1287,7 @@
fun lexGen(infile) =
let val outfile = infile ^ ".sml"
- val () = (InFile := infile; OutFile := outfile)
+ val () = (InFile := OS.Path.file infile; OutFile := OS.Path.file outfile)
fun PrintLexer (ends) =
let val sayln = fn x => (say x; say "\n")
in case !ArgCode
--- a/mlton/backend/ssa-to-rssa.fun
+++ b/mlton/backend/ssa-to-rssa.fun
@@ -599,12 +599,18 @@
src = Operand.word (WordX.one cardElemSize)}]
end
+fun convertWordSize (ws: WordSize.t): WordSize.t =
+ WordSize.roundUpToPrim ws
+
+fun convertWordX (w: WordX.t): WordX.t =
+ WordX.resize (w, convertWordSize (WordX.size w))
+
fun convertConst (c: Const.t): Const.t =
let
datatype z = datatype Const.t
in
case c of
- Word w => Word (WordX.resize (w, WordSize.roundUpToPrim (WordX.size w)))
+ Word w => Word (convertWordX w)
| _ => c
end
@@ -688,16 +694,21 @@
(ss, t)
end
| _ => Error.bug "SsaToRssa.translateCase: strange type"))
- | S.Cases.Word (s, cs) =>
- ([],
- Switch
- (Switch.T
- {cases = (QuickSort.sortVector
- (cs, fn ((w, _), (w', _)) =>
- WordX.le (w, w', {signed = false}))),
- default = default,
- size = s,
- test = varOp test}))
+ | S.Cases.Word (s, cases) =>
+ let
+ val cases =
+ QuickSort.sortVector
+ (Vector.map (cases, fn (w, l) => (convertWordX w, l)),
+ fn ((w, _), (w', _)) => WordX.le (w, w', {signed = false}))
+ in
+ ([],
+ Switch
+ (Switch.T
+ {cases = cases,
+ default = default,
+ size = convertWordSize s,
+ test = varOp test}))
+ end
fun eta (l: Label.t, kind: Kind.t): Label.t =
let
val {args, ...} = labelInfo l
--- a/mlton/control/source.sml
+++ b/mlton/control/source.sml
@@ -1,4 +1,5 @@
-(* Copyright (C) 1999-2006, 2008 Henry Cejtin, Matthew Fluet, Suresh
+(* Copyright (C) 2011 Matthew Fluet.
+ * Copyright (C) 1999-2006, 2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -11,7 +12,8 @@
datatype t = T of {file: File.t ref,
lineNum: int ref,
- lineStart: int ref}
+ lineStart: int ref,
+ origDir: Dir.t}
fun getPos (T {file, lineNum, lineStart, ...}, n) =
SourcePos.make {column = n - !lineStart,
@@ -20,10 +22,18 @@
fun lineStart (s as T {lineStart, ...}) = getPos (s, !lineStart)
-fun lineDirective (T {file, lineNum, lineStart},
+fun lineDirective (T {file, lineNum, lineStart, origDir},
f,
{lineNum = n, lineStart = s}) =
- (Option.app (f, fn f => file := f)
+ (Option.app (f, fn f =>
+ let
+ val f =
+ if OS.Path.isAbsolute f
+ then f
+ else OS.Path.mkCanonical (OS.Path.concat (origDir, f))
+ in
+ file := f
+ end)
; lineNum := n
; lineStart := s)
@@ -34,7 +44,8 @@
* starts at position ~1, which will translate position 0 to
* column 1.
*)
- lineStart = ref ~1}
+ lineStart = ref ~1,
+ origDir = File.dirOf file}
fun newline (T {lineStart, lineNum, ...}, n) =
(Int.inc lineNum
--- a/mlton/core-ml/dead-code.fun
+++ b/mlton/core-ml/dead-code.fun
@@ -1,4 +1,5 @@
-(* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
+(* Copyright (C) 2011 Matthew Fluet.
+ * Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -24,7 +25,7 @@
then escape true
else ())
; false))
- fun decIsWild (d: Dec.t): bool =
+ fun decIsWildOrUnit (d: Dec.t): bool =
case d of
Val {rvbs, vbs, ...} =>
0 = Vector.length rvbs
@@ -43,7 +44,6 @@
| Val {rvbs, vbs, ...} =>
Vector.exists (rvbs, varIsUsed o #var)
orelse Vector.exists (vbs, patVarIsUsed o #pat)
- orelse decIsWild d
fun useVar x = setVarIsUsed (x, true)
fun useExp (e: Exp.t): unit = Exp.foreachVar (e, useVar)
fun useLambda (l: Lambda.t): unit =
@@ -66,7 +66,7 @@
in
if deadCode
then List.fold (rev decs, [], fn (dec, decs) =>
- if decIsWild dec orelse decIsNeeded dec
+ if decIsWildOrUnit dec orelse decIsNeeded dec
then (useDec dec; dec :: decs)
else decs)
else (List.foreach (decs, useDec)
--- a/mlton/elaborate/elaborate-core.fun
+++ b/mlton/elaborate/elaborate-core.fun
@@ -1,4 +1,4 @@
-(* Copyright (C) 2009-2010 Matthew Fluet.
+(* Copyright (C) 2009-2011 Matthew Fluet.
* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
@@ -556,7 +556,21 @@
case constraint of
NONE => Type.new ()
| SOME t => elaborateType (t, Lookup.fromEnv E)
- val x = bindToType (x, t)
+ val xc = Avid.toCon (Avid.fromVar x)
+ val x =
+ case Env.peekLongcon (E, Ast.Longcon.short xc) of
+ NONE => bindToType (x, t)
+ | SOME _ =>
+ let
+ val _ =
+ Control.error
+ (region,
+ seq [str "constructor can not be redefined by as: ",
+ Avar.layout x],
+ seq [str "in: ", lay ()])
+ in
+ Var.fromAst x
+ end
val pat' = loop pat
val _ =
unifyPatternConstraint (Cpat.ty pat',
--- a/mlton/main/main.fun
+++ b/mlton/main/main.fun
@@ -188,8 +188,10 @@
case !Control.Target.arch of
Alpha => true
| AMD64 => true
+ | ARM => true
| HPPA => true
| IA64 => true
+ | MIPS => true
| Sparc => true
| S390 => true
| _ => false
--- a/mlton/ssa/analyze.fun
+++ b/mlton/ssa/analyze.fun
@@ -1,4 +1,5 @@
-(* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
+(* Copyright (C) 2011 Matthew Fluet.
+ * Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -126,23 +127,34 @@
end
| Case {test, cases, default, ...} =>
- let val test = value test
+ let
+ val test = value test
fun ensureNullary j =
if 0 = Vector.length (labelValues j)
then ()
else Error.bug (concat ["Analyze.loopTransfer: Case:",
Label.toString j,
" must be nullary"])
- fun doit (s, cs, filter: 'a * 'b -> unit) =
- (filter (test, s)
- ; Vector.foreach (cs, fn (_, j) => ensureNullary j))
+ fun ensureSize (w, s) =
+ if WordSize.equals (s, WordX.size w)
+ then ()
+ else Error.bug (concat ["Analyze.loopTransfer: Case:",
+ WordX.toString w,
+ " must be size ",
+ WordSize.toString s])
+ fun doitWord (s, cs) =
+ (ignore (filterWord (test, s))
+ ; Vector.foreach (cs, fn (w, j) =>
+ (ensureSize (w, s)
+ ; ensureNullary j)))
+ fun doitCon cs =
+ Vector.foreach (cs, fn (c, j) =>
+ filter (test, c, labelValues j))
datatype z = datatype Cases.t
val _ =
case cases of
- Con cases =>
- Vector.foreach (cases, fn (c, j) =>
- filter (test, c, labelValues j))
- | Word (s, cs) => doit (s, cs, filterWord)
+ Con cs => doitCon cs
+ | Word (s, cs) => doitWord (s, cs)
val _ = Option.app (default, ensureNullary)
in ()
end
--- a/mlton/ssa/analyze2.fun
+++ b/mlton/ssa/analyze2.fun
@@ -1,4 +1,5 @@
-(* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
+(* Copyright (C) 2011 Matthew Fluet.
+ * Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -123,35 +124,46 @@
end
| Case {test, cases, default, ...} =>
- let val test = value test
+ let
+ val test = value test
+ fun ensureSize (w, s) =
+ if WordSize.equals (s, WordX.size w)
+ then ()
+ else Error.bug (concat ["Analyze.loopTransfer: Case:",
+ WordX.toString w,
+ " must be size ",
+ WordSize.toString s])
fun ensureNullary j =
if 0 = Vector.length (labelValues j)
then ()
else Error.bug (concat ["Analyze2.loopTransfer: Case:",
Label.toString j,
" must be nullary"])
- fun doit (s, cs, filter: 'a * 'b -> unit) =
- (filter (test, s)
- ; Vector.foreach (cs, fn (_, j) => ensureNullary j))
+ fun doitWord (s, cs) =
+ (ignore (filterWord (test, s))
+ ; Vector.foreach (cs, fn (w, j) =>
+ (ensureSize (w, s)
+ ; ensureNullary j)))
+ fun doitCon cs =
+ Vector.foreach
+ (cs, fn (c, j) =>
+ let
+ val v = labelValues j
+ val variant =
+ case Vector.length v of
+ 0 => NONE
+ | 1 => SOME (Vector.sub (v, 0))
+ | _ => Error.bug "Analyze2.loopTransfer: Case:conApp with >1 arg"
+ in
+ filter {con = c,
+ test = test,
+ variant = variant}
+ end)
datatype z = datatype Cases.t
val _ =
case cases of
- Con cases =>
- Vector.foreach
- (cases, fn (c, j) =>
- let
- val v = labelValues j
- val variant =
- case Vector.length v of
- 0 => NONE
- | 1 => SOME (Vector.sub (v, 0))
- | _ => Error.bug "Analyze2.loopTransfer: Case:conApp with >1 arg"
- in
- filter {con = c,
- test = test,
- variant = variant}
- end)
- | Word (s, cs) => doit (s, cs, filterWord)
+ Con cs => doitCon cs
+ | Word (s, cs) => doitWord (s, cs)
val _ = Option.app (default, ensureNullary)
in ()
end
--- a/mlton/ssa/shrink.fun
+++ b/mlton/ssa/shrink.fun
@@ -1,4 +1,4 @@
-(* Copyright (C) 2009 Matthew Fluet.
+(* Copyright (C) 2009,2011 Matthew Fluet.
* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
@@ -460,7 +460,17 @@
Goto {canMove = canMove',
dst = m,
args = ps}
- | Bug => Bug
+ | Bug =>
+ if (case returns of
+ NONE => true
+ | SOME ts =>
+ Vector.equals
+ (ts, args, fn (t, (_, t')) =>
+ Type.equals (t, t')))
+ then Bug
+ else Goto {canMove = canMove',
+ dst = m,
+ args = ps}
| Case _ =>
Goto {canMove = canMove',
dst = m,
@@ -707,7 +717,7 @@
Transfer.layout))
val traceSimplifyCase =
Trace.trace
- ("Ssa2.Shrink2.simplifyCase",
+ ("Ssa.Shrink2.simplifyCase",
fn {canMove, cases, default, test, ...} =>
Layout.record [("canMove", List.layout Statement.layout canMove),
("cantSimplify", Layout.str "fn () => ..."),
--- a/mlton/ssa/shrink2.fun
+++ b/mlton/ssa/shrink2.fun
@@ -1,4 +1,4 @@
-(* Copyright (C) 2009 Matthew Fluet.
+(* Copyright (C) 2009,2011 Matthew Fluet.
* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
@@ -465,8 +465,18 @@
Goto {canMove = canMove',
dst = m,
args = ps}
- | Bug => Bug
- | Case _ =>
+ | Bug =>
+ if (case returns of
+ NONE => true
+ | SOME ts =>
+ Vector.equals
+ (ts, args, fn (t, (_, t')) =>
+ Type.equals (t, t')))
+ then Bug
+ else Goto {canMove = canMove',
+ dst = m,
+ args = ps}
+ | Case _ =>
Goto {canMove = canMove',
dst = m,
args = ps}
--- a/mlton/ssa/type-check.fun
+++ b/mlton/ssa/type-check.fun
@@ -1,4 +1,4 @@
-(* Copyright (C) 2009 Matthew Fluet.
+(* Copyright (C) 2009,2011 Matthew Fluet.
* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
@@ -48,7 +48,7 @@
end
val (bindTycon, getTycon, getTycon', _) = make' (Tycon.layout, Tycon.plist)
- val (bindCon, getCon, getCon', _) = make' (Con.layout, Con.plist)
+ val (bindCon, getCon, _) = make (Con.layout, Con.plist)
val (bindVar, getVar, getVar', unbindVar) = make' (Var.layout, Var.plist)
fun getVars xs = Vector.foreach (xs, getVar)
val (bindLabel, getLabel, unbindLabel) = make (Label.layout, Label.plist)
@@ -110,57 +110,47 @@
let
fun doit (cases: ('a * 'b) vector,
equals: 'a * 'a -> bool,
- toWord: 'a -> word): unit =
+ hash: 'a -> word,
+ numExhaustiveCases: IntInf.t) =
let
- val table = HashSet.new {hash = toWord}
+ val table = HashSet.new {hash = hash}
val _ =
Vector.foreach
(cases, fn (x, _) =>
let
- val _ =
+ val _ =
HashSet.insertIfNew
- (table, toWord x, fn y => equals (x, y),
- fn () => x,
+ (table, hash x, fn y => equals (x, y),
+ fn () => x,
fn _ => Error.bug "Ssa.TypeCheck.loopTransfer: redundant branch in case")
in
()
end)
+ val numCases = Int.toIntInf (Vector.length cases)
in
- if isSome default
- then ()
- else Error.bug "Ssa.TypeCheck.loopTransfer: case has no default"
+ case (IntInf.equals (numCases, numExhaustiveCases), isSome default) of
+ (true, true) =>
+ Error.bug "Ssa.TypeCheck.loopTransfer: exhaustive case has default"
+ | (false, false) =>
+ Error.bug "Ssa.TypeCheck.loopTransfer: non-exhaustive case has no default"
+ | _ => ()
end
+ fun doitWord (ws, cases) =
+ doit (cases, WordX.equals, WordX.hash, WordSize.cardinality ws)
fun doitCon cases =
let
- val numCons =
+ val numExhaustiveCases =
case Type.dest (getVar' test) of
- Type.Datatype t => getTycon' t
+ Type.Datatype t => Int.toIntInf (getTycon' t)
| _ => Error.bug "Ssa.TypeCheck.loopTransfer: case test is not a datatype"
- val cons = Array.array (numCons, false)
- val _ =
- Vector.foreach
- (cases, fn (con, _) =>
- let
- val i = getCon' con
- in
- if Array.sub (cons, i)
- then Error.bug "Ssa.TypeCheck.loopTransfer: redundant branch in case"
- else Array.update (cons, i, true)
- end)
in
- case (Array.forall (cons, fn b => b), isSome default) of
- (true, true) =>
- Error.bug "Ssa.TypeCheck.loopTransfer: exhaustive case has default"
- | (false, false) =>
- Error.bug "Ssa.TypeCheck.loopTransfer: non-exhaustive case has no default"
- | _ => ()
+ doit (cases, Con.equals, Con.hash, numExhaustiveCases)
end
val _ = getVar test
val _ =
case cases of
Cases.Con cs => doitCon cs
- | Cases.Word (_, cs) =>
- doit (cs, WordX.equals, Word.fromIntInf o WordX.toIntInf)
+ | Cases.Word (ws, cs) => doitWord (ws, cs)
in
()
end
@@ -211,11 +201,11 @@
val _ = Vector.foreach
(datatypes, fn Datatype.T {tycon, cons} =>
(bindTycon (tycon, Vector.length cons)
- ; Vector.foreachi (cons, fn (i, {con, ...}) =>
- bindCon (con, i))))
+ ; Vector.foreach (cons, fn {con, ...} =>
+ bindCon con)))
val _ = Vector.foreach
(datatypes, fn Datatype.T {cons, ...} =>
- Vector.foreach (cons, fn {args, ...} =>
+ Vector.foreach (cons, fn {args, ...} =>
Vector.foreach (args, loopType)))
val _ = Vector.foreach (globals, loopStatement)
val _ = List.foreach (functions, bindFunc o Function.name)
--- a/mlton/ssa/type-check2.fun
+++ b/mlton/ssa/type-check2.fun
@@ -1,4 +1,4 @@
-(* Copyright (C) 2009 Matthew Fluet.
+(* Copyright (C) 2009,2011 Matthew Fluet.
* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
@@ -49,7 +49,7 @@
end
val (bindTycon, getTycon, getTycon', _) = make' (Tycon.layout, Tycon.plist)
- val (bindCon, getCon, getCon', _) = make' (Con.layout, Con.plist)
+ val (bindCon, getCon, _) = make (Con.layout, Con.plist)
val (bindVar, getVar, getVar', unbindVar) = make' (Var.layout, Var.plist)
fun getVars xs = Vector.foreach (xs, getVar)
val (bindFunc, getFunc, _) = make (Func.layout, Func.plist)
@@ -134,60 +134,47 @@
let
fun doit (cases: ('a * 'b) vector,
equals: 'a * 'a -> bool,
- toWord: 'a -> word): unit =
+ hash: 'a -> word,
+ numExhaustiveCases: IntInf.t) =
let
- val table = HashSet.new {hash = toWord}
+ val table = HashSet.new {hash = hash}
val _ =
Vector.foreach
(cases, fn (x, _) =>
let
- val _ =
+ val _ =
HashSet.insertIfNew
- (table, toWord x, fn y => equals (x, y),
- fn () => x,
- fn _ => Error.bug "Ssa2.TypeCheck2.loopTransfer: redundant branch in case")
+ (table, hash x, fn y => equals (x, y),
+ fn () => x,
+ fn _ => Error.bug "Ssa.TypeCheck.loopTransfer: redundant branch in case")
in
()
end)
+ val numCases = Int.toIntInf (Vector.length cases)
in
- if isSome default
- then ()
- else Error.bug "Ssa2.TypeCheck2.loopTransfer: case has no default"
+ case (IntInf.equals (numCases, numExhaustiveCases), isSome default) of
+ (true, true) =>
+ Error.bug "Ssa.TypeCheck.loopTransfer: exhaustive case has default"
+ | (false, false) =>
+ Error.bug "Ssa.TypeCheck.loopTransfer: non-exhaustive case has no default"
+ | _ => ()
end
+ fun doitWord (ws, cases) =
+ doit (cases, WordX.equals, WordX.hash, WordSize.cardinality ws)
fun doitCon cases =
let
- val numCons =
+ val numExhaustiveCases =
case Type.dest (getVar' test) of
- Type.Datatype t => getTycon' t
- | _ => Error.bug (concat
- ["Ssa2.TypeCheck2.loopTransfer: case test ",
- Var.toString test,
- " is not a datatype"])
- val cons = Array.array (numCons, false)
- val _ =
- Vector.foreach
- (cases, fn (con, _) =>
- let
- val i = getCon' con
- in
- if Array.sub (cons, i)
- then Error.bug "Ssa2.TypeCheck2.loopTransfer: redundant branch in case"
- else Array.update (cons, i, true)
- end)
+ Type.Datatype t => Int.toIntInf (getTycon' t)
+ | _ => Error.bug "Ssa.TypeCheck.loopTransfer: case test is not a datatype"
in
- case (Array.forall (cons, fn b => b), isSome default) of
- (true, true) =>
- Error.bug "Ssa2.TypeCheck2.loopTransfer: exhaustive case has default"
- | (false, false) =>
- Error.bug "Ssa2.TypeCheck2.loopTransfer: non-exhaustive case has no default"
- | _ => ()
+ doit (cases, Con.equals, Con.hash, numExhaustiveCases)
end
val _ = getVar test
val _ =
case cases of
Cases.Con cs => doitCon cs
- | Cases.Word (_, cs) =>
- doit (cs, WordX.equals, Word.fromIntInf o WordX.toIntInf)
+ | Cases.Word (ws, cs) => doitWord (ws, cs)
in
()
end
@@ -238,11 +225,11 @@
val _ = Vector.foreach
(datatypes, fn Datatype.T {tycon, cons} =>
(bindTycon (tycon, Vector.length cons)
- ; Vector.foreachi (cons, fn (i, {con, ...}) =>
- bindCon (con, i))))
+ ; Vector.foreach (cons, fn {con, ...} =>
+ bindCon con)))
val _ = Vector.foreach
(datatypes, fn Datatype.T {cons, ...} =>
- Vector.foreach (cons, fn {args, ...} =>
+ Vector.foreach (cons, fn {args, ...} =>
Prod.foreach (args, loopType)))
val _ = Vector.foreach (globals, loopStatement)
val _ = List.foreach (functions, bindFunc o Function.name)
--- a/mlyacc/src/yacc.sml
+++ b/mlyacc/src/yacc.sml
@@ -1,3 +1,6 @@
+(* Modified by Matthew Fluet on 2011-06-17.
+ * Use simple file name (rather than absolute paths) in line directives in output.
+ *)
(* Modified by Vesa Karvonen on 2007-12-18.
* Create line directives in output.
*)
@@ -777,8 +780,8 @@
in let val result = TextIO.openOut (spec ^ ".sml")
val sigs = TextIO.openOut (spec ^ ".sig")
- val specPath = OS.FileSys.fullPath spec
- val resultPath = OS.FileSys.fullPath (spec ^ ".sml")
+ val specFile = OS.Path.file spec
+ val resultFile = specFile ^ ".sml"
val line = ref 1
val col = ref 0
val pr = fn s => TextIO.output(result,s)
@@ -793,8 +796,8 @@
String.concat ["(*#line ", Int.toString line, ".",
Int.toString (col+1), " \"", path, "\"*)"]
val fmtPos =
- fn NONE => (fmtLineDir {line = !line, col = 0} resultPath) ^ "\n"
- | SOME pos => fmtLineDir pos specPath
+ fn NONE => (fmtLineDir {line = !line, col = 0} resultFile) ^ "\n"
+ | SOME pos => fmtLineDir pos specFile
val termvoid = makeUniqueId "VOID"
val ntvoid = makeUniqueId "ntVOID"
val hasType = fn s => case symbolType s
--- /dev/null
+++ b/regression/weird-word1.ok
@@ -0,0 +1 @@
+0wx8
--- /dev/null
+++ b/regression/weird-word1.sml
@@ -0,0 +1,26 @@
+fun fib (w: Word5.word) : Word5.word =
+ if w <= 0wx1
+ then 0wx1
+ else fib (w - 0wx1) + fib (w - 0wx2)
+
+val s =
+ case (fib 0wx5) of
+ 0wx0 => "0wx0"
+ | 0wx1 => "0wx1"
+ | 0wx2 => "0wx2"
+ | 0wx3 => "0wx3"
+ | 0wx4 => "0wx4"
+ | 0wx5 => "0wx5"
+ | 0wx6 => "0wx6"
+ | 0wx7 => "0wx7"
+ | 0wx8 => "0wx8"
+ | 0wx9 => "0wx9"
+ | 0wxA => "0wxA"
+ | 0wxB => "0wxB"
+ | 0wxC => "0wxC"
+ | 0wxD => "0wxD"
+ | 0wxE => "0wxE"
+ | 0wxF => "0wxF"
+ | _ => "zzz"
+
+val _ = print (concat [s, "\n"])
--- /dev/null
+++ b/regression/weird-word2.ok
@@ -0,0 +1 @@
+0wx8
--- /dev/null
+++ b/regression/weird-word2.sml
@@ -0,0 +1,41 @@
+fun fib (w: Word5.word) : Word5.word =
+ if w <= 0wx1
+ then 0wx1
+ else fib (w - 0wx1) + fib (w - 0wx2)
+
+val s =
+ case (fib 0wx5) of
+ 0wx0 => "0wx0"
+ | 0wx1 => "0wx1"
+ | 0wx2 => "0wx2"
+ | 0wx3 => "0wx3"
+ | 0wx4 => "0wx4"
+ | 0wx5 => "0wx5"
+ | 0wx6 => "0wx6"
+ | 0wx7 => "0wx7"
+ | 0wx8 => "0wx8"
+ | 0wx9 => "0wx9"
+ | 0wxA => "0wxA"
+ | 0wxB => "0wxB"
+ | 0wxC => "0wxC"
+ | 0wxD => "0wxD"
+ | 0wxE => "0wxE"
+ | 0wxF => "0wxF"
+ | 0wx10 => "0wx10"
+ | 0wx11 => "0wx11"
+ | 0wx12 => "0wx12"
+ | 0wx13 => "0wx13"
+ | 0wx14 => "0wx14"
+ | 0wx15 => "0wx15"
+ | 0wx16 => "0wx16"
+ | 0wx17 => "0wx17"
+ | 0wx18 => "0wx18"
+ | 0wx19 => "0wx19"
+ | 0wx1A => "0wx1A"
+ | 0wx1B => "0wx1B"
+ | 0wx1C => "0wx1C"
+ | 0wx1D => "0wx1D"
+ | 0wx1E => "0wx1E"
+ | 0wx1F => "0wx1F"
+
+val _ = print (concat [s, "\n"])
--- a/runtime/basis/MLton/bug.c
+++ b/runtime/basis/MLton/bug.c
@@ -4,9 +4,7 @@
void MLton_bug (String8_t msg) {
uintmax_t size = GC_getArrayLength ((pointer)msg);
fprintf (stderr, "MLton bug: ");
- unless (0 == size)
- while (1 != fwrite ((const void*)msg, (size_t)size, 1, stderr))
- /* nothing */;
+ fwrite ((const void*)msg, (size_t)size, 1, stderr);
fprintf (stderr, "\nPlease send a bug report to MLton@mlton.org.\n");
exit (2);
}
--- a/runtime/basis/Posix/Signal.c
+++ b/runtime/basis/Posix/Signal.c
@@ -104,7 +104,7 @@
}
void Posix_Signal_sigsuspend (void) {
- int res;
+ int __attribute__ ((unused)) res;
res = sigsuspend (&Posix_Signal_sigset);
assert (-1 == res);
--- a/runtime/basis/Real/gdtoa.c
+++ b/runtime/basis/Real/gdtoa.c
@@ -14,10 +14,8 @@
int i;
ULong L[1];
char *result;
- ULong sign;
memcpy(L, &f, sizeof(Real32_t));
- sign = L[0] & 0x80000000L;
bits[0] = L[0] & 0x7fffff;
if (0 != (ex = (L[0] >> 23) & 0xff))
bits[0] |= 0x800000;
@@ -40,7 +38,6 @@
int i;
ULong L[2];
char *result;
- ULong sign;
int x0, x1;
if (isBigEndian()) {
@@ -51,7 +48,6 @@
x1 = 0;
}
memcpy(L, &d, sizeof(Real64_t));
- sign = L[x0] & 0x80000000L;
bits[0] = L[x1];
bits[1] = L[x0] & 0xfffff;
if (0 != (ex = (L[x0] >> 20) & 0x7ff))
--- a/runtime/basis/Real/strto.c
+++ b/runtime/basis/Real/strto.c
@@ -4,9 +4,8 @@
Real32_t Real32_strto (NullString8_t s, C_Int_t rounding) {
char *endptr;
Real32_t res;
- int ret;
- ret = gdtoa__strtorf ((const char*)s, &endptr, (int)rounding, &res);
+ gdtoa__strtorf ((const char*)s, &endptr, (int)rounding, &res);
assert (NULL != endptr);
return res;
}
@@ -14,9 +13,8 @@
Real64_t Real64_strto (NullString8_t s, C_Int_t rounding) {
char *endptr;
Real64_t res;
- int ret;
- ret = gdtoa__strtord ((const char*)s, &endptr, (int)rounding, &res);
+ gdtoa__strtord ((const char*)s, &endptr, (int)rounding, &res);
assert (NULL != endptr);
return res;
}
--- a/runtime/basis/Stdio.c
+++ b/runtime/basis/Stdio.c
@@ -2,18 +2,12 @@
void Stdio_printStderr (String8_t s) {
uintmax_t size = GC_getArrayLength ((pointer)s);
- if (0 == size)
- return;
- while (1 != fwrite ((const void*)s, (size_t)size, 1, stderr))
- /* nothing */;
+ fwrite ((const void*)s, (size_t)size, 1, stderr);
}
void Stdio_printStdout (String8_t s) {
uintmax_t size = GC_getArrayLength ((pointer)s);
- if (0 == size)
- return;
- while (1 != fwrite ((const void*)s, (size_t)size, 1, stdout))
- /* nothing */;
+ fwrite ((const void*)s, (size_t)size, 1, stdout);
}
void Stdio_print (String8_t s) {
--- a/runtime/gc/copy-thread.c
+++ b/runtime/gc/copy-thread.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
+/* Copyright (C) 2011 Matthew Fluet.
+ * Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -35,7 +36,7 @@
GC_thread fromThread;
GC_stack fromStack;
GC_thread toThread;
- GC_stack toStack;
+ GC_stack __attribute__ ((unused)) toStack;
if (DEBUG_THREADS)
fprintf (stderr, "GC_copyCurrentThread\n");
@@ -57,7 +58,7 @@
GC_thread fromThread;
GC_stack fromStack;
GC_thread toThread;
- GC_stack toStack;
+ GC_stack __attribute__ ((unused)) toStack;
if (DEBUG_THREADS)
fprintf (stderr, "GC_copyThread ("FMTPTR")\n", (uintptr_t)p);
--- a/runtime/gc/heap.c
+++ b/runtime/gc/heap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009-2010 Matthew Fluet.
+/* Copyright (C) 2009-2011 Matthew Fluet.
* Copyright (C) 2005-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
*
@@ -41,7 +41,7 @@
size_t liveMapsSize, liveWithMapsSize;
size_t currentMapsSize, currentWithMapsSize;
size_t resSize, resWithMapsSize;
- size_t syslimSize, syslimMapsSize, syslimWithMapsSize;
+ size_t syslimSize, __attribute__ ((unused)) syslimMapsSize, syslimWithMapsSize;
double ratio;
syslimWithMapsSize = alignDown (SIZE_MAX, s->sysvals.pageSize);
@@ -553,12 +553,11 @@
*/
void resizeHeapSecondary (GC_state s) {
size_t primarySize, primaryWithMapsSize;
- size_t secondarySize, secondaryWithMapsSize;
+ size_t secondarySize;
primarySize = s->heap.size;
primaryWithMapsSize = s->heap.withMapsSize;
secondarySize = s->secondaryHeap.size;
- secondaryWithMapsSize = s->secondaryHeap.withMapsSize;
if (DEBUG_RESIZING)
fprintf (stderr, "secondaryHeapResize\n");
if (0 == secondarySize)
--- a/runtime/gc/init-world.c
+++ b/runtime/gc/init-world.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
+/* Copyright (C) 2011 Matthew Fluet.
+ * Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -51,7 +52,7 @@
size_t bytes;
bool neg;
__mpz_struct resmpz;
- int ans;
+ __attribute__ ((unused)) int ans;
assert (isFrontierAligned (s, s->frontier));
for (i = 0; i < s->intInfInitsLength; i++) {
--- a/runtime/gc/invariant.c
+++ b/runtime/gc/invariant.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
+/* Copyright (C) 2011 Matthew Fluet.
+ * Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -42,6 +43,8 @@
assert (layout->size <= s->maxFrameSize);
offsets = layout->offsets;
+ for (unsigned int j = 0; j < offsets[0]; ++j)
+ assert (offsets[j + 1] < layout->size);
}
}
/* Generational */
--- a/runtime/gc/profiling.c
+++ b/runtime/gc/profiling.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
+/* Copyright (C) 2011 Matthew Fluet.
+ * Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
@@ -76,7 +77,6 @@
void enterForProfiling (GC_state s, GC_sourceSeqIndex sourceSeqIndex) {
uint32_t i;
- GC_profileData p;
GC_sourceIndex sourceIndex;
uint32_t *sourceSeq;
@@ -84,7 +84,6 @@
fprintf (stderr, "enterForProfiling ("FMTSSI")\n", sourceSeqIndex);
assert (s->profiling.stack);
assert (sourceSeqIndex < s->sourceMaps.sourceSeqsLength);
- p = s->profiling.data;
sourceSeq = s->sourceMaps.sourceSeqs[sourceSeqIndex];
for (i = 1; i <= sourceSeq[0]; i++) {
sourceIndex = sourceSeq[i];
@@ -123,10 +122,8 @@
}
void leaveSourceForProfiling (GC_state s, GC_profileMasterIndex i) {
- GC_profileData p;
GC_profileStack ps;
- p = s->profiling.data;
ps = getProfileStackInfo (s, i);
assert (ps->numOccurrences > 0);
ps->numOccurrences--;
@@ -136,7 +133,6 @@
void leaveForProfiling (GC_state s, GC_sourceSeqIndex sourceSeqIndex) {
int32_t i;
- GC_profileData p;
GC_sourceIndex sourceIndex;
uint32_t *sourceSeq;
@@ -144,7 +140,6 @@
fprintf (stderr, "leaveForProfiling ("FMTSSI")\n", sourceSeqIndex);
assert (s->profiling.stack);
assert (sourceSeqIndex < s->sourceMaps.sourceSeqsLength);
- p = s->profiling.data;
sourceSeq = s->sourceMaps.sourceSeqs[sourceSeqIndex];
for (i = sourceSeq[0]; i > 0; i--) {
sourceIndex = sourceSeq[i];