1 04/18/80  Potentially incompatible code changes generated by the PL/I compiler
  2 
  3 Since the Multics PL/I compiler was written, it has had a bug which may cause
  4 two external procedures to communicate incorrectly via parameters, based
  5 variables or external static variables.  This is PL/I bug number 1186, known
  6 informally as the padded reference bug.  This bug involves the conventions
  7 that two external procedures use to communicate, and hence cannot be fixed
  8 without recompiling every program at every Multics site.
  9 
 10 Release 26 of the Multics PL/I compiler implements the first phase of fixing
 11 this bug.  The second phase will be completed in about two years.  Users will
 12 have to recompile every program with release 26 or later before the second
 13 phase is installed.
 14 
 15 Some programs with invalid PL/I that worked with release 25 or earlier will
 16 fail when compiled with release 26 or later.  There shouldn't be too many
 17 programs that fail.  Programs that misdeclare an entry will fail if there is a
 18 mismatch in the alignment attribute for short bit string or short character
 19 string parameters or return values.  Short means two words or less.
 20 
 21 The rest of this info seg describes what the padded reference bug is, and
 22 exactly what code sequences are changing.
 23 
 24 
 25 Padded references: Some short bit strings or short character strings are
 26 padded.  Short means two words or less, i.e.  for character strings, 8
 27 characters or less, and for bit strings, 72 bits or less.  Some short
 28 character strings or bit strings have unused bits in a word.  For example:
 29 
 30           dcl v bit (1) aligned;
 31           dcl w bit (1);
 32 
 33 One word of storage will be used for v.  The first bit will be the value of v
 34 and the remaining bits will be zero.
 35 
 36             0  1                 35
 37           --------------------------
 38           | v | pad - must be zero |
 39           --------------------------
 40 
 41 The variable w, since it is unaligned, only needs one bit for its value.
 42 
 43             0
 44           -----
 45           | w |
 46           -----
 47 
 48 The compiler will try to pad w, as in v, if it is not a member of a structure,
 49 if it is automatic and if it the variable is only referred to by one name
 50 (This checking is not done correctly).  Variables may be padded even if they
 51 are declared unaligned.  The bit string b in the following structure won't be
 52 padded since there is another variable declared to use the remaining part of
 53 the word.
 54 
 55           dcl 1 s unaligned,
 56                 2 b bit (2),
 57                 2 c bit (34);
 58 
 59 The compiler could generate better code if it used the unused bits in the
 60 word.  That way it could use word oriented instructions directly, such as lda
 61 or ldaq, instead of masking the unused bits.  Often, such as with unaligned
 62 parameters, exactly which bits are unused is not known until runtime.  A
 63 reference to a short string is called a "padded reference" if the unused bits
 64 in the word are used.  When a padded reference is stored, the pad bits are
 65 zeroed.  When a padded reference is fetched, the unused bits are assumed to be
 66 zero.  In order for this to work, references to a short string must either be
 67 all padded or all unpadded.  This is easy to determine if the reference is
 68 only used within one external procedure.  If the reference is used by more
 69 than one external procedure, for example, if it is passed as an argument by
 70 reference, then the compiler must ensure that all references in any external
 71 procedure are either all padded or all unpadded.
 72 
 73 
 74 The padded reference bug: Sometimes the compiler pads some references to a
 75 variable, and inconsistently at other times, uses unpadded references to the
 76 variable.  For example:
 77 
 78           dcl c char (5);
 79           dcl cb char (5) based (addr (c));
 80 
 81 References to c are padded while references to cb are not.  The program will
 82 fail if c is always set by refering to cb, and always read by refering to c.
 83 If a string can be padded and is passed as an argument in a program, then set
 84 references to that string are not padded.  However, if the called program does
 85 not pass the string as an argument, the called program's references are
 86 padded.  Communication will fail if the calling program sets the string and
 87 the called program reads the string.  The calling program won't pad the
 88 string, but the called program will assume the string was padded when it was
 89 set.
 90 
 91 
 92 Release 26 code changes: The padded reference bug will be fixed in two phases.
 93 The first phase is done in release 26.  All set references that should be
 94 padded will be padded.  More set references will be padded in release 26 than
 95 in previous releases.  The second phase is to correctly pad read references.
 96 This phase will be done in about two years.  Since the effect of the first
 97 phase is to pad more references, it is a compatible change.  The second phase
 98 will assume that references are padded according to the release 26
 99 conventions.  All programs should be recompiled with the release 26 compiler,
100 or a later compiler, before the compiler implementing the second phase is
101 installed.  Note that most symptoms of the padded reference bug will disappear
102 once programs are recompiled with the release 26 compiler.
103 
104 One of the contexts in which release 26 will pad references is short, aligned,
105 string parameters or return values.  For example, a program calls the
106 following procedure:
107 
108  called_proc:
109      procedure (short_cs, short_bs);
110           dcl short_cs char (2) aligned;
111           dcl short_bs bit (5) aligned;
112 
113           short_cs = "ab";
114           short_bs = ""b;
115      end called_proc;
116 
117 The release 25 compiler generates the following code:
118 
119           short_cs = "ab";
120 
121                     lda       49762,du
122                     epp7      pr6|26,*
123                     epp5      pr7|2,*             short_cs
124                     stba      pr5|0,60            short_cs
125 
126           short_bs = ""b;
127 
128                     lda       3,ic                000022 = 017777777777
129                     ansa      pr7|4,*             short_bs
130 
131 Note that the unused bits are not padded.  The release 26 compiler pads these
132 references.  It generates:
133 
134           short_cs = "ab";
135 
136                     lda       49762,du
137                     epp7      pr6|26,*
138                     sta       pr7|2,*             short_cs
139 
140           short_bs = ""b;
141 
142                     stz       pr7|4,*             short_bs
143 
144 The compiler can pad these references since the strings are aligned.  This is
145 a compatible change for valid PL/I programs.  However, certain invalid PL/I
146 programs will fail.  For example:
147 
148  calling_proc:
149      procedure;
150           dcl called_proc entry (char (2), bit (5));        /* Invalid */
151           dcl 1 s,
152                 2 cs char (2),
153                 2 x char (2) init ("cd");
154           dcl 1 t,
155                 2 bs bit (5),
156                 2 y bit (31) init ((31)"1"b);
157 
158           call called_proc (s.cs, t.bs);
159 
160           ...
161 
162      end calling_proc;
163 
164 Note that calling_proc has misdeclared called_proc to have unaligned short
165 string parameters instead of aligned short string parameters.  The values of
166 s.x and t.y won't change if called_proc is compiled with release 25.  However,
167 once called_proc is compiled with release 26, the values of s.x and t.y will
168 be obliterated.  The affected programs misdeclare an entry so there is a
169 mismatch in the alignment attribute for short bit string or short character
170 string parameters or return values.  This change should not affect too many
171 programs.