MSP430 C/C++ CODE GENERATION TOOLS 16.9.0.LTS September 2016 Defect History ------------------------------------------------------------------------------- Table of Contents ------------------------------------------------------------------------------- 1. Defects fixed in MSP430 Code Generation Tools release 16.9.0.LTS 2. Current Known Issues =============================================================================== 1. Defects fixed in MSP430 Code Generation Tools release 16.9.0.LTS =============================================================================== The following 3 defects were fixed in MSP430 Code Generation Tools release 16.9.0.LTS, released September 2016. ------------------------------------------------------------------------------- FIXED CODEGEN-1285 ------------------------------------------------------------------------------- Summary : Remove -olength option from hex utility's help summary and Users Guides Fixed in : 16.9.0.LTS Affected Component : Hex Converter (hex) Release Notes: The help summary and Assembly Language Tools Users Guides mention the -olength option for the hex utility. However this option is not functional. The Users Guide lists this option in the summary but there is no detail on it. This option has been deprecated. ------------------------------------------------------------------------------- FIXED CODEGEN-1333 ------------------------------------------------------------------------------- Summary : Structure assignment causes compiler to fail with INTERNAL ERROR: Decomposition error. Fixed in : 16.9.0.LTS Severity : S2 - Major Affected Component : C/C++ Compiler (cl) Release Notes: Structure assignment causes compiler to fail with INTERNAL ERROR: Decomposition error. Workaround: Replace struct assignments involving packed structures with a memcpy() call to copy the contents of the RHS of the struct assign to the LHS. ------------------------------------------------------------------------------- FIXED CODEGEN-1417 ------------------------------------------------------------------------------- Summary : User error in _symval call causes compiler to issue INTERNAL ERROR: no match for ICALL Fixed in : 16.9.0.LTS Severity : S2 - Major Affected Component : C/C++ Compiler (cl) Release Notes: The argument to the _symval intrinsic must be the address of a static scope variable. If it is not, the parser may let it through, but the codegen will get a match failure, which is an internal error. Catch the problem early, in the parser. Workaround: Ensure that the argument to the _symval intrinsic is the address of a variable. =============================================================================== 2. Current Known Issues =============================================================================== The following 26 known issues exist for MSP430 Code Generation Tools release 16.9.0.LTS as of September 2016. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00008248 ------------------------------------------------------------------------------- Summary : Compilers on PC will not work without TMP set Affected Component : C/C++ Compiler (cl) Duplicate Defects : SDSCM00034609 Description: When compiling on the PC, the code generator cannot find the icode file produced by the parser if the environment variable TMP is no set. If TMP is set, then all appears well. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00008465 ------------------------------------------------------------------------------- Summary : Language Conformance: crash because of void pointer dereference Affected Component : Parser Description: Compiler generates multiple INTERNAL ERRORs when code like the following is compiled: void dr106_1(void *pv, int i) { *pv; i ? *pv : *pv; *pv, *pv; } ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00008537 ------------------------------------------------------------------------------- Summary : assembler expression ~(0x80000000) evaulates as 0x80000000 Affected Component : Assembler Description: The following expression is evaluating incorrectly in the assembler: .eval ~(0x80000000), mask mask ends up getting assigned 0x80000000, whereas I expect it to be 0x7FFFFFFF. It seems that any constant with bit 31 set will incorrectly return 0x80000000 ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00008543 ------------------------------------------------------------------------------- Summary : Forward reference in .space generates an internal error Affected Component : Assembler Description: If you attempt to assemble: .space 0+a b a .set 1 the assembler will generate an internal error. This happens with v3.83 and v4.1.0B1 on Solaris. If you change the code to: .space a b b .set 1 the correct error message is generated, 'Absolute, well-defined integer value expected'. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00008630 ------------------------------------------------------------------------------- Summary : printf gives wrong value for pointer when its value is incremented Affected Component : C/C++ Compiler (cl) Description: The following code does not execute correctly. On Compiling the code (v 3.83) the following warning occurs 'warning: pointer points outside of underlying object'. Code is: int global_var = 5; int main() { long int t; printf('0x%lx\n', 0x10000 + ((long int)&global_var)); } Workaround: To get rid of the warning message modify the printf statement as follows: printf('0x%lx\n', 0x10000 + (t=(long int)&global_var)); This modified code executes correctly too. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00008652 ------------------------------------------------------------------------------- Summary : pow(2,x) has fairly significant rounding error Affected Component : Runtime Support Libraries (RTS) Description: The algorithm used for pow [exp(log(x),y)] is correct but sometimes leads to a precision error for some inputs, due to rounding bugs in floating- point handling. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00008685 ------------------------------------------------------------------------------- Summary : DWARF does not correctly represent variables stored in register pairs Affected Component : Code Generator Description: In the attached example, variables 'var1' and 'var2' are both long long types, and are stored in A7:A6 and B5:B4. However, the DWARF information shows var1 only to be in A6, and var2 only to be in B4: [000000e8] DW_TAG_variable DW_AT_name var1 DW_AT_symbol_name _var1 DW_AT_type [00000113] DW_AT_location { DW_OP_reg6 } [000000fa] DW_TAG_variable DW_AT_name var2 DW_AT_symbol_name _var2 DW_AT_type [00000113] DW_AT_location { DW_OP_reg20 } ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00008928 ------------------------------------------------------------------------------- Summary : Extern inline functions are not supported in the C/C++ Compiler Affected Component : Parser Duplicate Defects : SDSCM00018364 Description: Users cannot create global accessible code with INLINE functions. The V3.00 compiler/code generator does not create globally accessible code for functions which are declared inline. A simple example is: inline int x() { return 1; } int y() {return 2;} When compiled with 'cl6x -k -c test.c', a warning is produced: 'test.c', line 1: warning: function 'x' was declared but never referenced and the resulting assembler file (test.asm) does not contain any code for x(). The documentation states that code declared inline will be inlined in that module but global code will also be generated (section 2.10.3.2 in v3.00 C Compiler manual). The new compiler is overly aggressive in its optimizations. If y() is modified to call x() then code is generated for x() unless the optimizer is also invoked (by using -x2). ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00014430 ------------------------------------------------------------------------------- Summary : calloc doesn't check arguments to make sure the requested size is reasonable Affected Component : Runtime Support Libraries (RTS) Description: The function calloc() is required to return a pointer to memory representing "nelem" copies of "size" bytes, or NULL if the request cannot be satisfied. However, for some values of "nelem" and "size" (specifically when the result of nelem*size wraps around), calloc can return a pointer to an object that is not large enough, rather than NULL. For example, on a 32-bit target, if the user calls calloc(0x00010001, 0x00010001), even though each argument by itself is reasonable, the request cannot be satisfied because the product is 0x000100020001, which exceeds size_t. (Note that we cannot check for overflow by checking if the product is less than either argument, which is commonly done for unsigned addition.) Arguably, we can try to claim that it is undefined behavior to make a call to calloc where the product would exceed size_t, but there doesn't seem to be anything in the standard which says so. The problem is worse on 16-bit targets, where calloc(0x0101, 0x0101) is enough to overflow size_t. It may not be obvious to the user that this overflows. Another concern is that it is hard to figure out whether a multiplication will overflow without having a double-width multiply available. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00018691 ------------------------------------------------------------------------------- Summary : Linker gives misleading warning when dot expressions used in SECTION directive for .stack section Affected Component : Linker Description: Linker gives the warning: warning: creating ".stack" section with default size of 0x800; use the -stack option to change the default size even when the application does not link in boot code from RTS lib. A linker command file is used that contains a specialized SECTION directive for the ".stack" section. Because of a series of ". += " assignments in the section spec, the linker is forced to increase the size of the .stack section to 0xc00. The linker is doing the correct thing by making a .stack section large enough to accommodate the dot expressions, but the diagnostic is misleading, as 0x800 isn't the final size of the .stack section. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00038178 ------------------------------------------------------------------------------- Summary : Should forbid non-const objects larger than 64k in large model if --near_data=globals Affected Component : C/C++ Compiler (cl) Description: In --near_data=globals mode (the default for large data model), it's not possible to create a non-const object larger than 64k, even in large data model. The compiler will accept it without error, but at link time there can be a mysterious relocation overflow, or if there is no link error, the test case can fail at execution time. It would be far better to catch this earlier and generate an error message saying "In --near_data=globals mode, non-const objects larger than 64k are illegal even in large model." ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00038293 ------------------------------------------------------------------------------- Summary : Relocation overflows for BIT instruction using 20-bit pointer Affected Component : C/C++ Compiler (cl) Description: When using options "cl430 -vmspx --data_model=large --near_data=globals", the compiler uses a BIT.W instruction to test a 20-bit address, leading to a relocation overflow. This bug does not happen if --near_data=none (the compiler uses BITX.W). The compiler should either use a BITX.W instruction to test expression which involve pointer addresses, or use a relocation that ignores overflow. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00040934 ------------------------------------------------------------------------------- Summary : Structure is not initialized correctly when using -o2 or -o3 optimization Affected Component : Optimizer Description: There is a problem with the initialization of a structure using symbols generated in the linker command file. We use symbols generated in the linker cmd file using the dot operator. These symbols are used as an initial value for a class/struct with a constructor. In our case we want the difference of two addresses that the linker generates. When using optimization -o2 or -o3, the compiler generates .cinit entries instead of the constructor call. In those .init-entries it doesn't use the difference of the addresses; instead it uses the first symbol. When turning off optimization or using lower level of opt than -o2, the constructor calls are generated and the struct is initialized correctly. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00044526 ------------------------------------------------------------------------------- Summary : Compiler emits bogus DW_OP_reg16 for split argument Affected Component : Code Generator Description: The fix for CQ42242 causes the compiler to emit "piece 2" parts of DW_AT_locations. The problem is that the code assumes that if the first part of the 32-bit argument was passed in a register, the second part is passed in the next register. This is only true if the argument is not split. MSP430 has 4 argument registers, R12 through R15. 32-bit arguments can be passed in adjacent (possibly unaligned) registers, or could be passed half in R15 and half on the stack. Here is a test case where the 2nd 32-bit argument is split: typedef struct ldiv_t { long quot; long rem; } ldiv_t; ldiv_t ldiv(long numer, long denom) { ldiv_t result; result.quot = numer / denom; result.rem = numer - (result.quot * denom); return result; } The struct return value is passed by reference as an extra parameter, so the above is handled as if you'd done this: typedef struct ldiv_t { long quot; long rem; } ldiv_t; void ldiv(ldiv_t *ptr, long numer, long denom) { ldiv_t result; result.quot = numer / denom; result.rem = numer - (result.quot * denom); if (ptr) *ptr = result; } The arguments are now: ptr R12 numer R13:R14 denom R15:stack However, the compiler emits: $C$DW$2 .dwtag DW_TAG_formal_parameter, DW_AT_name("numer") .dwattr $C$DW$2, DW_AT_TI_symbol_name("numer") .dwattr $C$DW$2, DW_AT_type(*$C$DW$T$12) .dwattr $C$DW$2, DW_AT_location[DW_OP_reg13 DW_OP_piece 2 DW_OP_reg14 DW_OP_piece 2] $C$DW$3 .dwtag DW_TAG_formal_parameter, DW_AT_name("denom") .dwattr $C$DW$3, DW_AT_TI_symbol_name("denom") .dwattr $C$DW$3, DW_AT_type(*$C$DW$T$12) .dwattr $C$DW$3, DW_AT_location[DW_OP_reg15 DW_OP_piece 2 DW_OP_reg16 DW_OP_piece 2] This is wrong; for "denom", "DW_OP_piece 2" should be on the stack, not "DW_OP_reg16". DW_OP_reg16 does not exist, and causes an assertion failure in my new DWARF code. For other reasons, the compiler will never split such an object unless the 2nd part is at FIRST_ARG_OFFSET. Any idea how to construct the DWARF tree that represents that location? [ See also SDSCM00049591 ] ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00046115 ------------------------------------------------------------------------------- Summary : MSP430 RTS float arithmetic functions do not round correctly Affected Component : Runtime Support Libraries (RTS) Description: The expression 1+DBL_EPSILON/2 should be rounded DOWN to 1.0 for only mode the TI compiler supports: "round to even" ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00046695 ------------------------------------------------------------------------------- Summary : FP rounding error, 1 ULP makes P70590.c fail Affected Component : Runtime Support Libraries (RTS) Description: IEEE-754 requires exact rounding for float addition. GCC gets 4056cf03 290a0f79 const folding gets 4056cf03 290a0f79 C6000 RTS gets 4056cf03 290a0f79 C6740 simulator gets 4056cf03 290a0f78 C6600 simulator gets 4056cf03 290a0f78 correct answer is ???? ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00047833 ------------------------------------------------------------------------------- Summary : msp C++ cpp compiled with printf_support=minimal causes cout to output incorrect results Affected Component : Linker Description: msp C++ cpp compiled with printf_support=minimal causes cout to output incorrect results And from further testing I found that -printf_support=minimal causes incorrect output from cout (prints out d instead of 1). I submitted CQ47833 for that since I think we have printf_support=minimal as default for CCS projects. Another solution to the printf_support=minimal would be to create an CCS project entry for new C++ project (we only have C code) and that project could have printf_support option left out. Not including printf_support, or choosing printf_support=nofloat and full both work. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00049278 ------------------------------------------------------------------------------- Summary : Array that is correctly initialized erroneously gets a MISRA diagnostic about size not being specified Affected Component : Parser Description: For this input ... int16_t y[]= {1,5,8} ; The compiler incorrectly issues this diagnostic ... "try1.c", line 2: warning: (MISRA-C:2004 8.12/R) When an array is declared with external linkage, its size shall be stated explicitly or defined implicitly by initialisation. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00049280 ------------------------------------------------------------------------------- Summary : Ill advised enum scalar usage gets MISRA diagnostic, but similar usage of enum array does not Affected Component : Parser Description: The test case given assigned a integer to an enum scalar variable. MISRA checking correctly flags this with a diagnostic. The test case goes on to do the same thing with an enum array expression. It should get the same MISRA diagnostic, but does not. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00049284 ------------------------------------------------------------------------------- Summary : Compiler misreports Misra warning 10.1 Affected Component : Parser Description: Compiler misreports MISRA warning 10.1/R for the following code. typedef enum _MyEnum { One, Two } MyEnum; MyEnum MyVariable; int foo(void) { int result = 1; if (One == MyVariable) // fails here with MISRA-C:2004 10.1/R { result = 2; } return result; } ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00050131 ------------------------------------------------------------------------------- Summary : Local struct with non-constant initializer treated as static scope variable Affected Component : Parser Description: We've discovered a problem where the C++ compiler places a local structure variable not on the stack but in the data segment, as if it was a static structure. The problem is especially insidious because the issue will only have an impact on re-entrance. The problem seems to occur only for C++ files, and only if the structure initializer list contains a variable. Constant initializer lists do not trigger the issue. The structure in the first function will be allocated on the stack, but the structure in the second will be compiled as if it was declared static. ------------------------------------------------------------------------------- KNOWN ISSUE SDSCM00051908 ------------------------------------------------------------------------------- Summary : Print a more friendly message when using a lnk.cmd with too large memory Affected Component : Linker Description: Print an error message when given a linker command file specifying memory ranges too large for the memory model to handle. When given a linker command file specifying memory ranges too large for the memory model to handle, the linker should print a more friendly error message and terminate. Older versions of the linker [than the 64-bit modified version in development] accepted the input and produced bogus cinit records Probably should not emit an error if there is a MEMORY defined in high memory, just if some section lands there. Otherwise, we'd get a spurious error if there is a linkfile shared between large and small model. ------------------------------------------------------------------------------- KNOWN ISSUE CODEGEN-1295 ------------------------------------------------------------------------------- Summary : MSP430 RTS rint() double routines failing for some inputs Affected Component : Runtime Support Libraries (RTS) Description: MSP430 RTS routines rint() rintl() lrint() lrintl() llrint() llrintl() failing for some inputs with double arguments. Workaround: Avoid using the rint() RTS routines with double arguments and instead use the corresponding rint() float routines. ------------------------------------------------------------------------------- KNOWN ISSUE CODEGEN-1297 ------------------------------------------------------------------------------- Summary : Incorrectly issues ULP 8.1 diagnostic Affected Component : C/C++ Compiler (cl) Description: The compiler throws an invalid ULP 8.1 diagnostic in the case below: % type try1.c void test2(char buffer[5]) { buffer[0] = 'A'; } void test(void) { char buf[5] = { 0 } ; test2(buf); } % cl430 --advice:power try1.c "try1.c", line 8: remark: (ULP 8.1) variable ""buf"" is used as a constant. Recommend declaring variable as either 'static const' or 'const'" ------------------------------------------------------------------------------- KNOWN ISSUE CODEGEN-1476 ------------------------------------------------------------------------------- Summary : Incorrect value assigned to a forward reference of a symbol defined in terms of the section's PC ($) after jump expansion Affected Component : Assembler Description: In this example, if a JMP instruction is out of range, a BR instruction will be substituted into the code, and the JMP instruction will be modified to the opposite case, to jump over the BR following (28xx is a JNC instruction, and a 2 word offset jumps over the next 2 words, 0080 is a BR instruction, and the word following is the address). So far, so good, however if you look at line 7, you will see that the label3 location indicated is 0x0408, which would be correct if an instruction hadn't been inserted, but is wrong for this case, since label3 has been moved to 0x040c. Workaround: Two workarounds are possible: 1) Use a label to get the value of the PC at a key location instead of "symbol .equ $" 2) Replace the jump that will be expanded with an already expanded form. In the example, the jump could be replaced with: JLO $+6 BR label1" ------------------------------------------------------------------------------- KNOWN ISSUE CODEGEN-1545 ------------------------------------------------------------------------------- Summary : MSP430 ULP Advisor mistakenly says to use type int16_t, when it means uint16_t Affected Component : C/C++ Compiler (cl) Description: >>> type try1.c #include extern int array[]; void fxn(int16_t i) { array[i++] = 20; } >>> cl430 -pden --advice:power try1.c "try1.c", line 7: remark #2553-D: (ULP 14.1) Array index (involving "i") of type "int16_t". Recommend using "int16_t" The advice should recommend using uint16_t. For array index variables, unsigned types are preferred over signed types.