Bugs and patches: version 3.5.3

Listed below are the known bugs and patches or workarounds for version 3.5.3 of SRC Modula-3. Many of these patches and workarounds apply to the more recent ``test'' releases as well (i.e. test-3.5.4, test-3.5.4-A, and test-3.5.4-B). You may also want to consult the bugs and patches from the previous release, version 3.5.

Contents

There is a natural tension between the frequency of new releases and the number of patches that must be applied to an old release. We try to make the right choice. If you have any wisdom or advice on how this tradeoff should be made, please send e-mail to m3-request@src.dec.com.


problems building PEX package

This problem applies to all platforms.

When building the "PEX" package, you may get a link-time error indicating that the appropriate PEX library could not be found. You output may look something like this:

---------------------- building PEX ----------------------

--- building in IRIX5 ---
m3 -w1 -why -g -a libPEX.a -F/var/tmp/qkAAAa000Xh
ld -shared -ignore_unresolved -o libPEX.so -all libPEX.a -none
-L/usr/local/lib/m3/pkg/X11R4/IRIX5 -lm3X11R4
-L/usr/local/lib/m3/pkg/libm3/IRIX5 -lm3 -L/usr/local/lib/m3/pkg/m3core/IRIX5
-lm3core -L/usr/lib -lpex -L/usr/lib -lXaw -L/usr/lib -lXmu -L/usr/lib -lXext
-L/usr/lib -lXt -L/usr/lib -lX11 -lm -lc
/usr/lib/ld:
Can't locate file for: -lpex
[ many more quake error messages follow ]

The version of PEX we are using differs from MIT PEX, and is supported only on Digital machines. So unfortunately, there is no point in building the PEX package on non-Digital platforms.

On Digital Unix, PEX is part of an optional kit called OPEN3D. OPEN3D is a software kit that lets you run 3D applications. It supports both PEX and OpenGL. OPEN3D adds a number of "extensions" to the X server (the two interesting ones are X3D-PEX and GLX), and also includes a set of libraries for building PEX and OpenGL programs. Even on Digital Unix platforms, you must have the OPEN3D kit installed in order to build the Modula-3 PEX package.

You can check if your X server has the right extensions by running xdpyinfo(1) and looking for the X3D-PEX and GLX extensions. You can check if you have the right libraries by looking for "libdecpex.a", "libGL.a", "libGLU.a", and "libGLw.a" (probably in /usr/lib). If you can't find those libraries, presumably you don't have OPEN3D installed (you can ask your system administrator, who can run a program called lmf(8) to find out for sure).

The "anim3d", "obliqlib3D", and "obliqbin3D" packages all use the "PEX" package. If you don't have the PEX library, the easiest thing to do is to edit your main m3makefile, commenting out the "BuildChunks" for "PEX", "anim3D", "obliqlib3D", and "obliqbin3D".

Here is another option. The newest version of the obliq-3D system uses OpenGL as well as Digital PEX. You may be able to buy commercial versions of OpenGL for your platform. For example, the companies Portable Graphics and Template Graphics both sell OpenGL for Linux. You may want to use a web search engine like Alta Vista to find more companies selling OpenGL.

Thanks to Allen Delaney, Brian Genewich, Huw Evans, Alex Kiskachi, and Boris Gjenero for reporting this problem.


getdirentries undefined when building postcard package

This problem applies to all platforms.

When compiling the "OSUtils.m3" source file of the "postcard" package, you may get the error message that the "getdirentries" function is undefined. The output you see will look something like this:

new source -> compiling ../src/OSUtils.m3
"../src/OSUtils.m3", line 190: unknown qualification '.' (getdirentries)
"../src/OSUtils.m3", line 190: types are not assignable
2 errors encountered

This is an easy problem to fix. Simply edit the file "postcard/src/OSUtils.m3" and remove the following:

Thanks to Allen Delaney, Brian Genewich, and Boris Gjenero for reporting this problem. The bug has been fixed in all releases of SRC Modula-3 after 3.5.3.


buggy visualobliq m3makefile

This problem applies to all platforms, but only for the test-3.5.4* releases.

When compiling the "visualobliq" package, you may get an error like the following:

---------------------- building visualobliq ----------------------
--- building in IRIX5 ---
m3 -w1 -why -g -o visobliq -F/var/tmp/qkAAAa002hF 
"/net/puma/u3/s/kiskachi/modula3/m3/visualobliq/src/m3makefile", line 38: 
expecting 2 args for procedure "ManPage": found 1

The fix is simple. In "m3/visualobliq/src/m3makefile", the line

ManPage("visualobliq")

should be changed to

ManPage("visualobliq", 1)

Thanks to Farshad Nayeri, Alex Kiskachi, and Spencer Allain for reporting this problem. It has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


FormsVBT MultiBrowser bug

This problem applies to all platforms.

There is a bug in the implementation of MultiBrowsers. If you press the mouse button over the first list item, then drag the mouse down a little bit past the last item and release the mouse, no event is generated.

The bug is in the source file "m3/formsvbt/src/FVRuntime.m3". In that file, the definition of the type "MultiSelector" needs to have its "outsideClick" method overridden, like this:

REVEAL
  MultiSelector = PrivateMultiSelector BRANDED OBJECT
  OVERRIDES
    insideClick := MultiInsideClick;
    outsideClick := MultiOutsideClick
  END;

Then, the "MultiOutsideClick" needs to be defined:

PROCEDURE MultiOutsideClick(v: MultiSelector; READONLY cd: VBT.MouseRec) =
  BEGIN
    ListVBT.MultiSelector.outsideClick (v, cd);
    IF cd.clickType = VBT.ClickType.LastUp
       AND (v.quick OR cd.clickCount = 3) THEN
      MouseProc (v.browser, cd)
    END
  END MultiOutsideClick;

Thanks to John Polstra for noticing the bug and for supplying the necessary correction! This bug has been fixed in all releases of SRC Modula-3 after 3.5.3.


Postcard build problem

This problem applies to all platforms.

The following bug in Postcard seems to have slipped into the 3.5.4 release. The file "m3/postcard/src/PostcardMain.m3" in the "postcard" package will fail to compile with an error message like this:

new source -> compiling ../src/PostcardMain.m3
"../src/PostcardMain.m3", line 2886: incompatible types (halign)
"../src/PostcardMain.m3", line 2886: incompatible types (valign)
2 errors encountered
compilation failed => not building program "Postcard"

The lines in question should be changed to:

    initImage := NEW(InitImage).init(logo,
      op := PaintOp.Pair(bg, decFg), bg := bg);

Thanks to Spencer Allain for reporting the problem. This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


VBTkit ReactivityVBT bug

This problem applies to all platforms.

If you change the state of a "ReactivityVBT.T", and then immediately read the state using the "ReactivityVBT.Get" procedure, you may receive the old state. "ReactivityVBT.Get" doesn't return the correct state until some time later, after the display has been updated.

The fix is simple: in the file "m3/vbtkit/src/lego/ReactivityVBT.m3", change the implementation of "ReactivityVBT.Get" to return "v.newState" instead of "v.state".

Thanks to John Polstra for noticing the bug and for supplying the necessary correction! The bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


FormsVBT Viewport bug

This problem applies to all platforms.

There is a bug with ViewPort widgets that causes their horizontal scroll bars not to work when instantiated in the HorAndVer mode (the default). The bug is with the way the FormsVBT system instantiates the ViewPortVBT.T object used to represent the ViewPort widget.

In the source file "m3/formsvbt/src/FormsVBT.m3", replace the "pViewport" procedure with the following version:

PROCEDURE pViewport (         cl  : ParseClosure;
                     VAR      list: RefList.T;
                     READONLY s   : State         ): VBT.T RAISES {Error} =
  VAR
    state     := s;
    name      := NamePP();
    step      := NEW(CardinalPP, name := "Step", val := 10);
    horandver := NEW(BooleanPP, name := "HorAndVer");
    horonly   := NEW(BooleanPP, name := "HorOnly");
    veronly   := NEW(BooleanPP, name := "VerOnly");
    enum      := NEW(EnumPP).init(KP3{horandver, horonly, veronly}, 0);
    res       : FVViewport;
    ch        : VBT.T;
    axis      : Axis.T;
    shapeStyle: ViewportVBT.ShapeStyle;
  BEGIN
    ParseProps(cl, list, state, PP2{name, step}, enums := EP1{enum});
    ch := OneChild(cl, list, state);
    IF horandver.val OR horonly.val
      THEN axis := Axis.T.Ver
      ELSE axis := Axis.T.Hor
    END;
    IF horandver.val
      THEN shapeStyle := ViewportVBT.ShapeStyle.Unrelated
      ELSE shapeStyle := ViewportVBT.ShapeStyle.Related
    END;
    res := cl.fv.realize("Viewport", name.valname);
    res :=
      res.init(ch := ch, axis := axis, shadow := state.shadow,
               step := step.val, shapeStyle := shapeStyle,
               scrollStyle := VAL(enum.chosen, ViewportVBT.ScrollStyle));
    AddNameProp(cl, res, name, state);
    RETURN res
  END pViewport;

This implementation is not backward-compatible with the existing one. In particular, the following boolean attributes are no longer recognized: Fixed, UnrelatedShape, Vertical, Horizontal, AlaViewport, Auto, and NoScroll. In the new implementation, a Viewport component has only the following two orthogonal attributes:

Step (an integer, defaults to 10)
This integer specifies how much the Viewport scrolls when the user is auto-scrolling by pressing the mouse in a scrollbar.

HorAndVer, HorOnly, VerOnly (an enumeration, defaults to HorAndVer)
This attribute specifies whether the viewport has both horizontal and vertical scrollbars, a horizontal scrollbar only, or a vertical scrollbar only.

Both these properties existed in the old implementation as well, but the second one now automatically determines a set of attributes that could previously be specified by the now defunct attributes.

One last caveat: There is still a known bug in the implementation of the underlying ViewportVBT.T type, namely, that meta-clicking on a horizontal scrollbar doesn't split the window horizontally as it should.

Thanks to Patrick Ziemeck for noticing the bug, and to Marc Brown for supplying the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bug in m3pp when built with flex

This problem applies to all platforms such as LINUXELF that use flex instead of lex.

The current sources for the Modula-3 pretty-printer m3pp in the "pp" package do not work correctly when the parser is built with flex instead of lex. The problem is that the lex "input" function returns 0 on end-of-file, whereas the flex "input" function returns -1 on end-of-file.

The solution to the problem is simple: several equality tests against 0 need to be changed into inequalities. Two source files are effected: "m3/pp/src/Parse.yacc" and "m3/pp/src/lex_help.h". Here are the diffs for version 3.5.3 of SRC Modula-3:

$ diff -uNr m3.orig/pp/src/Parse.yacc m3/pp/src/Parse.yacc
--- m3.orig/pp/src/Parse.yacc	Fri May 26 11:36:01 1995
+++ m3/pp/src/Parse.yacc	Sat Feb  3 23:08:03 1996
@@ -1438,7 +1438,7 @@
   temp2 = input();   /* input comes from the lex library. */
   if ((calledFromEmacs && (temp2 == '\001')) || (temp2 == 0)) return;
   temp = input();
-  while ((temp != 0) && (!calledFromEmacs || (temp != '\001')))
+  while ((temp > 0) && (!calledFromEmacs || (temp != '\001')))
     {P (temp2); temp2 = temp; temp = input();}
-  if ((temp2 != '\n') || (temp != 0)) P(temp2);
+  if ((temp2 != '\n') || (temp > 0)) P(temp2);
 }
$ diff -uNr m3.orig/pp/src/lex_help.h m3/pp/src/lex_help.h
--- m3.orig/pp/src/lex_help.h	Thu Feb 23 17:08:31 1995
+++ m3/pp/src/lex_help.h	Sat Feb  3 23:08:21 1996
@@ -273,6 +273,6 @@
 		    unput(c2);
 	    }
 	}
-    } while ((c = input()) != 0 /* EOF */);
+    } while ((c = input()) > 0 /* EOF */);
     return WHITESPACE;
 }

Thanks to Reuben Sumner and Michel Dagenais for pointing out the problem and supplying the fix! These changes have been made in all releases of SRC Modula-3 after release 3.5.4-B.


bug in m3pp grammar

This problem applies to all platforms.

The Modula-3 pretty printer has a bug that causes it to choke on a series of alternating identifiers and periods containing more than two identifiers. This occurs when naming an enumerated value in some other interface (I.EnumType.Val) or when accessing fields of several nested records.

The fix is simple. In the file "m3/pp/src/Parse.yacc" around line 881, the rule for "selector_t" should contain the additional rule "Dot Ident", like this:

selector_t:
      Dot Ident
    | Uparrow
	/* Removed SP from front of each of these. -DN */
	/* Added break before lists. -DN */
    | QSP Lbracket AX B0 expr_list           E Z Rbracket
    | QSP Lparen   AX B0 actual_list         E Z Rparen
    | QSP Lparen                               Z Rparen
    | QSP Lbrace   AX B0 elem_list elem_tail E Z Rbrace
    | QSP Lbrace                               Z Rbrace
    ;

Thanks to Derek Beatty and Reuben Sumner for pointing out the bug. This bug is known to exist in SRC Modula-3 version 3.5.3. It may also exists in some of the test-3.5.4* releases, but it has certainly been fixed in all versions of SRC Modula-3 after 3.5.4-B.


bugs in signatures of modf and yn math functions

This problem applies to all platforms.

There are bugs in the signatures of the modf and yn EXTERNAL functions in "m3/libm3/src/arith/Math.i3" (in the test-3.5.4-B release, there are two versions of the interface stored in "m3/libm3/src/arith/{POSIX,WIN32}/Math.i3"). The old signatures and comments for these procedures are:

<*EXTERNAL*> PROCEDURE modf (x: LONGREAL; VAR exp: INTEGER): LONGREAL;
(* returns the positive fractional part of x and sets exp to
   the remaining integer part. *)

<*EXTERNAL*> PROCEDURE yn (n, x: LONGREAL): LONGREAL;
(* returns the n th-order Bessel function of second kind on x. *)

The new signatures and comments are:

<*EXTERNAL*> PROCEDURE modf (x: LONGREAL; VAR (*OUT*) i: LONGREAL): LONGREAL;
(* splits the argument "x" into an integer part "i" and a fractional part "f"
   such that "f + i = x" and such that "f" and "i" both have the same sign as
   "x", and returns "f". Although "i" is a LONGREAL, it is set to an integral
   value. *)

<*EXTERNAL*> PROCEDURE yn (n: INTEGER; x: LONGREAL): LONGREAL;
(* returns the n th-order Bessel function of second kind on x. *)

In releases where there is a separate WIN32 version of "Math.i3", the <*EXTERNAL*> pragmas for the Bessel functions "y0", "y1", and "yn" need to include the name of the function preceded by an underscore, as in <*EXTERNAL "_yn"*>.

You may also want to add the following signatures for full compatibility with the C math library, although the functionality provided by these functions is available directly using the Modula-3 MOD and ROUND operators:

(*---- Modulo functions ----*)

<*EXTERNAL*> PROCEDURE fmod (x, y: LONGREAL): LONGREAL;
(* returns the remainder of dividing x by y.
   Note: use the built-in Modula-3 function MOD. *)

<*EXTERNAL*> PROCEDURE drem (x, y: LONGREAL): LONGREAL;
<*EXTERNAL*> PROCEDURE remainder (x, y: LONGREAL): LONGREAL;
(* returns the remainder "r = x - n * y", where "n = ROUND(x/y)".
   Note: the Modula-3 functions MOD and ROUND may be appropriate. *)

Thanks to Charlie Garrett for pointing out the mistakes and for supplying the proper signatures. These bugs have been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bug in os/Common/m3makefile

This problem applies to all platforms.

The file "m3/libm3/src/os/Common/m3makefile" does not include a declaration for the "FS.m3" module. Add the following line to the file, then rebuild and reship libm3.

  implementation("FS")

Without this line, the "FS.m3" file is not compiled and included in the libm3 library. All this module does is to define the value for the global variable "FS.DirectoryFileType". If this file is not included in libm3, that global variable will have the value NIL, so accessing it -- say by passing it as an argument to Atom.ToText -- will result in a NIL-dereference.

Thanks to Paul Kominek for reporting this problem and to the folks at Critical Mass for providing the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


problems shipping libraries

This problem applies to all platforms.

If you have an existing SRC Modula-3 installation and you download a new implementation, you may have problems shipping the libraries from the new implementation after you build them.

The problem is due to typing "m3ship" to ship the libraries. This invokes the already-installed "m3ship" program. Instead, you have to type "./m3ship" to run the version of "m3ship" in the "boot-architecture" directory.

The correct instructions are described on the SRC Modula-3 installation page.

Thanks to Farshad Nayeri for figuring out how to solve this problem!


m3browser bugs

This problem applies to all platforms.

The m3browser package has four bugs that are easily corrected. The first three of these patches should be applied to the file "m3/m3browser/src/Main.m3". The fourth one should be applied to "m3/m3browser/src/M3MarkUp.m3".

  1. The application uses the deprecated "OS.GetHostName" procedure, which returns the NIS domain name, rather than the IP domain name.

    The fix in this case is simple. In "Main.m3", first add "IP" to the list of imports. Then, change the line:

      server_machine   := OS.GetHostName ();
    
    to read
      server_machine   :  TEXT; (* initialized in "ParseOptions" *)
    

    Then, in the "ParseOptions" procedure, also in "Main.m3", just before the existing lines:

      IF (server_machine = NIL) THEN
        ErrLog.Msg ("unable to get host machine's name");
        Abort ();
      END;
    
    add the following lines to initialize the "server_machine" global variable:
      TRY server_machine := IP.GetCanonicalByAddr(IP.GetHostAddr()) EXCEPT
        IP.Error => server_machine := NIL
      END;
    

    Thanks to Nils Jungclaus and Spencer Allain for noticing the problem and supplying a fix!

  2. There is a bug that causes m3browser to crash if you view a type that declares any of its methods to be initialized to NIL. The fix in this case is to replace the existing "GenProcRef" procedure in the "Main.m3" file by the following code:
    PROCEDURE GenProcRef(fmt: XFormat.T; t: TEXT) =
      VAR dotIndex := Text.FindChar(t, '.'); BEGIN
        fmt.group();
        IF dotIndex = -1 THEN
          fmt.putMarkup(t)
        ELSE
          WITH
        	unit = Text.Sub(t, 0, dotIndex),
        	proc = Text.Sub(t, dotIndex + 1) DO
        	fmt.putMarkup("<A HREF=\"/S" & unit & ".i3." & proc & "#"
        	       & proc & "\">" & t & "</A>");
          END
        END;
        fmt.end();
      END GenProcRef;
    

    This bug was noticed and corrected by Allan Heydon.

  3. When viewing an implementation module, you can click on the name of the program in which that module is contained. However, there is a bug that causes such links to return a page containing "*Unknown*". The "GenOneUnitSet" procedure in the file "Main.m3" contains the following code:
        IF (pgm)
          THEN tbl := db.pgms;  tag := "program";  cmd0 := "I";
          ELSE tbl := db.libs;  tag := "library";  cmd0 := "8";
        END;
        ...
        IF NOT db.libs.get (nm, ref) THEN
        ...
    

    Change the second IF line above to instead read:

        IF NOT tbl.get (nm, ref) THEN
    

    Thanks to Farshad Nayeri for noticing the bug and suggesting the fix!

  4. The last bug is in the "M3MarkUp.m3" module. The bug causes the browser to run into an infinite loop when a method in an object declaration has a NIL default. The fix is to change the second line of the "MarkUpProc" procedure from:

      IF Text.Equal (id, "NIL") THEN RETURN; END;
    

    to read:

      IF Text.Equal (id, "NIL") THEN lex.next(); RETURN; END;
    

    Thanks to Peter Klein for noticing the bug and reporting the fix!

All four of these bugs have been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bugs in mentor m3makefiles

This problem applies to all platforms.

There are bugs in the m3makefiles in the mentor package:

  1. First, in the file "m3/mentor/src/m3makefile", the line:
        include_dir (c)
    
    should be:
        include_dir (one_chunk)
    

  2. Second, in the m3makefiles associated with each of the different animation subdirectories, lines like the following appear at the end of the file:
      if not defined ("MENTOR_UMBRELLA")
        implementation (Main)
        bundle         (BinpackBundle)
        program        (binpack)
      end
    
    Each of the arguments should be changed to have double-quotes around it, like this:
      if not defined ("MENTOR_UMBRELLA")
        implementation ("Main")
        bundle         ("BinpackBundle")
        program        ("binpack")
      end
    

Thanks to John Kominek for noticing these problems and suggesting the fixes! These patches have been made in all releases of SRC Modula-3 after 3.5.4-B.


bug in Network Object runtime

This patch applies to all platforms.

On Windows platforms, the Network Object runtime can crash with an address fault during normal termination. This patch fixes the bug that caused this problem.

To apply the patch, edit the file "m3/netobj/src/tcpnetobj/TCPNetObj.m3". Edit the procedure "TCPNetObj.Listener". Change the handler for "IP.Error" in the loop to read:

      LOOP
        TRY
          conn := TCP.Accept(l.c);
          EXIT;
        EXCEPT
        | IP.Error(x) =>
            IF x.head # IP.NoResources THEN
              RAISE IP.Error(x);
            END;
        END;
        (* pause and retry on IP.Error(NoResources) *)
        Thread.Pause(1.0D0);
      END;
Then, add "IP.Error" to the list of exceptions caught by the outer "TRY..EXCEPT" command, like this:
  BEGIN
    TRY
      LOOP
        ...
      END;
      ...
    EXCEPT
    | ConnFD.TimedOut, IP.Error => (* SKIP *)
    | Thread.Alerted, Rd.Failure, Wr.Failure => (* SKIP *)
    END;
    ...
  END Listener;

Thanks to Michel Dagenais for reporting the problem and to Ted Wobber for supplying the fix. This fix has been made in all releases of SRC Modula-3 after 3.5.4-B.


floating point IsNaN bugs

This patch applies to all platforms.

There are bugs in the "IsNaN" procedures for all three Modula-3 floating-point types.

To apply the patch, edit the files "RealFloat.m3" and "LongFloat.m3" in the directory "m3core/src/float/IEEE/". In "RealFloat.m3", change the "IsNaN" procedure to read:

PROCEDURE IsNaN (x: T): BOOLEAN =
  VAR xx := LOOPHOLE (x, Rep.T);
  BEGIN
    RETURN xx.exponent = 16_ff AND xx.significand # 0;
  END IsNaN;

In "LongFloat.m3", change the "IsNaN" procedure to read:

PROCEDURE IsNaN (x: T): BOOLEAN =
  VAR xx := LOOPHOLE (x, Rep.T);
  BEGIN
    RETURN xx.exponent = 16_7ff 
       AND (xx.significand0 # 0 OR xx.significand1 # 0);
  END IsNaN;

Then rebuild and ship the "m3core" library.

Thanks to Spencer Allain for reporting the bug and to the folks at Critical Mass for supplying the fix. This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


Wr.FastClose bug

This patch applies to all platforms.

The implementation of the "Wr" interface contains a bug in which closing a writer may not cause its "close" method to be invoked. This can happen if the writer's "flush" method fails.

The fix is simple. In the file "m3/libm3/src/rw/Common/WrMove.m3", locate the "FastClose" procedure. In that procedure, change the lines:

        wr.flush();
        wr.close()

to instead read:

        TRY wr.flush() FINALLY wr.close() END

The use of TRY..FINALLY guarantees that the "close" method will be invoked even if the "flush" method raises an exception.

Thanks to John Polstra for pointing out the bug and suggesting the fix! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


FileWr.Length bug

This patch applies to all platforms.

There is a bug in the implementation of the "length" method of seekable file writers (i.e., objects of type "FileWr.T"). The implementation does not meet the "length" method specification as described in the "Wr" interface: it gets the length of the file by reading the size of the underlying file on disk, but that number can be too small if some writes to the file haven't (yet) been flushed.

The fix is to report the length of a seekable file writer as the maximum of the writer's current position and the size of the underlying file. To fix the bug, edit the file "m3/libm3/src/rw/Common/FileWr.m3". Change the line in the "Length" procedure that reads:

    RETURN wr.targetH.status().size;

to instead read:

    RETURN MAX(wr.cur, wr.targetH.status().size);

Then rebuild and ship the "libm3" library.

Thanks to Allan Heydon for finding the bug and to Ted Wobber for supplying the fix! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


INTERNAL CG ERROR, unaligned LONGREAL

This problem applies to all platforms.

On platforms in which LONGREALs must be aligned to 64-bit boundaries, if you compare two arrays of LONGREALs for equality or inequality, you will get an "INTERNAL CG (code generator) ERROR" from the compiler, like this:

m3c ../src/DataPoint.m3 -w1
"../src/Mod.m3", line 23: ** INTERNAL CG ERROR *** unaligned load_indirect  type=4  s/a=64/32
"../src/Mod.m3", line 23: ** INTERNAL CG ERROR *** unaligned load_indirect  type=4  s/a=64/32

This is known to occur on at least the SOLgnu and IRIX5 platforms. The workaround is to write a loop to compare the arrays element by element. The patch for this bug is unavailable at this time.

Thanks to Jorge Stolfi and Warren Smith for reporting the bug, and to Bill Kalsow for making the fix! This compiler bug has been fixed in all releases of SRC Modula-3 after 3.5.3.


fingerprint of a non-constant expression

This problem applies to all platforms.

A declaration like:

CONST Bad = INTEGER;

will crash the Modula-3 compiler with the message "INTERNAL ERROR: fingerprint of a non-constant expression". This is a buggy program, since INTEGER is a type, not a value. However, a buggy program should not crash the compiler. The details of the fix are not available at this time.

Thanks to Farshad Nayeri and Christopher Wang for pointing out the problem, and to Bill Kalsow for supplying the fix. This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


<*EXTERNAL*> INTERFACE

This problem applies to all platforms.

The SRC Modula-3 reference manual says:

Beginning an interface with <*EXTERNAL*> declares all of the procedures and variables in that interface external.

However, if you include a CONSTANT definition in such an <*EXTERNAL*> INTERFACE, you will get the compilation error "a constant cannot be external". This is a bug.

To fix the bug, edit the file "m3/m3front/src/values/Decl.m3". In the "Decl.Parse procedure around line 57 in the "TK.tCONST" arm of the CASE statement, change the line:

        att.isExternal := att.isExternal OR Module.IsExternal ();

to read:

        att.isExternal := att.isExternal;

Thanks to Farshad Nayeri for pointing out the problem, and to Bill Kalsow for supplying the fix. This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


READONLY PROCEDURE crash

This problem applies to all platforms.

If you declare a procedure argument to be of type PROCEDURE and to have mode READONLY, the compiler will produce code that crashes your program when the procedure is invoked. For example, consider this program:

MODULE Main;
IMPORT IO;

TYPE P = PROCEDURE();

PROCEDURE Q(READONLY p: P) =
  BEGIN p() END Q;

PROCEDURE R() =
  PROCEDURE LocalProc() =
    BEGIN IO.Put("OK\n") END LocalProc;
  BEGIN Q(LocalProc) END R;

BEGIN R() END Main.

In this program, the invocation of "Q" will cause a crash, since the PROCEDURE argument "p" is declared with mode READONLY. The temporary workaround is to declare the procedure argument with mode "VALUE" (or with no mode at all, which is equivalent).

The patch for this bug is easy. In the source file "m3/m3front/src/values/Formal.m3" in the procedure "Formal.HasClosure" around line 139, change the line:

   | T(t) => RETURN (t.mode = Mode.mVALUE)

to read:

   | T(t) => RETURN (t.mode # Mode.mVAR)

Thanks to Paul Menage and Peter Robinson for reporting the bug and to Bill Kalsow for supplying the fix. This compiler bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


NEW(NULL), NEW(REFANY), NEW(ADDRESS) allowed

This problem applies to all platforms.

According to the language definition, NEW cannot be applied to NULL, REFANY or ADDRESS. However, the compiler will compile such allocations without complaint. This is a bug in the compiler. The obvious workaround is not to write such invocations of NEW.

The patch in this case is to change the "New.CheckRef" procedure in the file "m3/m3front/src/builtinOps/New.m3". Change the first part of the procedure from:

PROCEDURE CheckRef (r: Type.T;  ce: CallExpr.T;  VAR cs: Expr.CheckState) =
  VAR
    base: Type.T;
    fields: Value.T;
    info : Type.Info;
  BEGIN
    r := Type.CheckInfo (r, info);
    base := Type.Base (r);
    IF (r = NIL) THEN
     Error.Msg("cannot NEW a variable of type REFANY, ADDRESS, or NULL");
    ELSIF (info.isEmpty) THEN
      Error.Msg ("cannot allocate variables of empty types");

to read:

PROCEDURE CheckRef (r: Type.T;  ce: CallExpr.T;  VAR cs: Expr.CheckState) =
  VAR
    base: Type.T;
    fields: Value.T;
    info : Type.Info;
  BEGIN
    IF (r = NIL) THEN
      Error.Msg("cannot NEW a variable of type REFANY, ADDRESS, or NULL");
      RETURN;
    END;
    r := Type.CheckInfo (r, info);
    base := Type.Base (r);
    IF (info.isEmpty) THEN
      Error.Msg ("cannot allocate variables of empty types");

Thanks to Paul Menage for pointing out the problem and suggesting a fix. The actual fix was supplied by Bill Kalsow. This compiler bug has been fixed in all versions of SRC Modula-3 after version 3.5.4-B.


DIV, MOD bugs

This problem applies to all platforms.

The expressions "0 DIV 0" and "0 MOD 0" both produce 0, rather than producing a division-by-zero error.

The fix is simple. In the file "m3/m3core/src/Csupport/Common/hand.c", the "m3_div" and "m3_mod" functions are coded as follows:

long m3_div (b, a)
long a, b;
{
  register long c;
  if (a == 0L)        {  c = 0L;
  } else if (a > 0L)  {  c = (b >= 0L) ? (a) / (b) : -1L - (a-1L) / (-b);
  } else /* a < 0L */ {  c = (b >= 0L) ? -1L - (-1L-a) / (b) : (-a) / (-b);
  }
  return c;
}

long m3_mod (b, a)
long a, b;
{
  register long c;
  if (a == 0L)        {  c = 0L;
  } else if (a > 0L)  {  c = (b >= 0L) ? a % b : b + 1L + (a-1L) % (-b);
  } else /* a < 0L */ {  c = (b >= 0L) ? b - 1L - (-1L-a) % (b) : - ((-a) % (-b) );
  }
  return c;
}

The fix is to change the first test in both functions to read:

  if ((a == 0L) && (b != 0L)) ...

Thanks to Joseph Manning for reporting the problem, and thanks to Bill Kalsow for supplying the fix. This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bug in COMMON template

This problem applies to all platforms.

If you configure your system so that the INSTALL directories are different from the USE directories, then the current version of the COMMON template will mistakenly create symbolic links that point to libraries in the INSTALL directory rather than the USE directory.

The fix is simple. In the file "m3/m3build/templates/COMMON", locate the procedure named "install_link_to_derived", which appears near line 977. Within this procedure, change the lines:

    local target = format ("%s%s%s%s%s%s%s", PKG_INSTALL, SL, BUILD_PACKAGE,
                                             SL, BUILD_DIR, SL, src)

to read:

    local target = format ("%s%s%s%s%s%s%s", PKG_USE, SL, BUILD_PACKAGE,
                                             SL, BUILD_DIR, SL, src)

That is, change the occurrence of "PKG_INSTALL" to "PKG_USE".

Thanks to Olly Stephens for pointing out the bug and supplying the fix. This change will appear in all versions of SRC Modula-3 after 3.5.4-B.


constant MOD expression bug

This problem applies to all platforms.

The compiler has a bug that causes it to report errors for constant MOD expressions in certain circumstances. For example, the code

  VAR even: BOOLEAN := (23 MOD 2 = 0);

is okay, but the statement

  IF 23 MOD 2 = 0 THEN ... END

produces compilation errors.

The fix is quite simple. In the file "m3/m3front/src/exprs/ModExpr.m3", lines 118-119 in the Compile procedure are:

  IF (e1 # NIL) AND (e2 # NIL) AND IntegerExpr.Mod (e1, e2, e3) THEN
  ELSIF (e2 # NIL)

There is a line missing between these lines; they should read:

  IF (e1 # NIL) AND (e2 # NIL) AND IntegerExpr.Mod (e1, e2, e3) THEN
    Expr.Compile (e3);
  ELSIF (e2 # NIL)

Thanks to Viggo Kann for reporting the bug, and to Bill Kalsow for supplying the fix! This compiler bug has been fixed in all versions after 3.5.4-B.


M3File.IsEqual compiler bug

This problem applies to all platforms.

The compiler's "M3File.IsEqual" procedure will crash if one of its arguments names a file that does not exist or for some reason cannot be opened. The fix is simple. In the file "m3/m3middle/src/M3File.m3", the last few lines of the "IsEqual" procedure should be changed from:

    FINALLY
      f1.close ();
      f2.close ();
    END;
  END IsEqual;

to

    FINALLY
      IF f1 # NIL THEN f1.close () END;
      IF f2 # NIL THEN f2.close () END;
    END;
  END IsEqual;

Thanks to Louis-Dominique Dubeau for pointing out the bug and suggesting the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


SUBARRAY compiler bug

This problem applies to all platforms.

If you invoke the built-in SUBARRAY operator with too few arguments, the compiler will print a correct error message of the form:

"../src/Main.m3", line 5: too few arguments: M3_BUILTIN.SUBARRAY

and then proceed to crash. Although it prints a useful error message, the compiler should not crash.

The fix is simple. In the file "m3/m3front/src/builtinOps/Subarray.m3", add the following line at the beginning of the "Subarray.CheckPositive" procedure:

    IF e = NIL THEN RETURN NIL END;

Thanks to Rustan Leino for noticing the bug and providing the fix! This compiler bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


new TRY-EXCEPT-ELSE warning

This improvement applies to all platforms.

The semantics of RETURN and EXIT statements are defined by exceptions. Hence, if these statements appear inside the body of a TRY-EXCEPT statement with an ELSE clause, control will be transferred to the ELSE handler.

You should almost never use an ELSE handler to a TRY-EXCEPT statement. If you find that you're using them often, there is probably something wrong with the design of your program. However, for those rare cases where they are necessary, you probably do not expect the execution of RETURN and EXIT statements to transfer control to the ELSE handler. Hence, a new warning has been added to the compiler to point out such situations. If you actually intend for the ELSE clause to catch the RETURN or EXIT, you can add a <*NOWARN*> pragma on the line containing the RETURN or EXIT statement.

To add the new warning to the compiler, edit the source file "m3/m3front/src/misc/Marker.m3". Replace the existing procedures around lines 265-290 by the following:

PROCEDURE ExitOK (): BOOLEAN =
  BEGIN
    FOR i := tos - 1 TO 0 BY -1 DO
      WITH z = stack[i] DO
        IF (z.kind = Kind.zTRYELSE) THEN
          Error.Warn (1, "EXIT will be caught by TRY EXCEPT ELSE clause");
        END;
        IF (z.kind = Kind.zEXIT) THEN RETURN TRUE END;
        IF (z.kind = Kind.zPROC) THEN RETURN FALSE END;
      END;
    END;
    RETURN FALSE;
  END ExitOK;

PROCEDURE ReturnOK (): BOOLEAN =
  BEGIN
    FOR i := tos - 1 TO 0 BY -1 DO
      WITH z = stack[i] DO
        IF (z.kind = Kind.zTRYELSE) THEN
          Error.Warn (1, "RETURN will be caught by TRY EXCEPT ELSE clause");
        END;
        IF (z.kind = Kind.zPROC) THEN RETURN TRUE END;
      END;
    END;
    RETURN FALSE;
  END ReturnOK;

Thanks to Randy Coleburn for pointing out the problem, and to the folks at Critical Mass for supplying the fix. These warning messages have been added in all releases of SRC Modula-3 after 3.5.4-B.


bugs in m3quake

This problem applies to all platforms.

There are three known bugs in m3quake, the version of quake implemented in Modula-3 and integrated into m3build2 (the original version of quake is written in C and called by m3build). All three bugs are in the file "m3/m3quake/src/QMachine.m3". Here are the bugs and patches to the source code required to fix them:

As opposed to the original version of quake, the version written in Modula-3 does not allow hyphens and periods in identifier names. The m3makefile "m3/m3core/src/float/m3makefile" includes several identifiers containing hyphens. However, these ``identifiers'' should really be quoted strings. For the new version of quake to read this makefile, you will have to quote these identifiers. Here are the diffs:

$ diff m3makefile.orig m3makefile
9,10c10,11
< readonly _float_le = [ IEEE, IEEE-le, IEEE-default ]
< readonly _float_be = [ IEEE, IEEE-be, IEEE-default ]
---
> readonly _float_le = [ "IEEE", "IEEE-le", "IEEE-default" ]
> readonly _float_be = [ "IEEE", "IEEE-be", "IEEE-default" ]
17,18c18,19
<   "DS3100"     : [ IEEE, IEEE-le, DS3100 ],
<   "DS3100_OSF" : [ IEEE, IEEE-le, DS3100 ],
---
>   "DS3100"     : [ "IEEE", "IEEE-le", "DS3100" ],
>   "DS3100_OSF" : [ "IEEE", "IEEE-le", "DS3100" ],
25c26
<   "IRIX5"      : [ IEEE, IEEE-be, IRIX5 ],
---
>   "IRIX5"      : [ "IEEE", "IEEE-be", "IRIX5" ],
33,34c34,35
<   "SOLsun"     : [ IEEE, IEEE-be, SOLsun ],
<   "SPARC"      : [ IEEE, IEEE-be, SPARC ],
---
>   "SOLsun"     : [ "IEEE", "IEEE-be", "SOLsun" ],
>   "SPARC"      : [ "IEEE", "IEEE-be", "SPARC" ],
36c37
<   "SUN386"     : [ IEEE, IEEE-le, SUN386 ],
---
>   "SUN386"     : [ "IEEE", "IEEE-le", "SUN386" ],
38c39
<   "VAX"        : [ VAX ]
---
>   "VAX"        : [ "VAX" ]
42c43
<   include_dir (Common)
---
>   include_dir ("Common")

Thanks to Louis-Dominique Dubeau and Jerome Collin for pointing out the bugs and suggesting the fixes! These bugs have been fixed in all releases of SRC Modula-3 after 3.5.4-B.


code generation error related to set types

This problem applies to all platforms.

There is a bug in the implementation of set types that can lead to code generation errors in the front end of the compiler. The fix requires changes to two modules in the m3front package:

Thanks to Carsten Weich for reporting the problem and to the folks at Critical Mass for supplying the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bug in RTType.CheckBrands

This bug applies to all platforms.

There is a bug in the RTType.CheckBrands procedure in the file "m3core/src/runtime/common/RTType.m3". The bug is that the "buckets" array is not being initialized to contain all NIL pointers. The fix is simple. Change the declaration:

    buckets : ARRAY [0..292] OF RT0.TypeDefn;
to the initializaiton:
    buckets := ARRAY [0..292] OF RT0.TypeDefn {NIL, ..};

Thanks to the folks at Critical Mass for discovering this problem and for supplying the fix! This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


bug in packed sets

This bug applies to all platforms.

The compiler crashes for some values of n in a BITS n FOR SET OF T type declaration. The simplest workaround is not to use BITS FOR as a modifier of a SET type, since its use in SRC Modula-3 cannot reduce the natural size of a set.

However, the compiler should not crash, so here is a patch that can be applied to prevent it. In the file "m3/m3front/src/exprs/InExpr.m3", locate the "Prep" and "Compile procedures. In each of those procedures, change the line:

    set := Type.CheckInfo (Expr.TypeOf (p.b), info);
to instead read
    set := Type.Base (Type.CheckInfo (Expr.TypeOf (p.b), info));

Then, you'll have to recompile and ship the compiler from sources. (On Unix platforms, that means rebuilding the packages m3middle, m3linker, m3front, and m3).

Thanks to Peter McKinna for discovering this problem and to the folks at Critical Mass for supplying the fix! This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


bug in RTTipe.GetInt

This patch applies to all platforms.

The procedure RTTipe.GetInt has a bug that was causing the pickling of some types (such as SET types) to fail.

The patch is simple. In the file "m3core/src/runtime/common/RTTipe.m3", there is code at the end of the GetInt procedure around line 251 that says:

      VAR res := 0; BEGIN
        FOR i := 1 TO val DO
          res := Word.Or (Word.LeftShift (res, 8), ptr^);
          INC (ptr, ADRSIZE (ptr^));
        END;
        RETURN sign * res;
      END;

Those lines should be changed to read:

      VAR res := 0;  shift := 0;  BEGIN
        FOR i := 1 TO val DO
          res := Word.Or (res, Word.LeftShift (ptr^, shift));
          INC (shift, 8);
          INC (ptr, ADRSIZE (ptr^));
        END;
        RETURN sign * res;
      END;

The bad code was reading variable-length integer values in big-endian order, but the compiler writes them in little-endian order.

Thanks to Randy Coleburn for pointing out the problem and to Blair MacIntyre and the folks at Critical Mass for supplying the fix! This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


bug in TRACE pragma

This patch applies to all platforms.

When the TRACE pragma is used to monitor changes to a variable declared in a procedure that contains a nested procedure, the compiler generates code that sometimes logs changes to the variable too often, and sometimes logs changes to the variable too infrequently.

The patch is simple. Simply edit the file "m3/m3front/src/values/Procedure.m3", and make the following changes:

  1. Add "Tracer" to the list of IMPORTs.

  2. Add the following code to the very beginning of the body of the "GenBody" procedure (just after the first BEGIN):
        IF (Host.inline_nested_procs)
          AND (p.body # NIL) AND (p.body.level > 0) THEN
          (* make sure outer-level variable initializations are traced
             in the outer procedure, before we enter the nested one.*)
          Tracer.EmitPending ();
        END;
    

  3. Rebuild and ship the m3front package. Once you've rebuilt the m3front library, you'll also have to rebuild and ship the m3 package to rebuild the compiler with the new front-end.

Thanks to Randy Coleburn for reporting the problem and to the folks at Critical Mass for supplying the fix! This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


bug initializing arrays

This patch applies to all platforms.

Certain array initializations can produce code generation errors. The problem is that the compiler mistakenly attempts to initialize the array multiple times.

The fix is simple. In the file "m3/m3front/src/exprs/ArrayExpr.m3", locate the "PrepLiteral" procedure. Change that procedure by moving the last statement (the call to "GenOpenLiteral") up so it is inside the immediately preceding IF statement. The end of the procedure should then read:

    IF (p.offset = 0) THEN
      EVAL Type.CheckInfo (p.solidType, info);
      p.offset := Module.Allocate (info.size, info.alignment,
                                   "*open array literal*");
      CG.Declare_global_field (M3ID.Add ("_array"), p.offset, info.size,
                               Type.GlobalUID(p.solidType));
      EVAL GenOpenLiteral (p, p.offset,
    			   OpenArrayType.OpenDepth (p.tipe),
    			   OpenArrayType.OpenType (p.tipe),
    			   OpenArrayType.EltPack (p.type));
    END;
  END PrepLiteral;

Then rebuild and ship the m3front package. Once you've rebuilt the m3front library, you'll also have to rebuild and ship the m3 package to rebuild the compiler with the new front-end.

Thanks to Carsten Weich for reporting the problem and to the folks at Critical Mass for supplying the fix! This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


better stack overflow handling

This problem applies to all POSIX platforms.

In the current thread implementation on POSIX platforms, an assertion failure occurs if a forked thread overflows its stack. Since many users find this confusing, this patch adds code to print a more helpful message whenever an assertion failure would have occured in the existing code. The new code is triggered when a forked thread writes over the ``seals'' on its stack and control is then transfered to a different thread.

To add the patch, copy the patch file "ThreadPosix.m3" to "m3/m3core/src/thread/POSIX/ThreadPosix.m3". Then rebuild and reship m3core.

Thanks to the folks at Critical Mass for supplying this patch! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


bug generating position-independent code

This problem applies to all platforms using the gcc-based back-end.

There is a bug in the gcc-based code generator. One manifestation of this bug is that it causes PIC code generated for the i386 architecture to be incorrectly. However, it should be applied to all platforms that use the gcc-based back-end. In the file "m3cc/gcc/m3.c", the code around line 2330 reads:

    case M3_DECLARE_SEGMENT: {
      STRING (n);
      TYPEID (id);
      RETURN_VAR (v, VAR_DECL);
      
      DECL_NAME (v) = DECL_ASSEMBLER_NAME (v) = fix_name (n, id);
      DECL_EXTERNAL (v) = 0;
      /* we really don't have an idea of what the type of this var is; 
         let's try to put something that will be good enough for all
         the uses of this var we are going to see before  
         we have a bind_segment */
      fix_type (v, T_struct, BIGGEST_ALIGNMENT, BIGGEST_ALIGNMENT);
      TREE_UNSIGNED (TREE_TYPE (v)) = 1;
      TREE_STATIC (v) = 1;

Just after the line "DECL_EXTERNAL (v) = 0;" and before the long comment, add the following line:

      TREE_PUBLIC (v) = 1;

Thanks to John Polstra for reporting the bug and supplying the fix. This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bug generating Word comparison code

This problem applies to all platforms using the gcc-based back-end.

The current gcc-based back-end generates bad code for the comparison procedures "LT", "LE", "GT", and "GE" in the "Word" interface. Although values of type "Word.T" are unsigned, the generated code treats the arguments as signed values.

The fix is simple. In the "m3cc/gcc/m3.c" source file, add the following function just before the "condop" function around line 1523:

static void compareop (o, t)
   enum tree_code o;
   tree t;
{
  tree t1 = m3_cast (t, stack [tos-1]);
  tree t2 = m3_cast (t, stack [tos-2]);
  TREE_UNSIGNED (t1) = TREE_UNSIGNED (t);
  TREE_UNSIGNED (t2) = TREE_UNSIGNED (t);
  stack [tos-2] = m3_build2 (o, t_int, t2, t1);
  tos --;
}

Then, around line 2905, change the lines for the six comparison functions to use the new "compareop" function instead of the "binaryop" function, and change each of their second arguments from "t_int" to "t", like this:

    case M3_EQ:       { MTYPE (t); compareop (EQ_EXPR, 	   t); break; }
    case M3_NE:       { MTYPE (t); compareop (NE_EXPR, 	   t); break; }
    case M3_GT:       { MTYPE (t); compareop (GT_EXPR, 	   t); break; }
    case M3_GE:       { MTYPE (t); compareop (GE_EXPR, 	   t); break; }
    case M3_LT:       { MTYPE (t); compareop (LT_EXPR, 	   t); break; }
    case M3_LE:       { MTYPE (t); compareop (LE_EXPR, 	   t); break; }

Thanks to Charles Garrett for pointing out the bug and to the folks at Critical Mass for supplying the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bug in Stackx86.m3

This problem applies to all platforms using the integrated Intel back-end.

There is a bug in the "push" procedure of the file "m3/m3back/src/Stackx86.m3". The description of the bug is rather complicated, but the fix is simple. The assignment statement:

          stack0.loc := OLoc.fstack;
on or around line 653 must be moved to just before the immediately preceding IF, so the final snippet of code looks like this:
      IF mvar.t >= Type.Reel AND mvar.t <= Type.XReel THEN
        stack0.loc := OLoc.fstack;      (* <-- MOVE HERE *)
        IF mvar.var.loc = VLoc.temp AND mvar.var.parent # t.current_proc THEN
          unlock(t);
          indreg := pickreg(t, RegSet {}, TRUE);
          corrupt(t, indreg);

          t.cg.get_frame(indreg, mvar.var.parent, t.current_proc);
          t.cg.f_loadind(t.cg.reg[indreg], mvar.o + mvar.var.offset, mvar.t);

        ELSE
                                        (* <-- WAS HERE *)
          t.cg.fstack_push(mvar);
        END
      ELSE

Thanks to Jerome Collin for noticing this bug and supplying the fix! This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


bug in M3x86.m3

This problem applies to all platforms using the integrated Intel back-end.

Some updates have been made to the Intel code generator. Among other things, the code generator now handles both direct and indirect procedure calls. To apply the patch, simply copy the file "M3x86.m3" to "m3/m3back/src/M3x86.m3". Then rebuild and ship the m3back package.

Thanks to the folks at Critical Mass for supplying this fix! This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


bug in RTHeapDepC.c

This problem applies to the DS3100, FreeBSD, FreeBSD2, and SPARC platforms.

In the file "m3/runtime/src/<architecture>/RTHeapDepC.c", the lines:

      { char **a; for (a = argv; *a; a++) MAKE_READABLE(**a); }
      { char **e; for (e = envp; *e; e++) MAKE_READABLE(**e); }

should be:

      { char **a; for (a = argv; *a; a++) MAKE_READABLE(*a); }
      { char **e; for (e = envp; *e; e++) MAKE_READABLE(*e); }

Thanks to Jorge Stolfi for reporting this bug. Bill Kalsow provided the fix. This bug has been fixed in all releases of SRC Modula-3 after 3.5.3.


bug in quotactl signature

This problem applies only to the FreeBSD2 platform.

FreeBSD now has a prototype for the library function "quotactl" in its header files, and that prototype disagrees with the function definition in "RTHeapDepC.c". That causes the compilation of "RTHeapDepC.c" to fail.

To fix the bug, edit the file "m3/m3core/src/runtime/FreeBSD2/RTHeapDepC.c". In the "quotactl" function, change the type of the "addr" formal argument from "void *" to "char *", like this:

int quotactl(path, cmd, uid, addr)   /* ok */
const char *path;
int cmd, uid;
char *addr;
{ int result;

Thanks to John Polstra for noticing the problem and suggesting the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bad Unix signal constants

This problem applies only to the FreeBSD2 platform.

Certain constants related to Unix signals are incorrect. To get the correct contants, simply copy the file "Usignal.i3" to "m3core/src/unix/freebsd-2/Usignal.i3".

Thanks to John Polstra for noticing the problem and providing the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


bad M3_NONBLOCK constant

This problem applies only to the IBMR2 platform.

On this platform, there is a bad definition of the unix constant M3_NONBLOCK in the file "m3/m3core/src/unix/aix-3-2/Unix.i3". The correct definition (around line 771 of that file) is:

  M3_NONBLOCK = O_NDELAY;       (* -1 => would block, 0 => EOF *)

Thanks to Joe Morrison for detecting the bug and for providing the fix! This change has been made in all releases of SRC Modula-3 after 3.5.4-B.


no X11 shared memory extension

This problem applies to the IBMR2 platform and to all other platforms whose X11 servers do not include the shared memory extension.

The symptom of the problem is that linking any program against the Trestle "ui" library produces the following undefined symbols:

.XShmQueryExtension, .XShmGetEventBase, .XShmAttach, .XShmDetach, .XShmPutImage, .XShmCreateImage

The solution to the problem is to provide a ``null'' implemention of Trestle's XSharedMem interface. There are two steps to the patch:

  1. First, copy the file XNoSharedMem.m3 to the new file "m3/ui/src/xvbt/XNoSharedMem.m3".
  2. Then, edit the file "m3/ui/src/xvbt/m3makefile" as follows. Replace the line:
      Module ("XSharedMem")
    
    by the lines:
      Interface ("XSharedMem")
      implementation ("XNoSharedMem")
    
Then rebuild and ship the "ui" package.

Thanks to Pedo Giffuni, Paul McJones, and Mike Douglass for noticing the problem, and to Mike Douglass for providing the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.

In releases of SRC Modula-3 after 3.5.4-B, the problem has actually been fixed in a more general way. Each platform specific-template defines a new readonly variable, like this:

  % Does your X11 server have the shared memory extension?
  readonly X11_WITH_SHARED_MEM = "TRUE"
For those platforms like IBMR2 that don't have the shared memory extension, the variable is defined to be "" (the empty string). Then, the relevant lines in the file "m3/ui/src/xvbt/XNoSharedMem.m3" become:
  Interface ("XSharedMem")
  if X11_WITH_SHARED_MEM
    implementation ("XSharedMem")
  else
    implementation ("XNoSharedMem")
  end

Thanks to the folks at Critical Mass for suggesting this solution.


fstat, stat undefined

This problem applies only to the LINUX platform.

While building the Modula-3 compiler, you may see error messages like the following:

middle/LINUXELF/libm3middle.a ../../libm3/LINUXELF/libm3.a ../../m3core/LINUXELF/libm3core.a -lm
FilePosix_m.o(.text+0x129): undefined reference to `fstat'
FilePosix_m.o(.text+0x30a): undefined reference to `fstat'
FilePosix_m.o(.text+0xa82): undefined reference to `fstat'
FSPosix_m.o(.text+0x69f): undefined reference to `fstat'
FSPosix_m.o(.text+0xdb0): undefined reference to `stat'
ProcessPosix_m.o(.text+0x451): undefined reference to `stat'
ProcessPosix_m.o(.text+0x697): undefined reference to `stat'
*** error code 1
"/boot-LINUXELF/m3build/templates/COMMON.BOOT", line 58: command execute failed
*** call stack ***
"/boot-LINUXELF/m3build/templates/COMMON.BOOT", line 58: call to built-in exec
"./make.boot", line 28: call to procedure boot_prog
This is a known problem with V 1.2x of the LINUX ELF distribution. Geoff Wyant says:

The standard include file /usr/include/sys/stat.h declares 'fstat' and 'stat' as being inline functions. A simple workaround is to make a local library named 'libstat.a' that implements fstat and stat (just copy the functions from stat.h) and link this with the generated compiler (you'll have to add it to boot-LINUXELF/m3/make.boot) and specify it as one of the libraries that always gets linked with an M3 program (such as -lm). Yes, it's a hack, but it's quicker than fixing libm3 to do the write thing on V1.2 of Linux, especially since this problem is fixed in Linux 1.3 (or so the rumor goes...)
As another solution in the same vein, Carsten Weich suggests adding the following C file to the m3core library:
/* Carsten Weich, June 1995
 *
 * "stat" and "fstat" are declared as "__inline__" in
 * "/usr/include/sys/stat.h". These inline calls are not
 * accessible to the linker, so Modula-3 routines cannot
 * call them.
 *
 * This hack replicates the inline calls as regular functions.
 */

int stat (p1, p2)
char *p1, *p2;
{
    return _xstat(1, p1, p2);
}

int fstat (f, p)
int f;
char *p;
{
    return _fxstat(1, f, p);
}

Thanks to Michael Nonweiler and Matt Henley for reporting the problem. The problem has not been fixed in the Modula-3 sources, since it is really a problem with the Linux ELF distribution, and is supposed to be corrected in future Linux ELF releases.


stack overflow due to bad writev

This problem applies only to the LINUX/LINUXELF platform. As of 13-Aug-96, this patch has been superceded by a later patch.

Modula-3 thread stacks on Linux are not dynamically expandable. Most of the versions of Linux in use today have a version of the writev function that copies all of it's data to the stack before calling write. This can cause stack overflows, since the Trestle graphics system passes pixmaps to X via the X library, which uses writev to pass the actual data.

One solution to this problem is to use a version of Linux with kernel support for writev. Linux kernels since version 1.3.40 have native (kernel) readv/writev functions; in particular, versions of the Linux libc library since version 5.2.12 do not supply implementations of these functions in the library.

If you are not using one of these newer libraries, you can work around the problem by substituting your own version of writev. We've written two different implementations that you can try:

writev_slow.c
This version is like the default implementation, but it allocates its buffer on the heap instead of the stack. Like the default implementation, this version is fairly slow because it has to copy the bytes in the argument vector into the buffer.

writev_sleazy.c
This version does not copy the bytes from the argument vector into a separate buffer, but instead writes them directly using write. This version is faster than the slow version because it doesn't do an extra copy. The problem with this version is that it does multiple writes. This works fine when passing large arguments to an X server, but it may not work when writing to file descriptors associated with low-level ``devices'' like UDP sockets where making multiple write calls violates the writev semantics.

To use either of these alternative implementations, just copy one or both of the above files to the directory "m3core/src/Csupport/LINUXELF", edit the m3makefile in that directory to include a c_source line for the new source file, and then rebuild and reship m3core.

Thanks to Paul McJones and the folks at Critical Mass for diagnosing the problem and providing the fix! Both alternative versions of writev have been included in all releases of SRC Modula-3 after 3.5.4-B, but the lines that include them in the m3makefile are commented out.


incremental garbage collector

This patch applies only to the LINUXELF platform.

Michel Dagenais has managed to get the incremental virtual-memory based garbage collector working on the LINUXELF platform! To install the new collector, follow these steps:

  1. Copy the following files to the directory "m3/m3core/src/runtime/LINUXELF/":

  2. Edit the existing file "m3/m3core/src/runtime/LINUXELF/m3makefile" to include the new line:
    c_source       ("RTHeapDepC")
    

  3. Edit the existing file "m3/m3core/src/runtime/LINUXELF/RTMachine.i3" to initialize "VMHeap" to "TRUE", and add the following two lines immediately after that definition:
    <*EXTERNAL*> VAR RTHeapRep_Fault: ADDRESS;  (* => RTHeapRep.Fault *)
    <*EXTERNAL*> VAR RTCSRC_FinishVM: ADDRESS;  (* => RTCollectorSRC.FinishVM *)
    

  4. Copy the following four existing files to the directory "m3/m3core/src/unix/linux/":

Thanks to Michel Dagenais for supplying this patch! This patch has been installed on all versions of SRC Modula-3 after 3.5.4-B.


timezone support

This patch applies only to the LINUX/LINUXELF platform.

The current release does not include timezone support on the Linux platforms. This patch provides that support. To apply the patch, follow these steps:

  1. Edit the file "m3/m3core/src/time/POSIX/DateLinux.m3". First, add "M3toC" to the list of imports. Then, change the lines
           date.offset  := 0; (* Linux doesn't support time zones yet... *)
           date.zone    := Unknown;
    
    to read
           IF tm.tm_isdst = 0 THEN
             date.offset := Utime.timezone;
             date.zone   := M3toC.CopyStoT (Utime.tzname[0]);
           ELSIF tm.tm_isdst > 0 AND Utime.daylight # 0 THEN
             date.offset := Utime.altzone;
             date.zone   := M3toC.CopyStoT (Utime.tzname[1]);
           ELSE
             date.offset := 0;
             date.zone   := Unknown;
           END;
    
  2. Copy the existing file Utime.i3 to the directory "m3/m3core/src/unix/linux/". This is the same version of the file supplied in step 4 of the previous patch, so you don't need to re-copy the file if you've already installed that patch.

After making these changes, you'll have to rebuild and reship the m3core library.

Thanks to Michel Dagenais for supplying this patch! This patch has been installed on all versions of SRC Modula-3 after 3.5.4-B.


incremental GC readv/writev fix

This patch applies only to the LINUXELF platform. It assumes you have already applied the incremental garbage collector patch. This patch also supercedes an earlier patch to the implementation of the writev system call. This patch uses the user-level implementation referred to as "writev_sleazy" in that previous patch.

On some LINUXELF systems, the readv() and writev() system calls are not implemented as kernel calls. The initial incremental GC patch got the writev() system call correct, but not the readv() system call. This patch makes the two cases symmetric.

This patch also includes a change to the writev() implementation on systems where writev() is not implemented as a kernel call. The change is necessary because the user-level implementation of writev() included with some LINUXELF systems would allocate huge buffers on the stack, leading to thread stack overflows. Since the X window system library uses writev() to paint large pixmaps, many people were experiencing thread stack overflows. This version tests if your system has a user-level version of writev(), and if so, provides an alternate implementation that does not consume large amounts of stack space.

To install the patch, simply copy "RTHeapDepC.c" to the file "m3/m3core/src/runtime/LINUXELF/RTHeapDepC.c".

Thanks to the folks at Critical Mass for discovering this problem and for supplying the fix! This bug has been fixed in all versions of SRC Modula-3 after 3.5.4-B.


race condition in thread runtime

This problem applies only to the NT386 platform.

There is a race condition between the thread runtime and the garbage collector. A window of time exists between the time a new Thread.T is allocated and the time when the Win95/NT thread actually starts running. During that interval, the collector can move the Thread.T. When the new threads starts executing in this case, it is confused!

The fix requires replacing the module "m3core/src/thread/WIN32/ThreadWin32.m3". However, this fix has been superseded by a more extensive fix to the NT386 runtime described below, in which both "ThreadWin32.m3" and another file in the runtime need to be replaced.

Thanks to the folks at Critical Mass for supplying the initial version of this fix!


bugs in Windows garbage collector

This problem applies only to the NT386 platform. It supercedes the thread runtime patch described above.

There were two bugs in the garbage collector on Windows platforms. One was that the collector could be moving data around in the heap while other threads were running. The other was a bug in Windows that reports bogus stack pointer values for suspended threads.

To get the two fixes, you need to install the following two files:

Thanks to the folks at Critical Mass for supplying these fixes! These bugs have been fixed in all releases of SRC Modula-3 after 3.5.4-B.


FS.Rename bug on Windows 95

This problem applies only to the NT386 platform, and to Windows 95 platforms in particular. This patch is subsumed by the more general OS patches described below.

The Windows/NT function WinBase.MoveFileEx used by the FS.Rename procedure is not implemented on Windows 95. Here is a different definition of that procedure for Windows 95 that also works on Windows/NT. This version replaces the Rename procedure in "m3/libm3/src/os/WIN32/FSWin32.m3":

PROCEDURE Rename(p0, p1: Pathname.T) RAISES {OSError.E} =
  VAR err: INTEGER;
  BEGIN 
    IF WinBase.MoveFileEx(M3toC.TtoS(p0), M3toC.TtoS(p1),
                          WinBase.MOVEFILE_REPLACE_EXISTING) = 0 THEN
      err := WinBase.GetLastError();
      IF (err = WinError.ERROR_CALL_NOT_IMPLEMENTED) THEN
        (* MoveFileEx is not implemented on Win95. *)
        IF WinBase.MoveFile(M3toC.TtoS(p0), M3toC.TtoS(p1)) = 0 THEN
          OSErrorWin32.Raise();
        END;
        RETURN;
      END;
      OSErrorWin32.Raise0(err)
    END
  END Rename;

Thanks to the folks at Critical Mass for noticing this problem and for supplying the fix! This problem has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


OS improvements for Win32

This problem applies only to the NT386 platform, and to Windows 95 platforms in particular. This patch subsumes the FS.Rename patch described above.

Bill Kalsow has made several improvements to the operating system (OS) implementations on the NT386 platform. To get the improvements, you need to install the following three files:

Thanks to the folks at Critical Mass for supplying these patches! They have been applied in all releases of SRC Modula-3 after 3.5.4-B.


command-line argument separation bug

This problem applies only to the NT386 platform.

There is a bug in the code that separates command-line arguments on Win32 platforms. On these platforms, the command-line is given to the Modula-3 run-time as a single string; the run-time must separate this string into words. The existing code uses spaces to delimit the words. The fix is to also use other whitespace characters like tabs and newlines to separate the words.

To apply the patch, copy the file RTArgs.m3 to the file "m3/m3core/src/runtime/WIN32/RTArgs.m3".

Thanks to Paul McJones for pointing out the problem, and to the folks at Critical Mass for supplying the fix! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


terminal reading bug

This problem applies only to the NT386 platform.

The code for reading from a terminal is broken: it is implemented by the same code for reading from a regular file, which ignores its "mayBlock" argument. Hence, the code for reading from a terminal always blocks. This was causing higher-level code, such as "Rd.CharsReady" not to work.

The patch is to copy the file FileWin32.m3 to the directory "m3/libm3/src/os/WIN32/". You will then have to rebuild and ship the libm3 library. This patch supercedes the previous patch to FileWin32.m3.

Thanks to Blair MacIntyre for pointing out the bug and to the folks at Critical Mass for supplying the fix! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


terminal reading bug (again)

This problem applies only to the NT386 platform.

The previous patch to "FileWin32.m3" did not work for all kinds of terminals. In particular, the previous version of read would never return any data for "comN" files. This patch fixes that problem. It supercedes both previous versions of "FileWin32.m3".

To apply the patch, simply copy the patch file FileWin32.m3 to the directory "m3/libm3/src/os/WIN32/". You will then have to rebuild and ship the libm3 library.

Thanks to Blair MacIntyre for noticing the bug and supplying the fix! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


startup race in Trestle

This problem applies only to the NT386 platform.

There is a race condition in Trestle startup on the NT386 platform. The bug is a classic one: a condition was being signalled without an associated variable. The end of the "CreateTrestle" procedure in the file "WinTrestle.m3" contains:

    LOCK mu DO
      Thread.Wait (cond, mu);
    END;

The problem is that without an explicit variable to test, the condition variable can be signalled before the above statement is executed. Hence, the signal is never received, and the thread that executes this statement deadlocks.

The initial version of this patch was relative to a more recent source file than the one distributed with the latest release. Hence, it didn't work when applied to the latest publicly available software. See this later version for a correct patch.

Thanks to John Huntley for pointing out that the initial patch didn't work!


TCP timeout bug

This problem applies only to the NT386 platform.

The implementation of TCP on the NT386 platform can lead to very long timeouts at connection time if the other end is not available (for example, when calling "NetObj.Export" when no Network Object daemon is running).

To apply the patch, copy the file TCP.m3 to the existing file "m3/tcp/src/WIN32/TCP.m3". Then rebuild and ship the "tcp" package.

Thanks to Blair MacIntyre for noticing the problem and supplying the fix! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


Obliq path separator on Win32

This problem applies only to the NT386 platform.

The Obliq parser has the colon character hard-wired into it as the character that separates directory names in a search path. But on Win32 platforms, the semicolon character is used instead (go figure). This patch describes how to change the Obliq parser to provide support for both POSIX and Win32 platforms. Follow these steps, all in the directory "m3/obliqparse/src/" :

  1. Edit the file "ObFrame.i3". Change the constant declaration
    CONST 
      SearchPathSeparator = ':';
    
    to instead read:
    VAR (* READONLY after initialization *) 
      SearchPathSeparator: CHAR;
    

  2. Edit the "m3makefile". Add the following lines just after the declarations of all the modules:
    if equal (OS_TYPE, "WIN32")
      implementation("ObPathSepWin32")
    else if equal (OS_TYPE, "POSIX")
      implementation("ObPathSepPosix")
    else
      error ("obliqparse: unrecognized OS: " & OS_TYPE & CR)
    end end
    

  3. Copy the new files ObPathSepWin32.m3 and ObPathSepPosix.m3 to the source directory.

  4. Rebuild and ship the "obliqparse" package. You'll probably also have to relink some of the other Obliq packages that import "obliqparse".

Thanks to Blair MacIntyre for noticing the problem and supplying the fix! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


New WinIoctl interface

This addition applies only to the NT386 platform.

Roumen Roupski has supplied us with a Modula-3 version of the windows "winioctl.h" interface. To install the new interface and its implementaiton, follow these simple steps:

  1. Copy the files "WinIoctl.i3" and "WinIoctl.m3" to the directory "m3core/src/win32/".

  2. Add the line
    Module     ("WinIoctl")
    
    to the file "m3core/src/win32/m3makefile".

  3. Rebuild and ship the "m3core" package.

Thanks to Roumen Roupski for supplying the new interface and to the folks at Critical Mass for supplying the implementation! This patch has been applied in all releases of SRC Modula-3 after 3.5.4-B.


startup race in Trestle (again)

This patch applies only to the NT386 platform. It is a (hopefully) correct patch for a previously described problem.

To apply the patch, edit the file "m3/ui/src/winvbt/WinTrestle.m3". Toward the very end of the file, replace the declaration of the global variable "cond" and of the procedures "CreateTrestle" and "MessengerApply" by the following code:

VAR
  messenger_started := FALSE;
  cond := NEW (Thread.Condition);
  (* used to signal the main thread that "trsl.hwnd" has been created. *)

PROCEDURE CreateTrestle () =
  VAR mu := NEW (MUTEX);
  BEGIN
    trsl := NEW(T);
    DoHackInit(trsl);

    trsl.st := NEW(VBT.ScreenType);
    (* The st is irrelevant except that it must be non-NIL so that
       marking the trsl for redisplay is not a noop. *)

    LOCK trsl DO
      trsl.vbts := NEW(AddrRefTbl.Default).init();
    END;

    trsl.screen := WinScreenType.New(trsl);

    trslThread := Thread.Fork (NEW (Thread.Closure, apply := MessengerApply));
    LOCK mu DO
      WHILE NOT messenger_started DO Thread.Wait (mu, cond); END;
    END;
  END CreateTrestle;

PROCEDURE MessengerApply (<*UNUSED*> cl: Thread.Closure): REFANY =
  VAR
    wc    : WinUser.WNDCLASS;
    status: WinDef.BOOL;
    cs    : WinUser.CREATESTRUCT;
    class := M3toC.CopyTtoS("Trestle Desktop");
    msg   : WinUser.MSG;
  BEGIN
    (* First, we have to register a window class for the "null window". *)
    hInst := RTLinker.info.instance;

    wc.style := WinUser.CS_HREDRAW + WinUser.CS_VREDRAW;
      (* other styles to consider: 
         CS_GLOBALCLASS, CS_OWNDC, CS_PARENTDC, CS_SAVEBITS *)
    wc.lpfnWndProc := WindowProc;
    wc.cbClsExtra := 0;
    wc.cbWndExtra := 0;
    wc.hInstance := hInst;
    wc.hIcon := WinUser.LoadIcon (NIL, WinUser.IDI_APPLICATION);
    wc.hCursor := WinUser.LoadCursor (NIL, WinUser.IDC_ARROW);
    wc.hbrBackground := NIL;
    wc.lpszMenuName := NIL;
    wc.lpszClassName := class;

    status := WinUser.RegisterClass (ADR(wc));
    <* ASSERT status # 0 *>

    (* Now, we can actually create the "null window" *)
    trsl.hwnd := WinUser.CreateWindow(
                    class, NIL, WinUser.WS_DISABLED,
                    WinUser.CW_USEDEFAULT, WinUser.CW_USEDEFAULT,
                    WinUser.CW_USEDEFAULT, WinUser.CW_USEDEFAULT, 
                    NIL, NIL, hInst, ADR(cs));
    <* ASSERT trsl.hwnd # NIL *>

    (* Signal "CreateTrestle" that the null window is created. *)
    messenger_started := TRUE;
    Thread.Signal (cond);

    (* Start a Windows Timer with 0.1 sec clicks *)
    trsl.timerId := WinUser.SetTimer (trsl.hwnd, 1, 100, NIL);

    (* start the message loop for all windows belonging to this Trestle *)
    WHILE WinUser.GetMessage (ADR(msg), NIL, 0, 0) = True DO
      EVAL WinUser.TranslateMessage (ADR(msg));
      EVAL WinUser.DispatchMessage (ADR(msg));
    END;

    (* received WM_QUIT message -- exiting *)
    RETURN NIL;
  END MessengerApply;

Then rebuild and ship the "ui" library.

Thanks to the folks at Critical Mass for noticing the problem and for providing the fix! This bug has been fixed in all releases of SRC Modula-3 after 3.5.4-B.


library libaio.a not found

This problem applies only to the SOLgnu platform.

When you install SRC Modula-3 on the SOLgnu platform (that is, a Sun machine running the Solaris operating system using GCC as the C compiler), you will most likely get the following error message when building the m3build package:

---- building m3build ---- 
creating m3build... 
gcc -compat-bsd -c m3build.c 
../../m3-gcc -compat-bsd -Xlinker -dy -Xlinker -Bstatic-Xlinker -dy -Xlinker 
-Bstatic -o m3build m3build.o  
ld: fatal: library -laio: not found 
...

Most likely, you will have a shared version (libaio.so) of the libaio library installed in /usr/lib, but no static libaio.a version. Geoff Wyant says:

The problem is an unfortunate interaction between Solaris-2, GCC, and the way the GCC compiler and Modula-3 driver get built. GCC by default specifies "-laio" as one of the libraries to always build with. This library is provided only as a shared library for Solaris-2 (it's there for compatibility with SunOS 4.x). When the bootstrap M3 driver is built, it wants only static libraries; and as you have seen there is no static version of the libaio library.

Providing you can rebuild GCC, there is an easy workaround: take '-laio' out of the GCC Solaris configuration file, namely, config/sparc/sol2.h. GCC doesn't seem to use or need the libaio library, and will build successfully without it.

Jerry Leichter suggests another alternative:

  1. Copy any valid library to a file named libaio.a in some directory. (I used libc.a; it makes no difference, since nothing will actually be taken from the library. You could also use a link, I suppose.)
  2. If you put the libaio.a file in a directory the linker would not normally search, make sure LD_LIBRARY_PATH includes a reference to it.
  3. Once the boot is complete, you can delete the fake libaio.a file; it won't be needed any more.

Tim Mann suggests that an easier solution might be possible: simply supply your own empty library named "libaio.a". Tim says: ``The exact details of this (whether an empty file is good enough, or if it has to be created by ar, and exactly what directory to put in) remain to be worked out by someone who's in a position to try it.'' Jerry reports that he tried this approach, but that he couldn't get it to work.

Thanks to Jack Greenbaum, Huw Evans, and Basab Maulik for reporting the problem.


link failing due to "-ztext" link option

This problem applies only to the SOLsun platform.

When building the libm3core.so library, the link line looks something like this (ellipses have been added to shorten the list):

/usr/ccs/bin/ld -G -ztext -o libm3core.so hand.o dtoa.o RTBuiltin.o
RTHooks.io RTHooks.mo RT0.io RT0.mo RTAllocator.io RTAllocator.mo
RTAllocStats.io RTAllocStats.mo ... TextConv.io TextConv.mo
Fingerprint.io Fingerprint.mo Poly.io Poly.mo PolyBasis.io
PolyBasis.mo Main.io WeakRef.io WeakRef.mo Word.io Word.mo

However, due to the "-ztext" option passed to the linker, you will get link errors like this:

Text relocation remains                       referenced
    against symbol                  offset      in file
.div                                0x6c        hand.o
.div                                0x9c        hand.o
.div                                0xec        hand.o
.div                                0x124       hand.o
.rem                                0x1cc       hand.o
.rem                                0x200       hand.o
.rem                                0x258       hand.o
.rem                                0x28c       hand.o
tables_built                        0xb20       hand.o
tables_built                        0xb24       hand.o
 
...

_setjmp                             0x24        RTThreadC.o
_longjmp                            0x4c        RTThreadC.o
abort                               0x20        RTStackC.o
abort                               0x50        RTStackC.o
abort                               0x84        RTStackC.o
abort                               0xb8        RTStackC.o

Geoff Wyant says:

This problem is easily fixed. Remove the "-ztext" option from the SOLsun template where shared libraries are built. This option doesn't need to be there, and its only use seems to be to complain about normal situations.

In particular, in the file "m3/m3build/templates/SOLsun" the line (around line number 272) containing "ztext" should be changed from:

        exec ("/usr/ccs/bin/ld -G -ztext -o", lib_so, COMPILE_OBJECTS)

to read:

        exec ("/usr/ccs/bin/ld -G -o", lib_so, COMPILE_OBJECTS)

Thanks to David Cole for reporting the problem, and to Geoff Wyant for providing the fix. This problem has been corrected in all versions of SRC Modula-3 after 3.5.4-B.


undefined X-related symbols at link-time

This problem applies only to the SPARC platform.

On the SPARC platform (SunOS 4.1.x), some people have reported getting undefined symbols at link-time. The symbols should be defined by the X window system. Here is a typical error message:

  ld: Undefined symbol
     __XtInherit
     _get_wmShellWidgetClass
     _get_applicationShellWidgetClass
     _XtToolkitInitialize

Spencer Allain writes:

Ok, this should probably be placed in the beware of SunOS 4.1.x README even though it's has nothing to do with Modula-3 ;-)

There are a couple of solutions. The "easiest" can be implemented if you have X11 installed. The problems you see above are related to the OpenWindows implementation of X11. If you have the real X11, simply put this first in your LD_LIBRARY_PATH environment variable and things should work great.

If you only have OpenWindows installed, well.... here's an excerpt from the X FAQ. I believe the libXt Jumbo patch will also remedy your __XtInherit problem:

Subject: 112) What is this "_get_wmShellWidgetClass undefined" error?

In SunOS 4.1.2 Sun fixed a shared-library bug in ld which conflicts with the way X builds the shared Xmu library, causing these symbols, notably, to be undefined when building some X11 clients on SunOS 4.1.[23]:

_get_wmShellWidgetClass
_get_applicationShellWidgetClass

Compiling "-Bstatic -lXmu -Bdynamic" is overkill; be sure to set OSTeenyVersion correctly in the config/sun.cf file and rebuild X11R5.

To solve the problem if you are using OpenWindows 3.0 (X11R4-based Xt), please contact your local Sun office and request the following patches:

Patch i.d.  Description
100512-02   4.1.x OpenWindows 3.0 libXt Jumbo patch
100573-03   4.1.x OpenWindows 3.0 undefined symbols when using
                  shared libXmu
[Greg Earle, earle@Sun.COM; 7/92]

Thanks to Spencer for suggesting the fix!


[Modula-3 home page]

m3-request@src.dec.com
Last modified on Wed Sep  4 09:44:11 PDT 1996 by heydon
Copyright (C) 1992, 1996, Digital Equipment Corporation. All rights reserved.
See the COPYRIGHT for a full description.