Known SR Limitations and Deficiencies
last updated July 21, 1989

This list contains most of the problems we are aware of.  A few obscure bugs
that cannot be described simply, or are not well enough understood to describe
simply, have been omitted.



GENERAL WARNINGS:

Source and object files are generally expected to reside in the current
directory;  explicit paths elsewhere don't always work.



COMPILE TIME PROBLEMS:

Any message containing the phrase "compiler malfunction" indicates a bug in
the compiler.  Any error message referencing "./resource.c" or "./resource.h"
indicates that the compiler has generated bad code.

Type inference on variable declarations works only for basic types, as per
the reference manual.  Other types (e.g. arrays) can cause ugly failures
including core dumps.

Records:
    A string(*) should not appear in a record, and will cause a malfunction.
    Arrays inside records cause problems, as do fixed-length strings.
    "null" and "noop" don't work in a record constructor.

String(*):
    A string(*) resource const or var will lead to a malfunction
    Dereferencing a "ptr string(*)" can cause a malfunction.
    A procedure returning "string(*)" causes a malfunction when called.

Slices:
    Slices with constant subscripts fail if the slice size is zero [legal].
    Similarly, constant slices of negative length [illegal] also fail.
    Any slice of an array of strings will cause a malfunction.
    Assigning a cast to a slice of a char array will cause a malfunction.
    Slices of a matrix must select a contiguous portion.

Arrays:
    A named enum type provokes a compiler malfunction if used as an array.
    Bad code is generated for initializing an imported constant array
	dimensioned by an enumerated type.
    Null and noop can't be used in array constructors; a malfunction may occur.
    A variable-sized vector constructor cannot be used as a parameter.
	For example, f(([10] 0)) will work but f(([n] 0)) will fail.
	With a predefined function, even a fixed-size constructor malfunctions.
    The repetition expression in a vector constructor is evaluated twice.
    A scalar constant cannot be passed as an arg to an op expecting an array.

Capabilities:
    "type x = cap y" sometimes leads to a compiler malfunction.
    An implicit cast (to capability) is not performed if an operation name
	is used as an argument to a record constructor.
    A compiler malfunction can result from a proc argument that is a defined
	type that is a pointer to a defined type that is a capability.
    "null" & "noop" aren't accepted as args when a capability is expected.

SR may falsely report signature mismatches when passing parameters
to a defined type that is a pointer.

"noop" is not accepted as a file argument when calling a predefined operation.

"name truncated to 30 characters" reports the wrong line number --
then gets a segmentation fault!

Error messages resulting from syntax errors can be misleading or confusing.



RUNTIME PROBLEMS:

Sometimes the generated code frees memory at the wrong time, usually
causing a core dump.  For example, if the value of the first half of a
compound conditional causes the test in the second half to be bypassed,
and the second test involves a non-optimizable procedure call, a bad call
is made.  In an even more pathological case, a call to free memory can be
moved from the end of one operation into the (lexically) next operation.

There is no automatic detection of deadlock for multiple-machine programs.
Use an explicit "stop" statement.

Error messages can sometimes occur, due to race conditions, during normal
termination of multi-machine programs.  These can be caused, for example,
if X exits while Y is sending to it.

Havoc results if a process is killed before all processes that it creates
complete their initial code sections, or if a proc called from one resource
kills its invoker's resource.

Subscripting fails if an array of string(*) elements has a bound of *.

Record casts fail if the assignment of any element requires conversion between
character array and string.

Comparisons of two records for equality may give incorrect results because the
records are compared as a whole, without regard to the (undefined) contents of
any implicit filler fields.

Any use of a string-valued procedure (or external) may potentially call it
twice instead of once.

Output blocking can halt an entire virtual machine, not just one process.
This is a consequence of a deliberate decision to maintain compatibility
with the standard I/O library.  Input can only block a single SR process,
and in fact output blocking appears to happen on Vaxes but not Suns.

The current implementation of destroy kills all processes only after the final
code has completed, contrary to what is stated in the revised report.

Replying from final code doesn't work, and causes a runtime abort.

srx generates an incorrect network file path if the executable is found
not in the current directory but in the shell search path.

A call to read a single character into an element of a character array
instead reads the whole array.

A segmentation fault can occur if an op declaration follows a return
inside a proc, and the return is executed.



PROBLEMS WITH SUPPORTING PROGRAMS:

Keywords in strings or comments occasionally make srgrind think it saw
a "pb" (procedure begin), typesetting a new name in the margin.

Network tests fail if srv is run under control of "at"



UNDETECTED ERRORS:

Values of subscripts or enumeration types are not checked at runtime;
erroneous values can cause strange behavior.  Similarly, nothing prevents
the invalid use of uninitialized pointers or capabilities.

Previous versions of SR allowed arrays of size 1 to be used in situations
requiring a simple variable.  This is now illegal, but is not always checked.
In particular, dynamic arrays may slip through.

If the maximum number of active operations is exceeded, a segmentation fault
sometimes results.

call/send/callsend and public/private restrictions are not always enforced.

Nested constructors are not properly diagnosed.

No warning is given if an invocation is still pending when an op terminates.

Nothing checks to prevent a second reply to a single invocation.
