CC7A BUGS --------- NOTES: This list contains the bugs that produce wrong code. Compiler weaknesses which produce error messages are normally not included in this list. The bugs applies only to the stated compiler version(s), (using from - to notation) and the versions in between these. Bug reports starts with version 1.0 Last updated: 21. September 2020 BUG 24: Code generator bug ==> Version 1.0 - 1.0K It is possible to write improper code for SFR registers. In these cases the SFR register is used as a temporary register during the calculation. This may lead to undesired side effects. PORTD = (data & 0x0F) << shift; PORTC = (data | 0x5) - vx; Reported by: V Komarkov BUG 23: Code generator bug ==> Version 1.0K SFR registers in bank 1 and upwards may not be detected properly for some locations, which may lead to code generation issues. Code are generated as if the SFR are RAM locations. The problem is caused by the different internal compiler handling of address calculation for the SFR address space versus the RAM address space. The problem applies to around 20 % of the SFR registers located in bank 1 and upwards. Reported by: V Komarkov BUG 22: Code generator bug ==> Version 1.0 - 1.0J Accessing a large table using offset between 128 and 256 may result in a strange error. The problem is due to wrong internal type handling. uns16 m16[90]; .. m16[65] = 1000; // Wrong error: Offset out of range m16[(uns8)65] = 1000; // FIX / workaround Reported by: S Nagasue BUG 21: Optimization bug ==> Version 1.0 - 1.0J Bank bit updating may fail for special purpose registers located in bank 1 and up. PORTC = 0x55; if (PORTC != 0x55) err = 1; // BUG, register not reloaded Turning off optimization locally will prevent the bug. #pragma optimize 0 if (PORTC != 0x55) err = 1; // FIX #pragma optimize 1 Reported by: V Komarkov BUG 20: Bank bit updating bug ==> Version 1.0 - 1.0H Bank bit updating may fail when accessing const data implemented as a return table containing a multiple of 256 RETLW. This happens for access functions implemented directly by application code and access functions generated by the compiler. Further conditions for the bug that the last bank access before the return from the access function is different from the first bank access after the return. A workaround for the bug is to use a manual bank bit update: #pragma updateBank 0 // enter manual bank bit updating BSR = 0; // update bank #pragma updateBank 1 Reported by: J Bodin BUG 19: Bank bit updating bug ==> Version 1.0 - 1.0H Using two computed goto regions in a single function may cause wrong bank bit updating when entering the second computed goto region in some cases. The workaround is to inspect the generated code when a double computed goto is used in a single function. Then insert a manual bank bit update if the generated code is not correct. #pragma updateBank 0 // enter manual bank bit updating BSR = 0; // update bank #pragma updateBank 1 Reported by: J Bodin BUG 18: Code generator bug ==> Version 1.0 - 1.0H Wrong code is generated for certain expressions that use Carry to transfer a 'bit' value. Examples: bit TestFunc( void) { uns8 a8, b8, c8; if (...) return a8 + b8 == c8; // BUG Carry = Get8bitValue() != c8; // BUG return Get8bitValue() == c8; // BUG } Reported by: H Syrovátka BUG 17: Code generator bug ==> Version 1.0 - 1.0H Wrong code is generated for the following cases: uns8 u8, a8; u8 = (a8 & 0x0F) >= 0x0A; // Wrong code u8 = (a8 & 0x0F) < 0x04; // Wrong code u8 = ((a8+10) & 0x0F) > 0x0D; // Wrong code u8 = (func() & 0x0F) > 0x0D; // Wrong code u8 = func() >= 0x02; // Wrong code u8 = a8 + (func() >= 0x02); // Wrong code W = func() >= 0x02; // Wrong code .. char func() { return W; } BUG 16: Code generator bug ==> Version 1.0 - 1.0H Wrong code is generated for some special constant expressions. The general expressions are: var - K1 + (K2 op K3) var + K1 - (K2 op K3) 1. K1, K2 and K2 can be single constants or constant expressions. 2. K1 must be size 2 or larger (int16/uns16). 3. (K2 op K3) must be size 2 or larger (int16/uns16). 4. K1 must be larger than (K2 op K3). Examples: uns8 u8: u8 = u8 - 0x80 + (0x81 - 0x80); // BUG W = (int16)(W - 128U) + (0x81 - 0x80); // BUG W = W + 0x80 - (0x81 - 0x80); // BUG W = W - (0x80 + 3 - 3) + (0x81 - 0x80); // BUG W = W - 0x80 + (2001 - 2000); // BUG Reported by: H Syrovátka BUG 15: Code generator bug ==> Version 1.0 - 1.0H Wrong code is generated for some special conditional expressions using the & operator. The compiler will print a warning telling that the expression is always false or true. The problem only applies to variables of 16 bit or greater when using the > or <= operators. uns16 u16; if ((u16 & 0xF00) > 0xE01) .. // wrong code generated if ((u16 & 0xF00) <= 0xE22) .. // wrong code generated BUG 14: Variable overlapping bug ==> Version 1.0 - 1.0H Wrong code is generated when a function parameter is set to overlap with a global variable allocated by the compiler. This problem does not apply to parameters that overlaps with variables set to specific addresses before compilation. uns8 var; void func( uns8 par1 @ var) { .. } // wrong code generated Reported by: H Syrovátka BUG 13: Const data bug ==> Version 1.0 - 1.0H Accessing a large table (> 256 bytes) of const strings stored in a single table may fail. Only the first 256 bytes will be accessed. const struct { char str[10]; } Cbus[] = { "String1", .. "String30" }; // 10 * 30 = 300 bytes .. char k; writeString( &Cbus[k].str[0]); // wrong code generated BUG 12: Floating and fixed point bug ==> Version 1.0 - 1.0G Floating and fixed point local variables are not handled correctly when using the 'const' type modifier. Assignments and many operations including math library operations are wrong: const float z = (long)16*16; // BUG const fixed16_8 ee1 = 512; // BUG const fixed16_8 ee2 = 512.0; // OK float x; x = z; // BUG if (z == 3.2) // BUG .. if (z < 3.1) // BUG .. if (z == x) // BUG .. if (z >= x) // BUG .. x *= z; // BUG BUG 11: Fixed point bug ==> Version 1.0 - 1.0G The sign bit is not extended when using type cast on fixed point variables. fixed8_8 as8_8, bs8_8; fixed16_8 as16_8; as16_8 = (fixed16_8)as8_8 + bs8_8; // BUG Reported by: P van der Hulst BUG 10: Code generator bug ==> Version 1.0 - 1.0F Wrong code is generated for 8 bit signed right shift by 4 when using the W-register. int8 a, b, c; W = (int8)W >> 4; // WRONG CODE a = (b + c) >> 4; // WRONG CODE BUG 9: Fixed point bug ==> Version 1.0 - 1.0F Wrong code is sometimes generated when comparing an unsigned fixed point variable to a constant. The compiler warns that the expression is always true or false in these cases. A similar problem applies to signed and unsigned fixed point variables when the constant is out of range. Then the warning is sometimes wrong (always true instead of always false or opposite). fixedU8_8 delta; fixed8_8 aa; if (delta > 200.1) // BUG .. if (aa > 200.1) // BUG: Constant out of range, wrong warning .. Reported by: P van der Hulst BUG 8: Inline code bug ==> Version 1.0 - 1.0E Wrong code is generated for the following complex expression when using inline code (no math library call). The expression must be 16 bit or larger and contain (at least) 3 constants. The innermost expression must be subtraction or addition. The next operation must be multiplication. The error occur when the compiler tries to simplify the expression by moving the innermost constant. uns32 nCount, frequency; nCount = ((frequency - 100) * 2) / 12800; Reported by: S Reardon BUG 7: Typedef enum bug ==> Version 1.0 - 1.0E Wrong code is generated when reading enum const data to an enum variable. typedef enum { .. } A_list; const struct state_entry { A_list action; } arrayX[] = { .. }; A_list action; uns8 x; action = arrayX[x].type; // Wrong code generated Workaround: Use "uns8 /*A_list*/ action;". Reported by: C Belfer BUG 6: Fixed point bug ==> Version 1.0 - 1.0D Wrong code is generated when casting a constant expression to a fixed point type. fixed8_8 delta; if (delta > (fixed8_8)(-4.0/256.0)) // BUG .. Workaround: Avoid using fixed point typecast unless required. Reported by: P van der Hulst BUG 5: LCALL bug ==> Version 1.0 - 1.0D Wrong code is generated for LCALL. Reported by: S Shumilin BUG 4: Code generator bug ==> Version 1.0 - 1.0C Wrong code is generated in some cases when comparing for zero, typically when using the '||' operator right after the compare. The problem only applies when the code generator use the TSTFSZ instruction. unsigned char a; uns16 a16; uns24 a24; uns32 a32; if (a==0 || ..) .. // bug if (a<1 || ..) .. // bug if (a16<0x100 || ..) .. // bug if (a24<0x10000 || ..) .. // bug if (a32<0x1000000 || ..) .. // bug do { .. } while (a == 0); // bug Reported by: S Shumilin BUG 3: Code generator bug ==> Version 1.0 Wrong code is generated for the following special case. One argument must be indirect access of a 16 bit or larger variable. The other argument must be a constant. The problem applies only when comparing for equal or not equal. The problem applies when using a pointer or a table for the indirect access. uns16 tab16[10]; char x; if (tab16[x] == 2222) .. BUG 2: Const data bug ==> Version 1.0 Reading const data larger that 8 bit and storing indirectly using a pointer may fail. Only lower 8 bits are stored. uns16 *pDisBuf; const uns16 Segments[] = { 1000, 2000, .. }; char i; .. *pDisBuf = Segments[1]; // Wrong code generated pDisBuf[0] = Segments[i]; // Wrong code generated Reported by: W Mahringer BUG 1: Code generator bug ==> Version 1.0 Dividing a return value of 16 bit or larger is not correct when the function is second argument. uns16 u1, u2; uns16 read16( void); .. u1 = u2 / read16(); // Wrong code u1 = u2 % read16(); // Wrong code