MSP430 C/C++ Code Generation Tools v18.1.8.LTS Release Notes
Table of Contents
- 1 Support Information
- 2 C++ 2014 RTS support
- 3 C++ ABI Compatibility
- 4 New function attribute to specify calling convention and new ROM calling convention
- define __cc_rom attribute((call_conv(“cc_rom”)))
- 5 Improved stack usage with inline functions
- 6 Notable Bug Fixes for IAR Compatibility: __cc_rom calling convention
1 Support Information
1.1 List of Resolved and Known Defects
Resolved defects
ID | Summary |
---|---|
CODEGEN-7146 | Compiler loses conversion to size_t in length argument to memcpy |
CODEGEN-7141 | Simple division expression optimized into incorrect complicated expression |
CODEGEN-7098 | Incorrect optimization of expression that mixes the types long and short |
CODEGEN-7011 | Compiler intermittently fails with INTERNAL ERROR: opt2000 experienced a segmentation fault |
CODEGEN-6914 | Enum type with no enumerators fails to emit DW_AT_byte_size, crashes CCS |
CODEGEN-6783 | Ensure C std headers do not issue MISRA warnings |
CODEGEN-6757 | Use of C++ lambda causes Dwarf debug information to be incorrect, and prevents debugging the code |
Open defects
ID | Summary |
---|---|
CODEGEN-6509 | Compiler error: no instance of function template matches the argument list |
CODEGEN-6070 | Erroneous “redeclared with incompatible type” involving two tagless structs with same form |
CODEGEN-4712 | No MISRA 10.1 and 10.6 diagnostics issued on initializations |
CODEGEN-4329 | Initializing unordered_map with an initializer_list fails with -o2 or higher |
CODEGEN-4323 | 1 ULP rounding error in double addition |
CODEGEN-4318 | libcxx/include/random uses unsigned for unsigned long |
CODEGEN-4305 | Compiler aborts with excessive inlining of C++ functions |
CODEGEN-4304 | C++ feature causes runtime failure on unaligned access on ARM9 |
CODEGEN-4297 | Cannot take the address of std::ctype<char>::table_size |
CODEGEN-4281 | Unexpected type returned by bitset [] operator |
CODEGEN-4276 | std::multimap::clear is not noexcept |
CODEGEN-4275 | std::num_get does not parse floating-point strings correctly |
CODEGEN-4259 | noexcept(typeid(d)) runtime fail on polymorphic class type |
CODEGEN-4258 | deeply nested lambda functions hang the codegen |
CODEGEN-4248 | armcl allows non-default arguments to be specified after default arguments |
CODEGEN-4247 | Internal error when assigning default arguments to a parameter pack |
CODEGEN-4245 | Multiple non-variables may be declared using auto or decltype(auto) |
CODEGEN-4234 | No error generated for lambda-expression in default argument cannot capture any entity. |
CODEGEN-4158 | TI compiler does not emit clang error: constexpr function never produces a constant expression |
CODEGEN-4157 | error with using constexpr for return from end() with empty std::initializer_list |
CODEGEN-4132 | cannot find matching “==” operator definition |
CODEGEN-4124 | Failure to defer access control checks |
CODEGEN-4122 | decltype cannot be used as a destructor name |
CODEGEN-4119 | user-supplied allocator function is not called |
CODEGEN-4099 | Composing operations for valarray may fail to compile |
CODEGEN-4090 | Unimplemented core issue 475: std::uncaught_exception is not true when constructing the thrown object |
CODEGEN-4087 | wostringstream::fill(WCHAR_MAX) incorrectly sets the fill value to ' 'L. |
CODEGEN-4076 | Exception propagating out of noexcept function does not call std::terminate |
CODEGEN-4072 | Unimplemented core issue 1769: Catching a thrown derived class by reference to base clas |
CODEGEN-4071 | <regex> never throws error_ctype |
CODEGEN-4069 | std::linear_congruential_engine doesn't support 8-bit results |
CODEGEN-4044 | libcxx istreambuf_iterator points to end of string instead of character past match |
CODEGEN-4035 | Compiler allows constant subtraction between pointers to different objects |
CODEGEN-4026 | Non-standard partial ordering of variadic template partial specialization |
CODEGEN-4002 | Undefined behavior on lambda capturing constexpr by reference |
CODEGEN-4001 | Unimplemented core issue 588: Unqualified name lookup examines dependent base class |
CODEGEN-4000 | Core 1601: Overload resolution for enum with fixed type |
CODEGEN-3999 | Unimplemented core issue 1374: Conversion sequence ranks qualification before reference binding |
CODEGEN-3998 | Unimplemented core issue 1951: cv-qualified void and scalar types are not literal types |
CODEGEN-3993 | Constant initialiation may take place before dynamic initialization |
CODEGEN-3966 | slice_array assignment failures |
CODEGEN-3965 | Invalid conversion on static_cast from T1 to rvalue reference of T2 |
CODEGEN-3964 | Unimplemented core issue 1467: Overloads and initializations with single-element initializer_list |
CODEGEN-3963 | Unimplemented core issue 591: Name lookup in dependent base class that is also the current instantiation |
CODEGEN-3962 | Core Issue 1804 unimplemented: friend declaration does not apply to class template specializations |
CODEGEN-3961 | Pack expansion in template parameter list fails |
CODEGEN-3951 | Spurious error on bypassing initialization of trivially constructible objects |
CODEGEN-3948 | Spurious syntax error on alignas in alias declaration |
CODEGEN-3947 | Spurious error on unevaluated use of undefined constexpr function |
CODEGEN-3946 | Spurious error on global qualifier of struct template |
CODEGEN-1476 | Incorrect value assigned to a forward reference of a symbol defined in terms of the section's PC ($) after jump expansion |
CODEGEN-1295 | MSP430 RTS rint() double routines failing for some inputs |
CODEGEN-1138 | Print a more friendly message when using a lnk.cmd with too large memory |
CODEGEN-793 | Ill advised enum scalar usage gets MISRA diagnostic, but similar usage of enum array does not |
CODEGEN-792 | Array that is correctly initialized erroneously gets a MISRA diagnostic about size not being specified |
CODEGEN-733 | msp C++ cpp compiled with printf_support=minimal causes cout to output incorrect results |
CODEGEN-633 | Floating point addition rounding error |
CODEGEN-582 | MSP430 RTS float arithmetic functions do not round correctly |
CODEGEN-580 | C2000 RTS float arithmetic functions do not round correctly |
CODEGEN-501 | Compiler emits bogus DW_OP_reg16 for split argument |
CODEGEN-322 | Structure is not initialized correctly when using -o2 or -o3 optimization |
CODEGEN-274 | Relocation overflows for BIT instruction using 20-bit pointer |
CODEGEN-270 | Should forbid non-const objects larger than 64k in large model if –near_data=globals |
CODEGEN-104 | Linker gives misleading warning when dot expressions used in SECTION directive for .stack section |
CODEGEN-63 | DWARF does not correctly represent variables stored in register pairs |
CODEGEN-62 | pow(2,x) has fairly significant rounding error |
CODEGEN-60 | printf gives wrong value for pointer when its value is incremented |
CODEGEN-56 | Forward reference in .space generates an internal error |
CODEGEN-30 | Compilers on PC will not work without TMP set |
1.2 Compiler Wiki
A Wiki has been established to assist developers in using TI Embedded Processor Software and Tools. Developers are encouraged to read and contribute to the articles. Registered users can update missing or incorrect information. There is a large section of compiler-related material. Please visit:
https://processors.wiki.ti.com/index.php?title=Category:Compiler
1.3 Compiler Documentation
The “TI MSP430 Optimizing Compiler User’s Guide” and the “TI MSP430 Assembly Language User’s Guide” can be downloaded from:
https://www.ti.com/tool/MSP-CGT
1.4 TI E2E Community
Questions concerning TI Code Generation Tools can be posted to the TI E2E Community forums. The Code Composer Studio support forum can be found at:
https://e2e.ti.com/support/tools/ccs/f/81
1.5 Defect Tracking Database
The Code Generation Tools Defect Database can be searched at:
1.6 Long Term Support release
The MSP430 CGT v18.1.0.LTS release is a long term support (LTS) release. This release will be supported for roughly 2 years with periodic bug fix updates.
2 C++ 2014 RTS support
As of v18.1.0.LTS, the compiler uses the C++14 version of the C++ standard. Previously, C++03 was used. See the C++14 Standard ISO/IEC 14882:2014. For a description of unsupported C++ features, see Section 5.2 of the “TI MSP430 Optimizing Compiler User’s Guide”.
The move to C++14 will break ABI compatibility with previous C++ RTS releases. Attempting to link old C++ object code with the new RTS will result in a link-time error. Suppressing this error will likely result in undefined symbols or undefined behavior during execution.
C ABI compatibility will not be affected by this change.
In most cases, recompiling old source code with the new RTS should be safe. However, due to the changes made in the language, some constructs will result in syntax errors. Some common issues include:
- Macro expansion immediately adjacent to string literals may fail due to the inclusion of new string literals and literal suffixes. Ex: u8“def” will fail to compile if ‘u8’ is a macro “def”_x will fail to compile if ’_x’ is a macro
- New keywords: alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert, and thread_local
- The auto keyword has been repurposed and is no longer a valid storage class specifier. Similarly, the register keyword has been deprecated and will be removed in the future.
A full list can be found in Appendix C, section 2 of the C++14 standard.
3 C++ ABI Compatibility
v17.9.0.STS contains the first planned updates in preparation for the support of C++14 (International Standard ISO/IEC 14882:2014(E)). As part of this update, it is necessary to make changes which might cause errors when building C++ projects containing C++ object files compiled with older versions of the compiler.
These errors will usually include linktime errors involving undefined symbols. If you see undefined symbol errors during a link, pass the “–no_demangle” option to the compiler. If the undefined symbol’s name starts with _Z or _ZVT, then it’s possible that there is a C++ object file or library built with an older version of the tools being used. These will need to be compiled with the v18.1.0.LTS tools to work properly.
4 New function attribute to specify calling convention and new ROM calling convention
The call_conv attribute can be used to specify the calling convention for function calls. This is intended for allowing IAR and TI compilers to link against the same ROM image if it was generated using the new cc_rom calling convention.
Currently the implementation only supports linking against ROM images built with IAR’s compiler using their ROM calling convention implementation.
The TI Compiler currently does not support generating cc_rom ROM images.
The new attribute can be applied to functions, function pointers, and function typedefs.
The attribute is applied to a function with GCC attribute syntax, as follows: attribute((call_conv(“cc_rom”))) The attribute accepts “cc_rom” or “cc_norm” (the default calling convention).
Some examples:
define __cc_rom attribute((call_conv(“cc_rom”)))
__cc_rom void rom_func(void) { … } typedef __cc_rom void (rom_func_t)(void);
int main() { rom_func();
rom_func_t fp = (rom_func_t)0x1234; fp();
((void (__cc_rom *)(void))0x2468)();
void (__cc_rom *rom_func_ptr)(void); rom_func_ptr = &rom_func; rom_func_ptr(); }
See the MSP430 Optimizing C/C++ COmpiler User’s Guide or below article for more details: https://processors.wiki.ti.com/index.php/call_conv_attribute
5 Improved stack usage with inline functions
The new compiler improves stack usage by sharing aggregate data originally defined in inline functions. Example:
struct ARGS { int f1,f2,f3,f4,f5; };
static inline void func1() { struct ARGS a = {1, 2, 3, 4, 5}; foo(&a); }
static inline void func2() { struct ARGS b = {1, 2, 3, 4, 5}; foo(&b); }
void func3() { func1(); func2(); }
In previous compilers, if func1 and func2 are inlined, the structs a and b would not share the same stack location. This version of the compiler will now share stack memory for local aggregates defined in inline functions.
6 Notable Bug Fixes for IAR Compatibility: __cc_rom calling convention
6.1 Fixed in v17.3.0.ST
Version 17.3.0.STS fixed an issue where using the __cc_rom calling convention with parameters of pointer type could result in code that passed the pointer in the wrong register. For example:
typedef struct { uint8_t a; uint_8 b; } str_t; extern __cc_rom void func(uint16_t, str_t *); str_t my_str = {0, 0}; func(0, &my_str);
The address of ‘my_str’ would be passed in R14 erroneously, instead of R13.
6.2 Fixed in v17.6.0.STS
The TI MSP430 compiler requires that a function which returns a signed char value in the return register sign extend the return value to 16-bits in that register before returning to the caller. The IAR compiler does not adhere to this requirement. To address this issue, the TI MSP430 compiler will recognize a call to a function that has been annotated with the __cc_rom calling convention attribute and that returns a signed char type return value, and then sign extend the return value from such a function to 16-bits before that value is used elsewhere in the caller function.
For example, consider the following code:
extern attribute((call_conv(“cc_rom))) char my_ext_func(void); char my_glob_char = 0;
bool func() { my_glob_char = my_ext_func(); if (my_glob_char == -1) { return false; }
/* code containing other uses of my_glob_char */ … }
Because the my_ext_func() is declared with the __cc_rom attribute, the compiler knows that its signed char return value in the return register might not be sign extended to 16-bits, so it will sign extend the value in the return register before that value is used in the “if” condition or later in the body of func().
The compiler will behave similarly for indirect calls to __cc_rom functions that have a signed char return value. For example,
extern attribute((call_conv(“cc_rom))) char (*my_ext_func_ptr)(void); char my_glob_char = 0;
bool func() { my_glob_char = (my_ext_func_ptr)(); if (my_glob_char == -1) { return false; }
/* code containing other uses of my_glob_char */ … }
In this case, the value in the return register is again sign extended to 16-bits upon return from the indirectly called __cc_rom function, before the value is used elsewhere in the body of func().