09/21/87 pl1 Known errors in the current release of pl1. # Associated TR's Description 2187 phx16267 Internal compiler error 248 occurs when the right-hand-side for an assignment to the pseudo_variable pageno is an expression instead of a constant. pageno_bug: proc; dcl pp fixed bin (35) init (99); dcl pageno builtin; dcl sysprint print file; pageno(sysprint) = pp; put file (sysprint) edit ("Test", pageno(sysprint)) (a); end; ERROR 248, SEVERITY 3 ON LINE 5 Compiler error: Bad input "pp" to the conversion routine "convert". SOURCE: pageno(sysprint) = pp; PL/1 should allow an expression as the right-hand-side for an assignment to the pseudo-variable pageno. The AM83 manual (Page 10-12) does not disallow them. The affected module is builtin.pl1 . 2186 phx17798 A meaningful error message should be printed at compile time when one attempts to change the value of a variable declared with "options (constant)" for the duration of a program. change_a_constant: proc; dcl a fixed bin init (5); /* regular variable */ dcl c fixed bin init (2) internal static options (constant); /* constant */ dcl ioa_ entry () options (variable); call ioa_ ("a = ^d^/c = ^d", a, c); c = a; call ioa_ ("a = ^d^/c = ^d", a, c); return; end change_a_constant; -->pl1 change_a_constant PL/I 27d -->change_a_constant a = 5 c = 2 Error: no_write_permission condition by >udd>SysMaint>Housley>tr>change_a_constant|45 (line 10) referencing >udd>SysMaint>Housley>tr>change_a_constant|0 - level 2,10->rl -->sa change_a_constant rew -->change_a_constant a = 5 c = 2 a = 5 c = 5 --> 2185 phx20041 phx20035 Compiling bound_log_tools_.s::summarize_sys_log.pl1 generates bad code for PL/1 29. The compiler assumes the value in the index register will remain valid across an external call to iox_$put_chars when in fact it doesn't. Code generated from line 1136: call iox_$put_chars (switches (selectors (slx).switchx).iocb_ptr, addwordno (addr (text_buffer), 1), length (text_buffer), (0)); 012561 aa 040000 7270 07 lxl7 16384,dl 012562 aa 6 25502 2361 17 ldq pr6|11074,7 slx 012563 aa 000003 7360 00 qls 3 012564 aa 6 37734 2361 06 ldq pr6|16348,ql selectors.switchx 012565 aa 000004 7360 00 qls 4 012566 aa 6 20574 3735 17 epp7 pr6|8572,7 text_buffer 012567 aa 7 00000 3521 00 epp2 pr7|0 012570 aa 000001 0520 03 adwp2 1,du 012571 aa 6 27250 2521 17 spri2 pr6|11944,7 012572 aa 000000 6260 06 eax6 0,ql 012573 aa 6 20574 2361 17 ldq pr6|8572,7 text_buffer 012574 aa 6 27224 7561 17 stq pr6|11924,7 012575 aa 6 27332 4501 17 stz pr6|11994,7 012576 aa 067226 7210 07 lxl1 28310,dl 012577 aa 6 00536 3521 16 epp2 pr6|350,6 switches.iocb_ptr 012600 aa 6 00002 2521 11 spri2 pr6|2,1 012601 aa 6 27250 3521 17 epp2 pr6|11944,7 012602 aa 6 00004 2521 11 spri2 pr6|4,1 012603 aa 6 27224 3521 17 epp2 pr6|11924,7 012604 aa 6 00006 2521 11 spri2 pr6|6,1 012605 aa 6 27332 3521 17 epp2 pr6|11994,7 012606 aa 6 00010 2521 11 spri2 pr6|8,1 012607 aa 6 00000 6211 11 eax1 pr6|0,1 012610 aa 020000 4310 07 fld 8192,dl 012611 aa 6 00044 3701 20 epp4 pr6|36,* 012612 la 4 00126 3521 20 epp2 pr4|86,* iox_$put_chars 012613 aa 040000 7270 07 lxl7 16384,dl 012614 aa 6 27334 6535 17 spri7 pr6|11996,7 012615 aa 0 00623 7001 00 tsx0 pr0|403 call_ext_out STATEMENT 1 ON LINE 1137 if switches (selectors (slx).switchx).prev_message_ptr ^= null () then call log_read_$free_message (opt.log_read_ptr, switches (selectors (slx).switchx).prev_message_ptr); 012616 aa 6 25502 2361 17 ldq pr6|11074,7 slx 012617 aa 000003 7360 00 qls 3 012620 aa 6 37734 2361 06 ldq pr6|16348,ql selectors.switchx 012621 aa 000004 7360 00 qls 4 012622 aa 6 00534 2371 06 ldaq pr6|348,ql switches.prev_message_ptr After the external call to iox_$put_chars (at line 1137), it attempts to load the value of the variable "slx" into the "q" register. It does so by using an offset in register x7. However, it has made no provision for the possibility that the contents of x7 might have been destroyed during the external call. (In this case the value of x7 does get trashed). Therefore, the program sometimes faults, and always get erroneous results. Proposed solution: After the external call, x7 should be loaded with correct value. Insert an "lxl7 16384,dl" before 12616. 2184 phx18993 The pl1 compiler generates incorrect code when concatenating a single character to the end of a varying character whose length is an expression. test: procedure; dcl string char(1024) varying; dcl sp pointer; dcl l2 fixed bin(35) init(512); dcl c char(l2*2) varying based (sp); sp = addr(string); c = ""; c = c || "a"; return; end test; The code generated for statement 8 are as follows: 000027 aa 6 00504 2361 00 ldq pr6|324 l2 000030 aa 000002 4020 07 mpy 2,dl 000031 aa 6 00506 7571 00 staq pr6|326 000032 aa 7 00000 2361 00 ldq pr7|0 c 000033 aa 6 00511 1161 00 cmpq pr6|329 000034 aa 000005 6050 04 tpl 5,ic 000041 000035 aa 7 00000 0541 00 aos pr7|0 c 000036 aa 040 106 100 404 mlr (ic),(pr,ql),fill(040) 000037 aa 000004 00 0001 desc9a 4,1 000042 = 141000000000 000040 aa 7 00001 00 0001 desc9a pr7|1,1 c When concatenating a single character to the end of varying character string whose length is an expression, the compiler evaluates the expression for the length and stores it in a stack temporary. It then adds one to the current length of the varying character string and stores it in a register. It compares these two values to see if the resulting character string is too long in which it will be truncated (in this case the truncation is not taken place since it has added only one character to the string). However, the compiler does not use the same stack temporary to store the computed length of the string. The result depends on what is in that other stack location. Sometimes it works normally, and sometimes the concatenation is bypasses because the code thinks the string should be truncated. 2183 phx14895 PL/1 compiler may fail to keep track of the state of the indicators and generates unexpected result of the trunc operator. An input value of 11 for the following program demonstates the problem: main_: proc; dcl (sysin, sysprint) file; dcl r float bin; dcl (i, j, n) fixed bin; put skip list (">>"); get list (i); r = i; do while (r > 10); r = r/10; end; n = trunc (r); put skip edit ("Input=",r) (a, f(8,2)); put skip edit ("Trunc=",n) (a, f(6)); end main_; 2182 phx16456 Optimizer incorrectly stores data for controlled external structure. After the "exponent underflow" error is signalled at run time, the test program is an infinite loop. Test Paths: >udd>TR>TR_tc>tc1>run_bug.pl1 >udd>TR>TR_tc>tc1>s.pl1 >udd>TR>TR_tc>tc1>run_contour_staircase.pl1 2181 phx18441 PL/1 does not warn about qualified references to substr builtin and produces incorrect result. main_ : proc; dcl (xptr, yptr) pointer; dcl ioa_ entry() options(variable); dcl x char (4) init ("1234"); dcl xb char (4) based (xptr); dcl y char (4) init ("abcd"); dcl yb char (4) based (yptr); dcl (addr, substr) builtin; xptr = addr (y); yptr = addr (x); call ioa_ ("x = ^a", substr (yptr -> xb, 1, 1)); call ioa_ ("x = ^a", yptr -> substr (xb, 1, 1)); call ioa_ ("y = ^a", substr (xptr -> yb, 1, 1)); call ioa_ ("y = ^a", xptr -> substr (yb, 1,1)); return; end main_; The incorrect output are: x = 1 x = a y = a y = 1 2180 phx18973 pl1.dcl declares mhcs_$get_seg_usage incorrectly. The last argument which is also fixed bin (35) is missing from the declaration. Proposed solution: Update the entry in pl1.dcl as follows: dcl mhcs_$get_seg_usage entry (char(*), char(*), fixed bin(35), fixed bin(35)); 2179 phx14646 PL/1 complex float bin (63) arithmetic is unacceptably inefficient. The ineffiencies is due to the overheads in the call to the complex_binary_op_ external entry. 2178 phx19186 Incorrect result when a negative bit offset is given as an argument of the add_bit_offset_ subroutine or the addbitno PL/1 builtin. The following test program illustrates the problem: bit_offset_bug: proc; dcl fill1 fixed bin; dcl a fixed bin; dcl fill2 fixed bin; dcl p ptr; dcl add_bit_offset_ entry (ptr, fixed bin (24)) returns (ptr) reducible; dcl ioa_ entry options (variable); dcl (addbitno, addr) builtin; p = addr (a); call ioa_ ("^p", p); p = add_bit_offset_ (p, -1); call ioa_ ("^p", p); p = addr (a); p = addbitno (p, -1); call ioa_ ("^p", p); end; THE OUTPUT: 234|13001 234|631162(27) 234|631162(27) 2177 phx14717 Code generation bug when compiling with "-optimize" option. In some cases, when a varying string array is declared at more than 16 K of the index used, the compiler generates lxl and stq instructions between cmpc and tnz instructions of a IF statement that changes the condition codes. For example, if we put a call statement inside the IF_THEN statement, the code generated for the condition will be very different. Therefore the result of the comparison is also changed. The following program illustrates the problem: main_: proc; dcl it fixed bin init (1); dcl blanc char (4) init ((4)" "); dcl tab1 (16500) char (4); dcl tsymb (5) char (4) varying; dcl ioa_ entry options (variable); tab1 (it) = ""; tsymb (it) = ""; if tsymb (it) = blanc then do; tsymb (it) = "tex1"; /* With the call statement, the condition code will be changed */ end; call ioa_ ("it= ^d, tsymb(it)= ^a", it, tsymb (it)); end; 2176 phx15171 The storage type of f format item in a PL/1 put edit statement affects the formatted output. For example, the options (constant) in the following program seem to make a difference to PL/1 IO. test: proc; dcl i fixed bin; dcl item fixed bin init (4); dcl oay(3) fixed bin init (1,2,3); dcl way(3) fixed bin internal static options (constant) init (1,2,3); do i = 1 to 3; put skip edit (item, "XXX", item) (f(6,oay(i)), a(3), f(6,way(i))); end; end; 4.0XXX 4.0 4.00XXX 4.0 4.000XXX 4.0 2175 phx15861 Results of x= before (x,"."); statement depends on presence or absence of a call ioa_ statement. Program t1.pl1 will produce the desired result ('99 ') while t2 produces ('99 \000'). t1: proc; dcl x char(5); dcl ioa_ entry options (variable); dcl sysprint file; x= "99"; x= before (x, "."); put skip(1) edit ("'",x,"'")(a(1),a(5),a(1)); put skip(1); call ioa_ ("^/'^5a'",x); end; t2: proc; dcl x char(5); dcl ioa_ entry options (variable); dcl sysprint file; x= "99"; x= before (x, "."); put skip(1) edit ("'",x,"'")(a(1),a(5),a(1)); put skip(1); end; 2174 phx15152 Code generator fault or out of bounds error when compiling the following programs. test: proc; dcl sysprint file output; dcl dbmp ptr; dcl 1 dbm based (dbmp) aligned, 2 area area (255*1024-10); dcl 1 FOO like dbm aligned int static; put list(FOO); return; end; Proposed solution: Update assign_storage when it is assigning storage for static variables, add checking the size of the object segment as well as checking it for automatic storage. 2173 phx16479 A usage message should be printed instead of a message containing octal garbage when compiling "compile_messages" subroutine without an argument. Proposed solution: The "compile_messages.pl1" is rewritten so that it accepts valid pathname (such as the pathname of the source segment or archive segment). In addition, the message" suffix is added if the user does not supply it. If incorrect number of argument is supplied when invoking "compile_messages", a meaningful message should be printed. 2172 phx15586 Executing the following program will cause a storage condition at the first time and a fatal process error at the second time. test : proc; dcl astring char (10000) init ("abcde"); dcl do_sw bit (1) init ("1"b); dcl i fixed bin; dcl substr builtin; do i = 1 to 10000; if do_sw then astring = substr (astring, i) || substr (astring, 1, i - 1); else return; end; end; It is because PL/1 does not properly clean up stack extension when the statement that causes stack extension is an if_then_else statement which is followed immediately by the end of a do_loop. This error may be related to error 1795. 2171 phx17278 PL/1 compiler produces an incorrect source map entry if it lack of "s" access to the source's or include file's containing directory. Access to the containing directory is not necessary to get the pathname of a segment nor its DTCM, as long as the users have "r" access to the segment itself. 2170 phx18829 A packed_pointer_fault condition is signalled but with no indication of why or of any errors detected in the source when compiling the program >udd>TR>TR_tc1>datapath.pl1 . 2169 phx14771 Incorrect code is generated when compiling the following test case with both "-optimize" and "-table" options. test: proc; dcl dummy fixed bin (9) unsigned unal; dcl (i, nfound, j) fixed bin (36) unsigned unaligned; dcl ioa_ entry() options(variable); dcl nused fixed bin (35); i = 3; nfound = 4; j = 1; nused = 5; if ((i < nfound) & (j <= nused)) then call ioa_ ("right"); else call ioa_ ("wrong"); return; end test; Proposed solution: (1) Fix the code generator. (2) Leave things as they are now since using -ot and -tb is the only way to debug problems that only occur when the program is optimized. (3) Warn users that the symbol table of the optimized program may be incomplete. (4) Ignore the "-table" option and emit a warning message at the same time. For solution (3) and (4), the affected modules is v2pl1.pl1 and documentation change is AG92 and pl1.info segment. Add the following lines -> If you give both "-table" and "-optimize" , the "-table" option will be ignored since "-optimize" and "-table" are mutually exclusive. before the line -> NOTES ON SEARCH LIST Due to popular demand, the fixes for solution (3) and (4) will be installed. (Refer to forum transaction). 2168 phx14706 If aggregate references and BYTE builtin references are found in any of the STRING builtin arguments, PL1 error message 294 will be generated. test: procedure ; dcl bit_ar8 dimension (1) bit (8) unaligned init((1)"11111111"b); dcl char_1 character (1) unaligned ; char_1 = string (byte (binary (bit_ar8, 8))); end test; Note:: "bit_ar8" is of type aggregate, therefore all other arguments of the string will be converted to the aggregate type of "bit_ar8". The problem may occur during the conversion of BYTE builtin to the aggregate type. 2167 phx14977 After a PL/1 I/O "record" condition is raised, the length of the target string is not being set which causes the undefined result of the target string. The following test case illustrates the problem: test: procedure; declare cdx_sysin file; declare target char(50) varying; /* target is of variable length */ on record(cdx_sysin) begin; put skip list(" RECORD CONDITION RAISED> "); end; open file (cdx_sysin) title ("record_stream_ user_input") env (stringvalue) record input; put skip list(" INPUT: "); read file(cdx_sysin) into(target); put skip list (" LENGTH ", length(target)); put skip list(" OUTPUT "||target); end test; Note: If the input string is more than 50 characters, the target string is undefined after the "record" condition is raised. According to AM83 manual, PL/1 completes the I/O after the "record" condition is signalled and will truncate the record to fit the target. However, in our currect version of PL/1, the target string is undefined because the length of the target string has not been set after the "record" condition is raised; even though the input data has been read into the target string by the "read" statement. 2166 phx20841 phx14595 phx15607 PL/1 fatal process error (FPE) occurs when the invalid program which contains recursion in declarations is compiled the second time. PL/1 should give consistent error message for the subsequent compilations of the same invalid program. Test Case: main_: proc; dcl 1 a, 2 b char (3); dcl 1 z like a based (z); dcl m char (3); m = z.b; end main_; Compiling the test case the first time results in the pl1 error message FATAL ERROR 365 ON LINE 6 Compiler error: storage condition while in the semantic translator. Possible recursion in declarations. Correct all source programs and recompile. If this message persists, contact the compiler maintenance personnel. SOURCE: m = z.b; pl1: An unrecoverable error has occurred. pl1: Translation failed. test.pl1 But compiling the test case the second time results in the FPE Fatal error. Process has terminated. User stack space exhausted. New process created. Note: Ideally subsequent compilations should continue to get same ERROR 365 instead of Fatal Process Error. (See TR20841, TR14595, and TR15607 for more information) 2165 phx17376 PL/1 fatal error occurs when star_structure.incl.pl1 is defined twice. (Once in the main procedure and once in the internal procedure). 2164 phx17241 "Fatal error 335 while compiling a write from construct. Out-of-bounds while in the semantic translator. test case; oacr: proc(); dcl sort_out file stream output; dcl sel_exp char(300) varying; dcl 1 CSIR_raw_material aligned, 2 FILLER character (2) nonvarying unaligned; open file(sort_out); sel_exp = copy(""z"", length (string (CSIR_raw_material))); /* The first works, the second doesn't */ write file(sort_out) from (sel_exp); write file(sort_out) from (copy(""z"", length (string (CSIR_raw_material)))); end oacr;" Proposed solution: Ensure that io_semantics is dealing with a symbol node at all times. 2162 phx15818 No error condition is raised for storing incorrect result in a fixed bin (71) variable when a float bin value containing value larger than 2*10**21 (2.0E+21) is assigned to a fixed bin (71) value. The following test case illustrates the problem: test_assign: proc (); dcl long_float float bin (63), long_fixed fixed bin (71); dcl sysprint file print; long_float = 2.0e+22; long_fixed = fixed (long_float, 71, 0); put skip list (long_float); put skip list (long_fixed); end test_assign; The output are as follows: 2.000000000000000000e+022 1250000000000000000000 Note that incorrect value is stored in long_fixed which is declared as fixed bin (71). 2161 phx16265 Incorrect address of array is generated when compiling with -prefix subscriptrange. bug: proc; dcl (max_bytes, current_byte) fixed bin (24); dcl code fixed bin (35); dcl (array_ptr, bad_ptr) ptr; dcl array (max_bytes) char (1) unal based (array_ptr); dcl com_err_ entry () options (variable); dcl get_temp_segment_ entry (char (*), ptr, fixed bin (35)); dcl ioa_ entry () options (variable); dcl release_temp_segment_ entry (char (*), ptr, fixed bin (35)); dcl sys_info$max_seg_size fixed bin (35) external; dcl cleanup condition; dcl (addr, null) builtin; max_bytes = sys_info$max_seg_size * 4; array_ptr = null (); on cleanup call cleanup_proc; call get_temp_segment_ ("bug", array_ptr, code); if code ^= 0 then do; call com_err_ (code, "bug"); return; end; else; do current_byte = 1, 262140, 262141, 262142, 262143, 262144, 262145; bad_ptr = addr (array (current_byte)); call ioa_ ("Byte ^d, address ^p.", current_byte, bad_ptr); end; call cleanup_proc; return; cleanup_proc: proc; if array_ptr = null () then; else call release_temp_segment_ ("bug", array_ptr, (0)); return; end cleanup_proc; end bug; Note that Byte 262141 is incorrectly located at address 462|777777(0) whereas Byte 262140 is correctly located at address 462|177776(27). 2160 phx20392 Problem in evaluating a complex expression. The following test case illustrates the problem. round: proc (num, sig); dcl (num, sig) char(*); dcl number float dec(59), significant_digits fixed bin, result float dec(59); dcl ioa_ entry() options(variable); number = convert(number, num); significant_digits = convert(significant_digits, sig); result = round (number, significant_digits); call ioa_ ("round(^f,^d) = ^f", number, significant_digits, result); return; round: proc (number, significant_digits) returns (float dec(59)); dcl number float dec(59) parameter, significant_digits fixed bin(17) parameter; dcl (multiplier, result) float dec(59); dcl (abs, decimal, float, floor, log10, sign, trunc) builtin; multiplier = significant_digits; multiplier = 10 ** (multiplier-floor(log10(abs(number)))-1); result = decimal(float(sign(number),59),59) * floor(abs(number)*multiplier+0.5)/multiplier; return(result); end round; end round; When invoked the above test program as: round 123.14159 2 should produce 120. Instead, it produces: 120.00000000000000001200000000000000000120000000000000000012 The affected module is any_to_any.pl1 2159 phx15532 The pl1 compiler gets FATAL ERROR 310 when trying to call the external entry recursively. See the original TR and test case for more info. 2158 phx17612 Explicit initialization of an area is not performed. When an area is declared with an initial value other than empty (i.e. an area variable), no error is detected in the compile time but the decalred initial value is not assigned; the area is inititalized to empty. (See the original TR and test case for more info.) 2157 phx14472 Wrong result is produced when comparing values of different precisions. The following test case illustrates the problem: main_: proc; dcl a fixed bin (35) init (131072); dcl b fixed bin init (4); dcl ioa_ entry options (variable); if a <= b/2 then call ioa_ ("^d <= ^d", a, b/2); end; Note: The compiler seem to apply the conversion rules improperly. 2149 phx20802 The scale value in the symbol listing should match the declared value which can be negative sometimes. Currently, it is always printed as a positive value in the listing. Test Case: test: proc; dcl x fixed bin (35,-5); dcl nt entry options (variable); call nt (x); call nt (x); end test; Note: In the symbol listing, x is printed as fixed bin (35,5) instead of fixed bin (35,-5). Proposed solution: Update pl1_symbol_print.pl1 to get negative scale factors to print correctly in the listing. 2155 phx16951 Adding 'varying' to a character declaration causes a fatal compiler error. test case: t: proc; dcl cs char (36) varying init ("abc defg "); dcl result char (10); result = decat (ltrim(rtrim(cs))," ", "101"b); end t; 2154 phx17581 Compiler error 315 occurred when compiling the following test problem when "-optimize" option. print_val: proc (lst_ptr); dcl 1 cable aligned, 2 id character (5) unaligned, 2 cbl character (4) unaligned; dcl lst_ptr ptr; dcl cables_list (12) char (4) unaligned based (lst_ptr); dcl cable_title (12) char (66); dcl i fixed bin; cable = ""; do i = 1 to 3; cable_title (i) = cable.cbl || "=" || rtrim (cable.id); cables_list (i) = cable.cbl; end; end; ERROR 315, SEVERITY 3 ON LINE 14 Compiler error: temporary node "cbl" does not have value in storage. SOURCE: cables_list (i) = cable.cbl; (See bug2097 for other problem when invoked with "-ot".) 2153 phx15817 Error 435 occurred when compiling a multiple assignment. The following test case illustrates the problem: test: proc; dcl x ptr external; dcl y offset (z) external; dcl nullo builtin; x, y = nullo (); /* fails */ end; ERROR 435, SEVERITY 3 ON LINE 7 Invalid conversion between pointer and offset variables because no area has been declared to associate with the offset variable "cp.1". SOURCE: x, y = nullo (); (See bug2070 for other problem when compiling a multiple assignment.) 2152 phx13854 PL/1's "put list" does not always tab to the correct column (eg. column 1, 11, 21, etc). In some situations it will use space filling method instead and cause one column to the left of the proper position. The problem is best demontrated by printing a series of literals, of length 8. The items are alternately separated by spaces and TABs. Starting with the third item, every other one is wrong. Test Case: test_put: proc; dcl 1 p, 3 (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12) char (8) init ("I"); put skip list ("p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10", "p11", "p12"); put skip list (p); put skip list (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); end test_put; The following output illustrates the problem: p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 I I I I I I I I I I I I I I I I I I I I I I I I Note: There are different algorithms for space filling and TAB using. If within two spaces of a tab column, use space filling, otherwise use a TAB. Mixing the two algorithms may cause the internal counter off by one. Proposed solution: The affected module is put_field_.alm. (See bug 2140 for other problem caused by the put list statement.) 2151 phx19010 The use of a builtin (hbound) that references parameter descriptors within a PL/1 I/O statement results in a runtime error (size condition). bounds_bug: proc; dcl array (10:10) fixed bin init (0); call sub (array); sub: proc (a); dcl a(*) fixed bin; dcl i fixed bin; put skip list (hbound (array, 1)); put skip list (hbound(a, 1)); end sub; end; 2150 phx18680 phx20151 PL/1 compiler generates bad code if it crosses a 16K boundary in the stack frame while processing descriptors for a contiguous group of arguments which share an identical descriptor. Test case: test: proc; dcl padding (4072) fixed dec (12, 2); dcl (a, b, c, d, e, f) fixed bin (35); dcl nothing entry (fixed bin (35), (*) fixed dec (12, 2), fixed bin (35), fixed bin (35), fixed bin (35), fixed bin (35), fixed bin (35)); call nothing (a, padding, b, c, d, e, f); return; end; The following code generated using the "-tb" and "-list" illustrate the problem: dcl padding (4073) fixed dec (12, 2); call nothing (a, padding, b, c, d, e, f); 000013 aa 6 37744 3521 00 epp2 pr6|16356 a 000014 aa 6 37754 2521 00 spri2 pr6|16364 000015 aa 6 00100 3521 00 epp2 pr6|64 padding 000016 aa 6 37756 2521 00 spri2 pr6|16366 Note: Bad code is generated setting up the descriptors for the call to nothing. The requirements appear to be that a non-contiguous group of arguments share a descriptor, and that somewhere in that group of descriptors the 40000 (octal) offset in the stack be crossed. The compiler generates code to reference things like pr6 up 40002, which is taken by the hardware as a negative offset from pr6 rather than as what the compiler intends. 2148 phx16114 Incorrect descriptors for * extent parameters are generated when passing a cross_section of an array to a subroutine as an expression (by value). Test Case: 1 test: proc; 2 dcl s(11,11) bit (1) unaligned; 3 s (*,*) = "1"b; 4 call test_sub ( (s (*,2)) ); 5 return; 6 test_sub: proc (x); 7 dcl x (*) bit (1) unaligned; 8 dcl i fixed binary; 9 dcl lbound builtin; 10 i = lbound (x, 1); 11 x (i) = "0"b; 12 return; 13 end test_sub; 14 end test; Using "probe" on an active frame of "test_sub" (at line 11), the request "symbol x" reports "bit (1) unal parameter dimension (1358487760:1492492299)". If the parenthesiss immediately surrounding the actual parameter in line 4 are removed, the same request ("symbol x") now says "bit (1) unal parameter dimension (1:11)", which is the correct information. 2147 phx17503 phx14494 If both aggregate references and builtin references are found in the pseudo_variable SUBSTR arguments, bogus error message will be generated. Test case: test: proc; dcl line char(64)var; dcl ch_array (1) char(50); line = "random string"; substr(ch_array, 1, length(line)) = line; end test; Compiling the above test case produces error 121: The number of arguments used in a reference to the builtin function "length" is not equal to the number of arguments required by that function. SOURCE: substr(ch_array, 1, length(line)) = line; Proposed solution: If one of the arguments of the builtin is of array values with unequal dimensionality or structures with different structuring, display existing error 79 instead of 121. The module that required to be modified is expression_semantics.pl1 2146 phx16157 description: Runtime error: "Too few parameters in a format item" instead of compile error is generated when the "get edit" statement is used with the "a" format but with no length specified. test: procedure; dcl sysin file; dcl foo char(10); get edit (foo) (a); return; end test; According to AM 83 manual, string format item section, the "a" format with no length specific should not be allowed for input. The execution of the above test case produces a runtime error message: "Too few parameters in a format item." This message is not very specific to the problem and the error should be catch at compiled time instead of run time. The affected modules are: io_statement_parse.pl1 parse.incl.pl1 format_list_parse.pl1 pl1_error_messages_.message 2143 phx18065 phx18442 If the extent variables is used as the extent or dimension of any other based area or variable for which there was no allocate statement, and if the program is compiled with -ot -sb or options that causes supression of area or array bound checking, that variable will not show up in the list of external variables and will incorrectly listed as declared but never referenced. test_ref: proc (my_area_ptr, thing_ptr); dcl my_area area (sys_info$max_seg_size) based (my_area_ptr); dcl my_area_ptr ptr parameter; dcl sys_info$max_seg_size fixed bin(35) ext static; dcl thing char (4) based (thing_ptr); dcl thing_ptr ptr parameter; dcl null builtin; thing_ptr = null (); allocate thing in (my_area); return; end test_ref; 2140 phx20222 Using a put list statement to print out a data string after a string causes an ASCII tab character to be printed between the blank string and the data string. If that data string is more than 8 characters long, then PL1 I/O will cause an unwanted tab to be printed after the data string. Test case: put_list_test: procedure (); dcl sysprint file; put list ("", "12345", "12345", "RIGHT!!!"); put skip list ("123456789", "123456789", "123456789", "RIGHT!!!"); put skip list ("123456789", " ", "123456789", "WRONG!!!"); put skip list ("", "123456789", "123456789", "WRONG!!!"); put skip list (" ", "123456789", "123456789", "WRONG!!!"); put skip list (" ", "123456789", "123456789", "WRONG!!!"); put skip list (" ", "123456789", "123456789", "RIGHT!!!"); put skip list (" ", "123456789", "123456789", "WRONG!!!"); put skip; end put_list_test; Proposed solution: The affected modules : put_field_.alm - update the correct column for put list statement. plio2_put_util_ - insert a comment for warning users about the obsoletion of the modules. (See bug 2152 for other problem caused by the put list statement.) 2139 phx20581 Assigning the aggregate structure to a scalar structure, PL1 fails to diagnose the incorrect assignment but generates incorrect code that uses one single register as all loop indexes of the assignment. Test case: test: proc; dcl 01 src dim (8), 02 var1 dim (3) char (10) var; dcl 01 dest like src; dcl i fixed bin; do i = 1 to 8; src(i).var1(*) = ""; end; dest = src; end test; Note: When the assignment statement "dest = src" is executed, PL1 fails to diagnose the incorrect structure assignment. It instead generates incorrect code that uses the same register as the loop indexes for both the 1:3 loop and the 1:8 loop. 2137 phx20669 The PL1 compiler does not validate references to variables unless the value is used. If a PL1 program contains a declaration such as dcl (based_array_len) based (array_ptr); and no declaration of based_array_len, the PL1 compiler will not generate any error message if the -no table control argument is specified and if the program has no reference to hbound (based_array,1) and dimension (based_array,1). Test case: t1: proc; dcl based_array (based_array_len) based (array_ptr); dcl array_ptr pointer; end t1; 2136 phx20650 PL1 compiler error messages 205 and 357 contain the value 262144 words as the maximum segment size. The correct value is 261120 words. Although most Multics software and user programs are not designed to cope with segments size greater than 255 pages (261120) words, the Multics hardware does allow segments to be as long as 256 pages (262144) words. The PL/1 compiler generates correct code for variables as large as 256 Multics pages. Error messages 205 and 357 reflect this ability. While most Multics segments are at most 255 pages long, some segments can be as long as 256 pages. A small number of PL1 application programs do use segments up to 256 pages long. Changing the value for the maximum segment size in the error messages to 261120 words will probably break those programs. (See >doc>info>256K_segments.gi.info for more information) 2135 phx16916 Pl1 does not generate correct long_profile code for some statements. In call proc (funct (...) ); the cost of calling "proc" will be charged to "funct"'s return statement. Test Case: test: proc; dcl ioa_entry options (variable); dcl n fixed bin; n=66; call ioa_ ("^d", n); n= funct(); call ioa_ ("^d", n); call ioa_ ("^d", funct())); funct: proc return (fixed bin); dcl (i,x) fixed bin; d`o i = 1 to 50; x = i; end; return(;x); end funct; end test; Incorrecct long profile code is also generated for entrypoints in internal procedures. Currently there is a missing call to profile operator for any internal "procedure" statement or "entry" statement. Test Case: test2: proc; call e1 (66); call p1 (66, 66); return; p1: proc (x, ypar); dcl (x, ypar) fixed bin; dcl (iy, y) fixed bin; y = ypar; e1: entry (x); do i = 1 to 50; y = i; end; return; end p1; end test2; 2134 phx20593 When the name condition is signalled, the documentation (AM83, page 13-15, AG91-03A, page 7-57) claims that an error message is printed on the 'error output' stream and control is returned to the point at which the condition was detected. In fact, no error message is being printed. 2133 phx20359 The compiler generates wrong code for the assignment to tempname in the following program. test:proc; dcl area (512) bit(36); dcl area_ptr ptr; dcl j fixed bin; dcl r fixed bin init(2); dcl tempname char (8); dcl 1 temp1 based (area_ptr) unaligned, 2 temp2 (16) float bin; dcl 1 level1 (0:9), 2 level2 (16) aligned, 3 level3 char (8); area_ptr = addr (area); do j = 1 to 16; if temp1.temp2 (j) = 0e0 then do; tempname = level1 (r).level2 (j).level3; end; end; end test; This appears to be fixed. 2132 phx20376 Program yields different results when optimized. Eg: (stringrange,subscriptrange):test_pgm:proc; dcl i fixed bin (17); dcl A(12) char(1) unaligned init ("A", "B", "C","D","E","F","G","H","I","J","K","L"); dcl index (1:7) init (1, 1, 1, 1, 1, 1, 1); dcl ioa_ entry () options (variable); do i = 1 to 3; call ioa_ ("Case(^d) ^7(^3d^) ^7( ^a ^)", i, index(*), A (index(1)), A(index(2)), A(index(3)), A (index(4)), A(index(5)), A(index(6)), A(index(7))); index (1) = index (1) + 1; index (2) = index (2) + 1; index (3) = index (3) + 1; index (4) = index (4) + 1; index (5) = index (5) + 1; index (6) = index (6) + 1; index (7) = index (7) + 1; end; end test_pgm; 2131 phx13918 Compiler generates bad code for a mixed real and complex expression. This appears to be fixed. 2130 phx13876 Pl1 optimizer generates bad code. bug:proc; dcl (type,j) fixed bin init(1); dcl defn bit(36) varying static options (constant) init ("777777777777"b3); dcl ioa_ entry options (variable); if substr (defn,j,9) = "777"b3 then call ioa_ ("GOOD"); else call ioa_ ("BAD"); unspec (type) = substr (defn,j,9); end; The optimized code generated for the if statement results in the else branch being taken unconditionally. 2129 phx13857 The open/close statement does not reset environment (stringvalue) in the FSB. 2128 phx13700 Under certain conditions, the stringsize condition is not signalled. Eg: dcl x char (len) based (p); If len is 5 and x is set to a character string longer than 5 then stringsize is signalled. If len is -5 it is not. This sometimes results in a fatal process error. 2127 phx13248 The pl1 compiler gets a fatal error 310 when trying to handle the passing of a cross section of an array that is part of an array structure. Eg: test_pl1:proc(len); dcl len fixed bin; dcl x entry ((*) char (*)); dcl 01 y (5), 02 z (5) char (len); call x (y.z (1,*)); end; 2126 phx12963 Put_edit_eis destroys the value in index register 2. The compiler expects this register to contain the same value before and after the operator is invoked. See the test case at >udd>TR>TR_tc>tc2>jrs1.pl1 for more information. 2123 phx14508 When the substr function has only two arguments and the second argument is an expression, incorrect string may be generated randomly. This is demonstrated by: main: proc; dcl S20 char(20) init ("1234567890abcdefghij"); dcl S11 char(20) var; dcl j fixed bin init (2); dcl (sysin, sysprint) file; S11 = substr(S20, (9 * (j - 1) + 1)); put skip list (S11); end; 2119 phx16080 If the object segment has a max length that is set too small for compilation, the compiler will emit error 311 which complains about the object segment exceeding the maximum supported length of 65536 words. This is not the case and the error message is misleading. 2121 phx19854 The pl1_operators_ routine "call_signal_" is called whenever a pl1 software condition is signalled. When invoked, this routine adds 48 words to the stack frame of the signaller in order to save registers and such. It will then call pl1_signal_from_ops to handle the condition. Upon return from this call, the stack length is set to the value stored in sp|5 (which is the offset of the original end of the permanent stack frame). This has the effect of removing all stack extensions - not just the 48 words added by "call_signal_". The following program demonstrates the problem: (size): test: proc; dcl a char (len) based (p); dcl len fixed bin init (100); dcl x float bin init (1e30); dcl p pointer; dcl size condition; allocate a; a = "a"; on size; call internal_test (a||"a", (x)); free a; return internal_test: proc (a,i); dcl a char (*); dcl i fixed bin; dcl ioa_ entry () options (variable); call ioa_ (a); end; end; In the above example, the call to internal_test contains an argument that creates a temporary stack extension and another that causes the size condition to be signalled. The condition handler for the size condition releases the storage of the first argument, causing it to be overwritten. Proposed solution: Remove the 48 words extension instead of all stack extension upon return from call_signal_ routine by subtracting the 48 words that added abd resetting the stack size. The affected module is pl1_operators_.alm : Replace ldx0 sp|5 get offset of original end of frame By ldx0 sp|stack_frame.next_sp+1 reset the stack frame size sblx0 48,du by subtracting the 48 words we added. 2120 phx20356 The runtime support routine any_to_any_ doesn't always handle fixed bin numbers with a negative scale factor correctly. The test case in the associated TR demonstrates this. 2116 phx19094 phx19318 phx19323 phx16341 Compiler gets fatal error message 313 when the following program is compiled optimized: compile_bug: proc returns (ptr); dcl string char(5); dcl string_ovrly char (1) varying based (addr(string)); string_ovrly = string_ovrly; return (addr(string)); end; This problem only occurs if "string_ovrly" is a varying string. 2115 phx19571 The charno buitlin works incorrectly with unaligned pointers. It returns the entire packed pointer instead of just the character offset. 2113 phx19401 If a nonlocal goto is used to leave a condition handler, there is an extra 48 words that is left on the stack frame of the procedure that signalled the condition. This can lead to a fatal process error in some instances: test: proc; dcl cond condition; on cond goto label; do while ("1"b); signal cond; label: end; end; If the program given above is run, the stack frame of "test" will be extended by 48 words every time the "signal cond;" statement is executed. Stack space will quickly run out. The problem is caused by the fact that the pl1_operators_ "signal" procedure extends the stack frame by 48 words before calling the routine "pl1_signal_from_ops_". Normally, the condition handler will eventually return control to this procedure which will reset the stack size. However, when a nonlocal goto is used to leave the handler, control is never returned to the pl1_operators_ "signal" procedure, and the stack frame isn't restored. This is a hardcore problem. Oct 23/85: The problem involves more than just the signaller. Example: main_: proc; dcl x fixed bin; dcl p pointer; dcl len fixed bin init (1000); dcl string char (len) based (p); allocate string; do while ("1"b); call fred (string||"abc"); x = x; /* the stack shorting code is on this line */ loop: end; free string; fred: proc (a); dcl a char (*); goto loop; end; end; This program will run out of stack space if it is run. The "call fred" line contains an argument that must be stored as a temporary stack extension (the || causes this). The nonlocal goto "fred" uses to return, does not clean up the stack extension. Therefore, each time "fred" is called, the stack frame of the caller gets larger - until the stack runs out of space. The only way I can think of fixing this problem would be to make the routine "nonlocal_goto_.alm" (used by the unwinder) reset any stack extension it finds on the destination stack frame. It would have to first make sure that that stack frame wasn't owned by an ALM program. 2105 phx16845 (generic functions) Fails to find a match when calling a generic function. generic subroutines work fine. 2104 phx18757 Incorrectly factors an entry declaration. 2103 Use of -table on a program with a complicated expression (in particular, subscripted) in the position attribute of a defined variable takes a reference count error. 2097 phx12211 Multiple occurrances of the rtrim builtin in the source-list of a put statement with the list option cause ERROR 313 when compiled with -ot or -optimize. Example: 'put skip list(rtrim(ename),rtrim(ename))' gets error 313. (See bug 2154 for other problem when invoked with "-ot". ) 2095 phx11977 The 'unspec' builtin and pseudo-variable yield bad code when their arguments are based cross-sections of arrays that are members of structures with refer options. An example: unspec (p -> struc.array(*)) = unspec (q -> struc.array(*)) totally fails to generate correct code for either the source or the target of the assignment. 2094 phx11810 The 'size' condition is raised incorrectly in assignments where the lhs is fixed bin(35) and the rhs is ceil of a fixed bin(35). dcl ceil builtin; dcl (x,y) fixed bin(35); x=12; (size):y=ceil(x) /* size is raised here */ 2091 phx11800 phx12714 The indicators are destroyed by ldlxn instructions in programs with stack frames larger than 16384 words when compiled with -optimize. Comparisons of based variables with unaligned based qualifiers then sometimes fail. Typically this happens in 'do while' loops. See the original TR and test case for more info. 2089 phx11459 phx11784 References to character, decimal, or bit members of structures where the offset is greater than 2**18-1 characters, decimal digits, or bits may result in incorrect code addressing the structure. This only happens in assignments where the target and source both have extremely large offsets and lengths. There are 2 registers available for large offsets and lengths, the A and the Q. When more than 2 oversize offsets and lengths are present in an assignment the compiler stuffs one of them in an index register which throws away the high order digits of values larger than 2**18-1. See the testcase for more info and suggestions for a fix. Bit offsets of unaligned bit arrays which are larger than 2**18-1 also get put into index registers (xrs) when subscriptrange (subrng) is enabled. A separate test cases, test2089a, exists. This bug should not be considered fixed until both cases work. 2087 phx11434 bug in pl1_snap_ causes the io switch user_output to be thrown out in the process of returning control to the user program. A quick fix is to change restore_io_'s call to iox_$attach_iocb to use an attach description of "syn_ user_i/o" (around line 157). Currently, it is "syning" switches to themselves! A better fix, suggested by Bill York, is to have save_io_ create dummy uniquename switches, move the attachments of user_output, user_input, and error_output to these switches and reatch user_output, user_input, and error_output in the usual manner. Then restore_io_ would do its work by closing and detatching user_* and error_output and then moving the attachments of the unique-name switches back to their corresponding user_* and error_output switches. See the TR for more info. 2083 phx11008 phx17956 Bad code produced when using rank builtin, refer extents and prefixes (such as subrg, strg, strz, size). noload: proc; dcl 1 based_frob aligned based, 2 data_len fixed bin (35), 2 string char (0 refer (based_frob.data_len)) unaligned; dcl 1 auto_frob aligned, 2 len fixed bin (35) initial (8), 2 string char (8) initial ("abcdefgh") unaligned; dcl floatword float bin, from_ptr pointer, fixbin17 fixed bin, charvar6 char (6) var, ioa_ ext entry options (variable); floatword = rank (substr (auto_frob.string, 1, 1)); call ioa_ ("^f", floatword); from_ptr = addr (auto_frob); floatword = rank (substr (from_ptr -> based_frob.string, 1, 1)); call ioa_ ("^f", floatword); charvar6 = "abcdef"; fixbin17 = rank (substr (charvar6, 1, 1)); call ioa_ ("^f", fixbin17); end; Note: When the above code is compiled with prefixes enabled, apparent corruption of registers or stack tempories causes the value stored in fixbin 17 to be 0 regardless of the content of charvar6 . The implementaion of rank builtin assumes its argument will be in the high order byte of the A. In the case of strings whose length is given by an expression (as opposed to a constant) this will not be the case, resulting in incorrect code. (TR11008, TR17956) 2076 phx10128 code generated for initial lists of the form 'initial(val1,val2,...,*,*,val)' fails randomly for varying character string arrays and fixed or float decimal arrays. The initialization code depends upon the assumption that assigning undefined values is safe. This fails for varying string and decimal data types. Expand_initial.pl1 should be fixed not to do this. (TR10128) 2072 phx09985 fred = decat((fred),"xyz","101"b) faults in the semantic translator when fred is declared char varying. (TR9985) 2070 phx09528 phx14896 phx16971 Compiler error 315 occured when compiling a multiple assignment. The following test case illustrates the problem: stack_compute:proc; dcl stack_index fixed binary (18); dcl stack_base fixed binary (18); dcl stack (0:999) fixed bin (18) based (object_base); dcl object_base pointer; dcl lbound builtin; stack_index, stack_base = lbound (stack,1); end stack_compute; ERROR 315, SEVERITY 3 ON LINE 8 Compiler error: temporary node "cp.1" does not have value in storage. SOURCE: stack_index, stack_base = lbound (stack,1); The compiler error is probably caused by an error in machine state management, in this case, the location of a temporary was inconsistent. (See bug2153 for other problem when compiling a multiple statement.) 2069 phx09491 ERROR 79 (operands of an assignment operator have unequal dimensionality or structuring) is gotten in an assignment statement of the form T=S,by name where T and S are based structures. When the based attribute is removed, the assignment statement is accepted. (TR9491) THIS ERROR LIST ENTRY IS OBSOLETE. SEE NUMBER 2109 IN THIS ERROR LIST. 2067 phx09439 compiler creates segments named "X.lis" where "X" is 28 chars long. (TR9439) 2066 v2pl1 goes into an infinite loop calling pl1_symbol_print if it hasn't called the code generator and pl1_symbol_print faults. (MPRF 6558, bug1851) 2065 pl1_symbol_print faults if it needs to print out a block name and the semantics hasn't processed the block (the semantics could have faulted earlier ...) It gets a token node in the first label of the first statement of the proc instead of a reference node. (MPRF 6558) 2063 phx09363 code gen doesn't realize floating point instructions kill a common offset expression in q. Shows up with -ot. (TR9363) 2062 phx09361 return(f(n)) in a returns(char(*)) proc where f is returns(char(*)) fails when there is another entry to the proc which returns(char(10)var). (TR9361) 2061 phx09310 return(bit(cs)) in a returns(bit(*)) proc where cs is char(*) parm fails. cs isn't converted to a bit-string. (TR9310) 2059 ptrs declared by context aren't listed in the "NAMES DECLARED BY CONTEXT OR IMPLICATION" section. 2058 phx09228 an index register value is sometimes destroyed and then saved. (Bug in xr_man? See TR) (TR9228) 2056 phx09125 phx10131 the round_fx1 operator doesn't set the indicators to reflect what's in the q. (TR9125, TR10131) 2055 phx08869 (strg):put edit(rtrim(s(i)))(a) where s is (*)char(12) fails. Always puts s(1) because strg code kills char offset in a. (TR8869) 2051 phx09045 decat(s,rtrim(c),"101"b) fails. Code to compute rtrim(c) is omitted. (TR9045) 2050 phx10077 phx10185 phx02606 a=min(b,c)[or max][or unspec ] where a,b,c are fixed bin(36) uns unal generates staq/cmpaq/ldaq instructions to odd addresses. (MPRF 6397)(TR 10077)(TR 10185) 2048 phx08902 phx14969 phx09881 PL/1 should not use index register which is 18 bit to hold value that exceed the precision of fixed bin (17) . The following test case illustrate the problem: test: proc; dcl Aarray (1000) fixed bin; dcl Barray (1000) fixed bin; dcl Aarray_index fixed bin (35); dcl Barray_index fixed bin (21); Barray_index = 2**20; Aarray_index = Barray_index + 1; Aarray (Aarray_index) = 69; Barray (Barray_index) = Aarray (Aarray_index); end test; Barray (Barray_index) = Aarray (Aarray_index); 000037 aa 6 00077 2361 17 ldq pr6|63,7 Aarray 000040 aa 6 04021 7261 00 lxl6 pr6|2065 Barray_index 000041 aa 6 02047 7561 16 stq pr6|1063,6 Barray 2047 call e(reverse(bit(bin(m,2),2))); where e is entry(bit(2)) and m is fixed bin gets ERROR 316 and then ERROR 313. 2046 phx08683 substr(structure,1,length(scalar)) gets ERROR 121 instead of promoting length(scalar) to a structure. (TR8683) 2044 phx08822 tanget_$double_tanget_degrees_ fails on 90. It signals error because argument is too close to singularity, but when user types start according the deh message, it takes overflow muliplying max_value by the input. Code for determining sign of result in error case is wrong. (TR8822) 2043 s.form=8 fails where form is fixed bin(5) uns unal, the first two bits are in one word, the last three bits are in the next word. The q is not cleared. (MPRF 6270) 2042 phx09184 phx09839 phx12632 phx20389 phx15287 If the argument used in rank builtin is a varying character string, internal compiler error occurs. The following test case illustrates the problem: test: proc; dcl ch1 char (1) var; dcl rank builtin; dcl val fixed bin; ch1 = "1"; ch1 = rank (ch1) - rank ("0"); end; ERROR 374, SEVERITY 3 ON LINE 7 Compiler error: attempt to load decimal value "ch1" in a register. SOURCE: ch1 = rank (ch1) - rank ("0"); pl1: An error of severity 3 has occurred. Note: ERROR 374 is not meaningful. Also the documentation of rank is unclear and ambiguous. Proposed solution: (1) builtin.pl1 - If the argument used in rank builtin is not a non_varying character string of length 1, display new error message instead of error 374 (the compiler error) . (2) pl1_error_messages_.message - add a new error message. (3) AG94 manual - The documentaion of rank should be defined better. DOCUMENTATION CHANGES: Manual Update for AG94C, Page 13-6.1 REPLACE X must be a character string of length 1. WITH X must be declared as a non varying character string of length 1. 2040 phx08441 out=translate(in,to,from) fails on -no_optimize where in, out are declared char(bc/9). The translate_3 operator leaves result in string_aq, then divide_fx1 is used to calculate length of result. Divide_fx1 destroys string_aq. Macro_table is correct. (TR8441) 2039 phx08518 build_message_segment incorrectly checks for bad severities. Bad severities always get set to zero in pl1_error_messages_. These messages never get printed because 0 < -sv1. (TR8518) 2034 phx08211 the compiler fails to match a generic alternative when the parameter and argument selector are dimensioned structures. (TR8211) 2032 ptr(p,varying_bs) fails. It gets bad inline code. 2029 phx02362 phx11643 compiler faults in semantics on (subrg):p->a.c(1)=y; where a.c is a based struc with refer extents and y is like a.c. May be related to 1969. (TR2362) 2028 phx08093 phx08708 a-b fails where a is fixed bin(35,35) and b is fixed bin(35,33). (TR8093) Also fails where a is fixed bin(35,2) and b is fixed bin(35). (TR8708) 2027 references to s.m(even_number).a fail where each element of s.m takes an odd number of words, s.m.a is fixed bin(71) unal and s.m is preceded by an aligned ptr. Compiler generates staq/ldaq with odd addresses instead of sta-stq/lda-ldq pairs. (MPRF 6080) 2025 the compiler faults on the return statement in a returns(area(*)) procedure. 2011 if b="b" then ... fails where b is char(1) unal auto and aliasable. Pad bits in b's word are not masked off when b is loaded into a. Also fails for aligned. 2008 phx07288 p->s.descs(*)=q->s.descs(*) fails where s.descs and a preceding structure member are arrays with auto variable extent expressions. Offset of s.descs is computed incorrectly. (TR7288) 2006 phx07180 hbound(a(1,*),1) is evaluated as hbound(a(*,*),1) instead of hbound(a(*,*),2). (TR7180) 2000 phx07142 dcl entry entry(entry) returns(entry returns(entry)) variable; call entry(entry); gets fault_tag_1 in function. call entry(entry)(); gets no_write_permission in function. Both statements are valid. (TR7142) 1998 phx07077 references to a(1).b.c where c is char(1) unal, starts on word boundary and following member of b is word aligned, are not padded correctly. Stores should clear padding but don't. Fails when a simpler structure is based on array element that assumes padding is clear. (TR7077) May be related to 1757. 1994 phx20881 PL/1 complains about the attributes of variables with ERROR 15 on a the seemingly valid declarations: dcl a fixed bin (op_con1) static options (constant) init (1); dcl xx (3:op_con1) fixed bin (op_con1); where op_con1 is declared as static options(constant) init (15); Since op_con1 can yield a scalar value that is suitable for conversion to a fixed_point, binary, real and integer, the compiler should allow the above declarations. 1993 "s.l=c.u; if s.l=c.u then ..." fails with -ot where s.l is bit(2) unal and doesn't start on a word boundary and c.u is bit(2) unal int static options(constant) and doesn't start on a word boundary. (MPRF 5633, MPRF 5830) 1992 if a bound on an array is defined on a structure member, a garbage runtime symbol table entry is built. Either (1) an error message similar to ERROR 306 should be issued and a known quantity put in the runtime symbol table that will not cause stu_ to fault, or (2) if a correct runtime symbol table entry can be built, one should be. (MPRF 5792) 1987 phx06761 bool(a,"1"b,var) where a has star-extents gets ERROR 329. (TR6761) 1983 fixed dec(5,-6) variables are listed as fixed dec(5,6) in the symbols section of the listing. 1982 bad inline conversion code is generated to convert fixed dec(5,5) to char. 9f-5 is incorrectly converted to 0.0000 instead of 0.00009. The second mvne mop that is generated is an insm 1. This should be omitted. 1979 if a varying int static array gets ERROR 292, and a subscripted array reference is used, the compiler goes into an infinite recursion loop. 1976 passing an offset variable as an argument where the parameter is a ptr fails. The offset is converted to a pointer via the pointer operator, but the result is not saved. 1972 phx06423 bad code for area=empty(); where area extent is 2**15. After call to decimal_exp_, a bad mvn instruction is generated which tries to write in the object segment. (TR6423) 1969 phx06361 compiler faults in expand_assign on (subrg):a(1)=s; where a is a refer extent array of structures and s is a structure. May be related to 2029. (TR6361) 1967 phx06317 unspec(s.vs)=... where s is a structure of varying char strings and vs isn't the first member of the structure gets bad code. (TR6317) 1966 phx06198 phx06967 label_constant_1=label_constant_2 gets bad code. An eraq is done with contents of an instruction word instead of the address of the instruction. Also fails for entry constants. (TR6198, TR6967) 1965 phx06221 sin(picture), asin(picture) gets ERROR 136. (TR6221) 1958 phx05870 on input, PL/I I/O does not default e(5) format to e(5,0), but to e(5,). (TR5870) 1956 "put data;" prints garbage for a variable declared in an outer block that hides the declaration of another variable. 1955 if a variable is declared in a quick block with a complicated extent expression dependent upon a parameter to the quick block, and the quick block is called with a constant (itp) argument list, then the extent expression is calculated incorrectly when the thunk is called by probe or debug. The pointer registers that the itp argument list uses, namely pr6, are not the same when the thunk is invoked as when the quick block was called. Constant (itp) argument lists should not be used for blocks which generate thunks or for blocks whose sons generate thunks. 1954 "put data;" fails if a variable is declared with a complicated extent expression dependent on a parameter, and the "put data;" is inside a nested non-quick block. PL/I I/O calculates an incorrect display pointer which it passes to stu_$decode_runtime_value which passes it to the thunk. 1953 "put data;" fails in a program with based variables without implicit qualifiers. put_data_var_all_ cannot get the runtime address for a garbage symbol table offset. Also fails if the implicit qualifier is based(addr(w)). 1949 compiler gets ERROR 313 when it is forced to make an aggregate temporary whose length depends upon the length of a varying string. Works for nonvarying strings. 1940 a variable s is never allocated if s is int static options(constant), only use of s is in based(addr(s)) and only use of overlaid string is in argument list. 1933 phx03816 a calls b, b calls c, b compiled with -lpf, a, c weren't, c does a non-local goto back to a. The lpf data for the call statement in b will contain garbage. (TR3816) 1932 phx03815 a calls b, b compiled with -lpf, a wasn't, b does a non-local goto back to a. The lpf data for the goto statement in b will contain garbage. Lpf code should figure out how much time is used by goto statement before it really transfers. (TR3815) 1930 phx03784 under rare circumstances the same index register is sometimes used for two index values. The arrays are star extent arrays of structures. Fails w/o -ot. (TR3784) 1928 phx03798 the sin builtin for single precision numbers gives notably less accurate results for arguments in the range 1/5681 to 1/256. Currently sine_ uses sin(x)=x approx for 0 to 1/256. and a polynomial for (1/256, .3). Change it to use the polynomial for (1/5681, .3). See new_fortran bug 244. (TR3798) 1922 phx03454 compiler gets size converting 5.6e2+5.6e2i to its internal representation. (TR3454) 1917 phx03228 the offset in chars from the beginning of the source segment to a source statement is stored in a bit(18) field in the symbol table statement map. This means that source segments >64K words long cannot be handled. (TR3228) 1912 phx03239 bad code for return(unconnected_array) where proc is returns((5)char(*)), returns((*)char(7)) or returns((*)char(*)). (TR3239) 1909 phx05357 bad code for z=translate((z),constant,constant) where z is char(3) aligned. Compiler fails to realize that the mvt to translate z kills the value of z in a register. See 1908. (TR5357) 1908 phx05357 phx07181 bad code for z=translate(z,constant,constant) where z is char(3) aligned. Z is zeroed before it is translated. (TR5357) Also fails for char(5) aligned. (TR7181) 1906 phx03077 phx08604 phx10024 phx11508 for some assigments of one element of a refer extent array in a structure to another when subrg is enabled, compiler incorrectly generates code to check that lhs and rhs arrays have the same bounds eventhough only one element is being assigned. (TR3077, TR8604, TR10024) 1900 phx03032 phx08645 compiler faults promoting scalar refer extent char string argument to an array. If argument is enclosed in parentheses, compiler doesn't fault but generates bad code. (TR3032) Also fails promoting star extent scalar parameter char string argument to an array. (TR8645) May be related to 1868. 1899 phx02993 m_a references through null ptr on write from(s) where s is a defined structure. (TR2993) 1898 when compiling a program with -tb that uses two arrays with different extent expressions that use the sum bif, compiler gets ERROR 313 and then faults in cg. Also fails if the two arrays have the same extent expression, but one is in an inner block. 1895 phx02761 phx19587 phx17702 Semantic translator (declare_descriptor$builder) references through null ptr on invalid returns syntax: returns(char(len)). (TR2761) returns(float(1:n)) (TR19587) PL/1 should print an error message instead of a null pointer condition when a invalid return clause occurs as the above. Proposed solution: declared_descriptor.pl1 - To avoid references through null pointer on invalid returns options, add checking for null pointer, if so display existing error 22 or 37. 1894 phx02530 Bad code with -ot: compiler doesn't realize that setting a member of a structure sets unspec(structure). (TR2530) 1887 A warning should be issued similar to ERROR 306 when a program is compiled with -tb and contains constructs that cannot be represented in the runtime symbol table, e.g. based(exp). An error message should be issued when put data will fail because of based(exp). 1886 phx15311 "PL/1 gets confused about the bounds attributes of the defined overlay, and it insists on passing the array by value despite the fact that its bounds match the requirements of ""subroutine"". The following test case contains two examples of overlay defining, one using based (addr) and one using the defined attribute, the latter results in warning error 47. test : procedure; dcl (start, count) fixed bin; dcl array (20) fixed bin; dcl nothing entry options (variable); dcl subroutine entry ((*) fixed bin); call nothing (array, start, count); begin; dcl based_overlay (count) fixed bin based (addr (array (start))); dcl defined_overlay (count) fixed bin defined (array (start)); call subroutine (based_overlay); /* but this works */ call subroutine (defined_overlay); /* This fails */ end; end test; WARNING 47 ON LINE 13 ""array"" has been passed as an argument by value rather than by reference because its attributes did not match the parameter to which it was passed. SOURCE: call subroutine (defined_overlay); Note: The warning message 47 is not appropriate. It should indicate the name of the defined variable, not the name of the base reference." (MPRF 5369) 1885 phx04118 phx09324 phx17971 PL/1 optimizer mishandles concatenation of 3 or more short character strings. A store to a temporary is omitted. bug : proc; dcl a char (1) init ("a"); dcl b char (1) init ("b"); dcl c char (1) init ("c"); dcl d char (1) init ("d"); dcl e char (1) init ("e"); dcl f char (1) init ("f"); dcl (s1 , s2) char (5) init (""); dcl ioa_ entry options (variable); s1 = a||b||c||d||e; s2 = a||b||c||d||f; call ioa_ ("s1: ^a s2: ^a",s1, s2); return; end bug; ! pl1 bug -ot PL/I 25 bug s1: abcde s2: abc f Note: When compiled with "-optimize" , the middle char "d" is dropped from s2, whereas compiled without optimization, correct result is printed. 1884 phx04044 Varying internal static bit strings with init attribute are initialized to be one bit longer than they should be. (TR4044) 1882 phx03932 phx03989 phx06421 Get data of char(1) unaligned padded vars fails to clear padding at the end of the word. Also happens for conversions done by any_to_any_ where the target is unal and padded. Also fails for short bit strings. (TR3932, TR3989, TR6421) 1880 phx03252 phx03861 phx11871 Bad code for string(struc)=... where the last member in struc is padded. The assignment does not clear the padding. Struc may be longer than 2 words. Fails for both char strings and bit strings. May be related to 1882, 1757. (TR3252, TR3861) 1879 phx04163 phx05173 Bad code for fixed dec(p,q) ** fixed dec(r,0). The scale factor seems to be ignored. The result is converted to fixed instead of being left as float. (TR4163, TR5173) 1875 phx04808 Bad bif code for copy(exp,exp). Possible reusing of temporary. (TR4808) 1871 phx04529 Call_op references through null ptr if internal entry constant is declared by dcl stmt, but no such internal procedure exists. (TR4529) 1870 phx04626 Runtime signals error condition because of a bad type field in descriptor of output item on put data(format_variable). (TR4626) 1868 phx04562 The compiler faults in base_man while compiling a statement in which a scalar argument is promoted to an array in an argument list. The scalar (char(32)) was initialized to more than one value. (TR4562) May be related to 1900. 1867 phx04507 Using multiple assignment statements to store the same variable in more than 11 other variables fails. Bug in store. (TR4507) 1864 phx19469 If two variables are declared fixed bin int static options(constant) with the same initial value, and the initial value>1, one is placed in "NAMES DECLARED BY DECLARE STATEMENT" section of listing, and the other is placed in "NAMES DECLARED BY DECLARE STATEMENT AND NEVER REFERENCED" section. The -table control argument must be specified. Oct 3 1985: Actually this problem occurs for non fixed bin constants too. See associated TR. 1863 If an internal procedure with a returns attribute is invoked in an argument list with a returns(char(*)) function, the internal procedure is not made non_quick eventhough it will be invoked during a stack extension. 1854 when pl1 is changed to use 32K constant offsets, the listing generator will have to have the bug fixed that prevents listing them properly. (see new_fortran listing generator) (compare_object has to be fixed, too). 1850 phx02643 dcl 1 struc based, 2 x ptr unaligned, 2 y(0:n) ptr unaligned, 2 z(-1:n+1) ptr unaligned; gets FATAL ERROR 310 when compiled with -table and n is internal static. This appears to be a general problem with unaligned pointer arrays with expression extents. (TR2643) 1849 phx02768 arg1,arg2,...,argn are passed to entry_valued_function in reverse order when entry_valued_function returns(entry) in statements where the returned value is invoked and the argument list for the returned enty is omitted. Example: call entry_valued_function(arg1,...,argn); fails. Bypass by specifying omitted null argument list: call entry_valued_function(arg1,...,argn)(); succeeds. (TR2768) 1840 phx02956 reference to a level 1 defined structure in the from option of a write statement causes FATAL ERROR 310. (TR2956) 1839 phx02956 assign statement involving pictures peceded by a reference to the convert builtin (conversion of picture to character data) sometimes causes the compiler to fault. (TR2963) 1838 when an external entry is declared by context or implication the first reference to the entry does not appear in the cross reference listing. 1835 bad runtime symbol table entry built for offset variable whose area reference has a non-constant offset expression. This causes trouble with get data, put data, probe, and debug. 1824 The compiler fails to diagnose the specification of more than one precision for a parameter in an entry declaration. 1819 call subr(labarray); where labarray is a label array constant, gets FATAL ERROR 335. 1818 References to members of structures declared with the like attribute are somtimes omitted from the cross reference listing. When compiled with the -table control argument the structures are also omitted from the runtime symbol table. 1815 phx02375 , = ; gets errors 200 and 498 about bad declaration. Bug in expand_assign. 1798 a bad while clause in a do statement can cause FATAL ERROR 334. 1795 phx06934 phx08146 phx10569 phx02501 phx12672 phx17741 the stack may not be shortened after evaluation of the expression in an if statement. (TR6934, TR8146, TR10569, TR2501, TR12672, TR17741). It may be related to Error 2172). 1794 substr(str,(i),1) gets ERROR 313 and bad code. 1787 close_file command won't close (or detach) files attached explicitly by the user (using io attach, etc). This is probably reasonable, but it should print an error...it is a little mysterious to say 'cf foo' and have nothing happen! 1778 the error condition should be signalled when a variable with a value of zero is raised to the zero power. The error condition isn't signalled when the exponent is a constant. 1770 phx19673 Bad offset is found in PL/1 error message regarding a size condition. The offset is set to zero which is not corresponded to the line where the error occured. Also probe seem to get very confused about the values of arguments to the subroutine. Test case: test: proc; dcl sysprint file; dcl str char (8) init ("string"); dcl value (array_size) controlled; dcl array_size fixed bin init (8); allocate value; value (*) = 100.0; call sub (); free value; return; sub: proc (); put edit (str, value) (skip,a,8(p"z9")); return; end sub; end test; PL/I 28e Error: size condition by >udd>TR>Gilcrease>work>test$p|0 Precision of target insufficient for number of integral digits assigned to \c it. system handler for error returns to command level Note: if "value (*) = 100.0" is changed to "value (*) = 50.0" then the output string will be 5050505050505050 . 1757 phx01691 assignment to a packed word-aligned aggregate of less than 2 words in length may fail to take into account any padding used to pad out the last member of the aggregate to a word boundary. (TR1691) May be related to 1998. 1741 if a locate statement gets the storage condition, an attempt to close the same file gets out_of_bounds. 1739 phx07140 diagnose refer extents that refer to variables after the array instead of before it. Compiler gets storage conditions, incorrect ERROR 70's or fatal process errors if not diagnosed. (TR7140) 1737 dcl i fixed bin external constant; should get error message complaining that only files and entries may be external constants. Instead FATAL ERROR 310 often occurs. 1736 dcl a(4) fixed;dcl b(2) def(a(*)); call foo(b); where foo expects an array of 2 gets WARNING 47. Either compiler & documentation should disallow the declaration because array sizes don't match for simple defining, or the WARNING should be removed and the array should be passed by reference. 1726 if the expression to the left of a refer option contains an irreducible function reference, the value of the expression used to determine the size of the based structure may not be the same as the value used to initialize the variable named in the refer option. 1722 put data fails if there is a data list, the data list contains a string with refer extents or a structure containing such a string, and an explicit qualifier which is different than the implicit qualifier (if any) is used. 1702 phx12788 passing an isub-defined array to an options(variable) entry gets error 248. 1688 float bin to fixed bin conversion operators do not signal size if abs(input) >= 2**71. any_to_any_ works OK. 1678 if a default stmt is used in a program with a picture format, an erroneous WARNING 206 results. 1672 The base (binary or decimal) of real constants passed to options(variable) entries varies depending on whether the program contains any default statements or not. Further, the action when no default statements are present is wrong! A constant like 0 is incorrectly passed as binary if no default statements are present, and correctly passed as decimal if any default statements are present. System entries like com_err_ (but not ioa_) expect binary values only. Programs that use both default statements and options(variable) should include a default statement of the form: default (constant & real) binary; in order to get constants converted to binary. An alternate solution is to write the constant in binary (0b) instead of decimal (0). This problem will be fixed in phases; the first phase will be to just diagnose the present incorrect action, the second phase will be to change the implementation. 1670 dcl x(size(y)) fixed; produces ERROR 295 if y is based on automatic ptr even though the ptr isn't used to get the size. 1669 phx14496 passing a part of an array containing characters as argument gets FATAL ERROR 335 or ERROR 343. test:procedure(str); dcl str(*,*) char(*); call inner(str(1,*)); return; inner:procedure(str1); dcl str1(*) char(*); str1(1)="a"; return; end inner; end test; FATAL ERROR 335 ON LINE 3 Compiler error: null_pointer condition while in the semantic translator. Correct all source program errors and recompile. If this message persists, contact the compiler maintenance personnel. SOURCE: call inner(str(1,*)); 1665 the copy file does not contain the correct output if some get statements to a file use the copy option and some do not. Problem is that the entire input buffer is copied, instead of just the input characters scanned. 1532 The size condition is not raised in some circunmstances although the PL/1 standard says it should be: (1) when a negative floating point number that exceeds the field width by one character is output by a "put edit" statement. (2) when an e_format is given with only a field width, i.e. "put edit ...(e(w));" that the field width is insufficient to prevent loss of low order digits. Because of performance implications, there are no plans to correct this behavior at this time. time." 1408 phx05595 a non-local goto into a stack frame which has been extended (by signalling the conversion condition or by a string expr in an arglist) does not shorten the frame, possibly leading to stack overflow (isn 8689). Possible fix: if a statement has a label that is referenced non-locally or that is assigned to a label variable, then always shorten_stack before that statement. (TR5595) 1401 extent expressions for members of nonparameter structures with no explicit storage class may be handled incorrectly. 1309 get data, put data, debug, and probe fail for any based variable whose implicit qualifier is other than a simple reference to a scalar pointer or offset variable (c53184). There is presently no room in the runtime_symbol node to encode a more complicated qualifier expression. 1186 phx03594 phx05101 phx13134 phx16426 phx19743 phx15634 THIS IS THE PADDED REFERENCE BUG. dcl c char(<8) auto|static unal;dcl cb char(<8) unal based(addr(c)); references to cb are not padded while references to c are. This is part of a more general problem which has always existed and cannot be fixed without recompiling every program at every Multics site. In general, if a short based or external string which normally can be padded to a word boundary with zeroes is set in a program that also passes it as argument, the padding does not take place, causing problems if another program, which does not pass it as arg, references the string with the assumption that the padding has been done. Padding is normally done if a short string is aligned or is not followed by an unaligned var in a structure. Inconsistent result is generated when referencing a PL/1 character variable of less than a word. Test Case: test: proc; dcl (source, string) char (2); dcl bstring char (2) based; dcl addr builtin; dcl ioa_ entry options (variable); addr (source) -> bstring = "10"; if string ^= "10" then call ioa_ ("bad news."); end; Note: The above test case is not guranteed always fail, but it generally do so because of the existing padding reference problem. 1006 into, from options and string, unspec builtins fail for a connected array reference whose declaration inherits some dimensions from a containing structure. This is a rare case. Example: dcl 1 st(3), 2 a fixed bin; write from(a); Note that st has no other members. Also, the compiler doesn't check that the above options or builtins have connected references. ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL and BULL HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by BULL HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved