Release History
- V9.50 2023-11-28
- V9.40 2023-05-24
- V9.32 2022-12-13
- V9.30 2022-06-02
- V9.20 2021-11-02
- V9.10 2021-02-19
- V8.50 2020-02-17
- V8.42 2019-12-12
- V8.40 2019-05-24
- V8.32 2018-10-12
- V8.30 2018-06-15
- V8.22 2018-01-22
- V8.20 2017-10-16
- V8.11 2017-04-11
- V8.10 2017-03-10
- V7.80 2016-10-17
- V7.70 2016-06-17
- V7.60 2016-03-31
- V7.50 2015-11-10
- V7.40 2015-02-19
- V7.30 2014-09-24
- V7.20 2014-05-19
- V7.10 2014-02-21
- V6.70 2013-10-29
- V6.60 2013-06-27
- V6.50 2012-11-10
- V6.40 2012-06-05
- V6.30 2011-10-22
- V6.21 2011-07-05
- V6.20 2011-04-29
- V6.10 2010-11-04
- V5.50 2010-04-21
- V5.41 2009-12-14
- V5.40 2009-07-10
- V5.30 2009-01-23
- V5.20 2008-06-24
- V5.11 2007-12-11
- V5.10 2007-06-12
- V4.41A 2006-12-08
- V4.40A 2006-06-03
- V4.31A 2006-02-03
- V4.30A 2005-06-23
- V4.20A 2005-01-10
- V4.11A 2004-06-10
- V4.10B 2004-03-09
- V4.10A 2004-02-21
- V3.40C 2003-12-12
- V3.40B-P1 2004-10-06
- V3.40A 2003-07-03
- V3.30B 2003-03-18
- V3.30A 2003-02-18
- V3.21A 2002-09-27
- V3.20A 2002-06-18
- V3.11A 2001-12-04
- V3.10A 2001-10-02
- V2.10D 2001-06-27
- V2.10A 2001-02-21
- V1.30C 2000-10-14
- V1.30A/B 2000-09-28
- V1.20A 2000-05-28
- V1.10A 2000-01-14
V9.50 2023-11-28
Program corrections-
In EWARM 9.50.4
[EWARM-12298]When compiling the secure part of a CMSE application for Armv8.1-M with MVE, the wrong instructions are used in code sequences that protect non-secure call and non-secure entry from leaking data to the non-secure part of the application.
The problematic instructions are VLLDM and VLSTM (lazy load/store). The instruction that is used tries to load/store thirty-two D registers, but there are only sixteen D registers, and the sequence has not allocated enough room on the stack for thirty-two D registers. Likely symptoms of this problem are:
- A hardware exception, if the core does not accept the instruction.
- A stack overrun, if the core writes 32 double words to the stack. A stack overrun can cause all sorts of problems.
-
In EWARM 9.50.4
[EWARM-11946, TPB-3831]static_cast conversions can erroneously try to use a user-defined conversion function instead of downcasting. This can lead to incorrect code being generated.
For example:
struct V { template <typename T> operator T() { return {42}; } }; struct J : V {}; void f() { auto v = V{}; static_cast<J const&>(v); // Error, tries to use T() for conversion which leads to type mismatch }
-
In EWARM 9.50.2
[EWARM-12104]The address range check function cmse_check_address_range (in arm_cmse.h) does not work as expected when compiling for non-secure mode (without the --cmse option):
- if CMSE_AU_NONSECURE is set in the flag argument, the check does not always fail (it should fail, since CMSE_AU_NONSECURE is only supported with --cmse)
- if CMSE_AU_NONSECURE is not set in the flag argument, the check always fails (it should not fail when the permission bits requested by the flag bits are set)
-
In EWARM 9.50.2
[EWARM-12026] Reading a 64-bit value can result in half of the value being read from the wrong address, when all these are true:- the optimization level is Medium or higher
- the compiler generates code in Arm mode
- the compiler generates code for one of the Arm architectures Armv5E or Armv6
- the alignment of the address that is being read from is known to be greater than 8
If the address operand has an immediate offset greater than 0, two LDR instructions are used instead of LDRD. The problem occurs if the low register in the register pair being loaded is the same as the base address it is loaded from.
Workaround:
In the example below pSrc is initialized to an offset from Buffer, with alignment more than 8. A possible workaround is to add an inline assembler statement that claims to update the address, so that the compiler no longer can conclude the alignment of derived addresses from the alignment of Buffer:long long *pSrc = (long long*) &Buffer[1].offset8; __asm volatile("" : "+r"(pSrc));
-
In EWARM 9.50.2
[EWARM-11981, TPB-3834]On optimization level High, the compiler can generate incorrect code for loops that contain at least two variables with static storage duration, if:
- the variables are changed in the loop
- at least one of these variables copies the value from another of them
- the loop condition contains a disjunction of multiple conditions and one of the conditions contains a test of the assigned variable.
This example triggers the problem:
#include <stdio.h> int a, b, c, d; int main(void) { do { c = b; b |= 3; } while (d || a & 1 || a || c != 3); printf("DONE\n"); }
-
In EWARM 9.50.2
[EWARM-11916] In some situations, the memchr() library function reads an extra character after the specified range.The affected instruction sets are 32-bit Arm and Thumb2. Thumb1 and A64 are not affected.
-
In EWARM 9.50.2
[EWARM-11901] The instruction CLREX, injected by the intrinsic function __iar_builtin_CLREX, is not handled correctly by the instruction scheduling optimization (which reorders instructions on optimization level High). Problems occur when it is moved across an LDREX or STREX instruction. -
[EWARM-11833] When generating code for a 32-bit Arm device with an FPU, a read or write access to a packed struct can result in an internal error if the struct consists only of a single floating-point value.
-
[EWARM-11730, TPB-3828] On optimization level High, the compiler sometimes reverses floating-point conditions incorrectly in the presence of NaN values, so that expressions like x < 5.0f evaluate to true when the value of x is NaN. This can lead to incorrect code.
-
Writing a 64-bit value to an address can result in one half of the value being written to the wrong address, when all these are true:
- the optimization level is High
- the compiler generates Thumb2 code
- the address written to is updated by adding an offset that is not divisible by 4, and
- the update of the address can be optimized so that it is performed by the address operand of a store instruction (post-indexed addressing).
-
[EWARM-11505, TPB-3797] The compiler can exit with an internal error if a member function that compares the this pointer to the address of a variable or to a null-pointer, is called on a temporary object. Note that this issue will not generate incorrect code.
-
[EWARM-11437] An implicit call to memset is generated by the compiler to zero-initialize variables of composite type. When possible, such a call should be avoided. In other case, the call must be made to __aeabi_memset in order to adhere to the AEABI (in particular when compiling with --aeabi).
-
The compiler emits a spurious error Pe265 for some specific usages of enumeration-qualified enumerators.
Example:
struct A { protected: enum E { value }; }; struct B : A { using A::E; }; auto e = B::E::value; // Previously, spurious error 'Error[Pe265]: constant "A::value" is inaccessible', now ok.
-
[EWARM-11189, TPB-3771] If both the --preprocess and --predef_macros=n options are specified, the preprocessed output from the compiler is empty (notice the n parameter for --predef_macros) .
-
An invalid local linkage specification triggers an internal error in the compiler under certain conditions, for example, if a local definition and assignment is followed by an expression which leaves the local scope. For example:
void f() { extern "C" { int id = 4; return 0; } }
-
Compiling an inline assembler statement that uses a segment operator (one of SFB, SFE, SFS, and SIZEOF) with an argument that is a
string literal, results in an internal error instead of an error message.Example: __asm("DC32 SFB(\".bss\")");
- outputs Internal error: [print_problem A01]
- should output: Error[Og006]: Error in inline assembly: "Invalid syntax"
-
New GCC C language extensions
The following GCC C language extensions are now supported by the compiler- Structures with no members: struct Empty {}
- Empty initializer: struct Color color = {};
-
Additional Arm ACLE support
Added support for the following Arm C Language Extensions subsets:- __ARM_FEATURE_CLZ
- __ARM_FEATURE_QBIT
- __ARM_FEATURE_DSP
- __ARM_FEATURE_SAT
- __ARM_FEATURE_SIMD32
V9.40 2023-05-24
Program corrections-
In EWARM 9.40.2
[EWARM-11621, TPB-3808] When using malloc or calloc to request heap memory of a size close to the full representational range of the size_t type, for example, 0xFFFF'FFFF bytes on a 32-bit architecture or 0xFFFF bytes on a 16-bit architecture, the request fails if no such continuous space is available (which is usually the case). However, input values are processed, for example, word-aligned, before the requested heap space is allocated. As a result, an enormously large input value can wrap around and become tiny, so that the request is accepted instead. This behavior is considered a bug.The bug shows only in projects that use the no-free heap implementation, that is, using the option --no_free_heap, and particularly when heap storage is requested (using malloc or calloc) with a size close to the full representational size of a size_t type. (To be precise, any heap storage request larger than the full representational range of a size_t type minus the architecture's maximum alignment size is affected by the bug.)
The program correction is that malloc and calloc now check for integer overflows. If a memory request results in an integer overflow, these functions return a null pointer.
-
In EWARM 9.40.2
[EWARM-11417, TPB-3787, TPB-3807] The compiler can sometimes fail to recognize aliased memory locations when it accesses subranges of the aliased location inside loops.
This can lead to incorrectly discarded read or write operations.
[2023-10-16] -
In EWARM 9.40.2
[EWARM-11396]When compiling for 32-bit Arm, copying an aggregate type (struct or union) with a flexible array member results in an internal error when:
- the alignment of both the source and the destination is at least 4
- the source object is 8 bytes (including padding)
- the destination object is larger than 8 bytes.
-
In EWARM 9.40.2
[EWARM-11372, TPB-3783]On optimization level High, the compiler can generate incorrect code when a non-static local array is written in a loop using array[i], where i is the loop index, and later passed as a parameter to a function declared to keep no state using #pragma function_effects=no_state. Because #pragma function_effects=no_state is only intended for internal use in the compiler runtime library, the functions that this applies to are the memory and string functions from string.h. An example that triggers the problem is shown below. In this example, the changes to upper[i] inside the loop are lost.
#include <ctype.h> #include <string.h> _Bool cmp(const char * str, const char * str2) { char arr[100]; int i; for (i = 0; i < 99; i++) { arr[i] = toupper(str[i]); if (arr[i] == 0) { break; } } arr[i] = 0; return !strcmp(arr, str2); }
-
[EWARM-11216, TPB-3774] Calling std::round(float) when compiling with the option --libc++ leads to infinite recursion.
-
[EWARM-11102] The intrinsic function __enable_irq clears the wrong bits of the system register DAIF (it clears all bits except bit 1, when instead it should clear just bit 7).
See also EWARM-10800, EWARM-11101 -
[EWARM-11101] The intrinsic function __enable_fiq clears the wrong bits of the system register DAIF (it clears all bits except bit 0, when instead it should clear just bit 6).
See also EWARM-10800, EWARM-11102 -
[EWARM-11099, TPB-3764] On optimization level High, the compiler can generate incorrect code when a function changes the fields of a struct, either directly by using a pointer to the struct, or by calling a function that updates the value. The problem is more likely to occur in C++ code if the function inlining optimization is enabled, but it can occur also in other situations.
-
[EWARM-11085, TPB-3763] Instantiating a template function with lambdas of identical signatures can cause the compiler to exit with an internal error.
-
[EWARM-11038, TPB-3758] On optimization level High, the compiler can generate incorrect code for applications that contain volatile objects. Because of an error in the common subexpression elimination optimization, load operations from volatile objects can be erroneously removed or reordered.
-
[EWARM-11005, TPB-3755] For extremely complex data flows on optimization level High, the compiler can generate incorrect code due to incorrect data flow analysis. In the triggering example below, using High optimization favoring speed, the for loop with the pointer pt does not break after pt equal to e+6, resulting in a missing OK message at the end.
#include <stdio.h> enum { a } b; long c, d; int e[7] = {0,0,0,0,0,0,1}; int f, g; int i; int main(void) { typedef struct { struct { struct { char k; } l; } m[4]; char n; } o; static o p; p.m[c].l.k = p.n |= 128; void *pvl = &p; if (((o *)pvl)->n & 128) while (d) ; static int q[6]; for (int j = 0; j < 6; ++j) f = q[j]; int *pt1 = e; for (int *pt = e; pt != e + 6; ++pt) { pt1 = pt; if (*pt) { b = 8; break; } } for (; i < 10; i++) g = i != 0; if(pt1 == e + 5) { printf("OK\n"); } return 0; }
-
[EWARM-10988] When generating code for the Thumb2 instruction set, passing a total of 4096 bytes or more as stack parameters in a function call can result in the wrong value being passed on the stack.
This can happen for stack parameters that are 4 bytes or smaller, if the offset to the parameter value from the SP is 4096 or more. -
In EWARM 9.40.2
[EWARM-10929, TPB-3744]Storing the address of an element of a multi-dimensional array in a variable with the storage attribute __ro_placement can cause a spurious error: "Error[Go023]: Dynamic initialization of __ro_placement variable not allowed".
Example:
__no_init const int A[4][5]; __ro_placement const int * const pA { &A[2][3] }; // Triggers the error
-
When evaluating C++ constexpr functions at compile time, conversion between constants of integer type are not always performed correctly.
Example:
template<typename T> static constexpr int convert<T data> { return static_cast<int>(data); } static_assert(convert<long long>(4294967254ULL) == -42); // fails
-
When performing an aggregate copy assignment to a volatile object, of a trivially copyable class, the compiler can incorrectly emit error message Pe674 instead of the correct error message Pe372, class "X" has no suitable assignment operator.
Example:
struct X { int member; }; void fun() { volatile X b; b = { 1 }; // Error[Pe674]: initial value of reference to const volatile must be an lvalue }
-
[EWARM-10852, TPB-3739] Hexadecimal character constants are not parsed correctly. A hexadecimal constant should be at most two hexadecimal digits long: for example, \x123ABC should produce 0x12 in the first byte. Instead it is parsed as a single byte, 0xBC (the upper bits are masked when the byte is written).
-
Having multiple typedef statements with identical type and name generates a compiler warning. This warning is incorrect, because this has been legal according to the C standard since C11.
typedef float float32_t; typedef float float32_t; // Warning[Pe301]: typedef name has already been declared (with same type)
-
[EWARM-10800] The compiler accepts the intrinsic functions __enable_fiq and __disable_fiq for the Cortex-M family. This is incorrect. FIQ is not supported by Cortex-M hardware.
See also EWARM-11101, EWARM-11102 -
[EWARM-10547, TPB-3703] When the packed attribute is used, the compiler can in some cases emit:
Warning[Pa039]: use of address of unaligned structure member
even if the structure member is of size 1. -
[EWARM-10359] When compiling code containing uses of the MVE intrinsics vcaddq_rot90_m_f32, vcaddq_rot90_m_s32, vcaddq_rot90_m_u32, vcaddq_rot270_m_f32, vcaddq_rot270_m_s32, or vcaddq_rot270_m_u32, the compiler can attempt to use the same register as both the first and the third register; such code is CONSTRAINED_UNPREDICTABLE and generates an internal error.
None
V9.32 2022-12-13
Program corrections-
In EWARM 9.32.2
[EWARM-10990, TPB-3750] On optimization level High, the compiler can generate incorrect code for down-counting loops where the decrement of the loop counter is 1 and the lower limit is 0. The error is only triggered when the compiler generates code for the Arm v8.1M architecture. -
In EWARM 9.32.2
[EWARM-10820, TPB-3736]On optimization level High, the compiler can generate incorrect code when unrolling a loop where the loop variable starts at a positive constant number, and the loop body indexes an array using a constant offset to the loop variable and the index expression is cast to an unsigned type that is smaller than the int type. The effect when the issue is triggered is that the array will be indexed by a value larger the maximum value for the unsigned type. The exact position that will be accessed depends on the start value for the loop variable.
In this triggering example, calling test() will try to set arr[256] to 2. The array arr is declared as volatile to produce a minimal example, and it is not needed to trigger the problem in the general case.
volatile uint8_t arr[16] = {0}; void test(void) { for (int i = 1; i < 1 + 10; i++) { arr[(uint8_t)(i - 1)] = 2; } }
-
[EWARM-10704, TPB-3724] On optimization level High, the compiler can generate incorrect code when a multi-dimensional array inside a nested loop is indexed both by the loop variable in one of the loops, and an element in a local array that in turn is indexed by the loop variable in another loop. The problem only triggers if this exact element access occurs at least twice in the same inner loop. A triggering example is shown below. These triggering conditions are the two accesses to v[i][index[j]]:
#include <stdio.h> #include <stdint.h> uint8_t v[2][2] = {0}; void test(void) { uint8_t i, j; uint8_t index[8] = {0, 1}; uint8_t status = 0xE2; for (i = 0; i < 2; i++) { for (j = 0; j < 8; j++) { if (status & (1 << j)) { v[i][index[j]] = 8; } else { v[i][index[j]] = 9; } } } } int main(void) { test(); printf("%d %d\n", v[0][0], v[1][0]); }
-
[EWARM-10693, TPB-3725] For bitfields, the compiler fails to honor requests for downgraded debug information.
-
[EWARM-10660, TPB-3716, TPB-3722]
The compiler might crash if it encounters a dynamic initialization of a lambda which is sufficiently complex. A lambda is sufficiently complex when, for example, it captures a (sufficiently) non-trivial class by value. A dynamic initialization of a lambda occurs when, for example, it is captured by value by another lambda. For example:
struct b { ~b(); // sufficiently non-trivial class }; void e() { auto d = [arg = b{}] {}; [d] {}; // dynamic initialization of sufficiently complex lambda d }
-
On optimization level High, the compiler can generate incorrect code when variables with static lifetime read or written in functions might call outside the translation unit. The observable effect is that changes to the variable are moved across calls to external functions that can call back to the module via the externally visible functions. In this example, the update of DataCount in the loop in DataInit() is moved to a position after the call to UseData(), even though the call might access DataCount by calling any of the functions accessible outside of the translation unit.
#include <stdbool.h> #include <string.h> #include <stdint.h> #include <stddef.h> static const uint32_t Data[] = {1u, 2u, 3u, 4u, 5u, 20u, 6u, 0u /* Terminator */}; static size_t DataCount = 0u; // will be updated within DataInit extern void SomeExternalFunction(void); extern bool UseData(void); static bool DataIsValid(size_t Index) { if (Data[Index] != 0u) { return true; } else { return false; } } bool DataInit(void) { // Count Data for (DataCount = 0u; DataIsValid(DataCount); DataCount++) { // Scan Data } return UseData(); // UseData() is an external function that is allowed to access Data by using } static const uint32_t *GetDataPointer(size_t Index) { if (Index > DataCount) { Index = DataCount - 1u; // use last Value } return &Data[Index]; } static size_t GetDataIndex(void) { return 5; // this index should resolve to 20u in the defined array } static uint32_t GetData(uint32_t ua) { uint32_t DataIndex = GetDataIndex(); const uint32_t *p_Data = GetDataPointer(DataIndex); SomeExternalFunction(); // Nothing to do with the data, but required to trigger the bug! return *p_Data; } bool CheckData(uint32_t uAddress) { // The general purpose of this module is to Access Data at some Address. // This Demo instead ignores the address and instead uses a fixed entry within the Data Array. uint32_t Value = GetData(uAddress); if (Value > 10u) { return true; // this is expexted to happen } else { return false; // this actually happens } } int main() { DataInit(); }
-
[EWARM-10488, TPB-3697] The compiler unnecessarily enforces the C++20 rules for designated initializers in C++, that is, not accepting array initializers, chained initializers, and field initializers that are not in field order.
-
The compiler can terminate with an internal error ("Access violation") in cases involving assignment of a compound literal to a class containing a multi-dimensional character array, where the initializer for the array is a string literal.
Example:
struct R { char para2[32][5]; }; struct S { R r; }; struct T { T(); S s; }; T::T() { s = {{{""}}}; }
-
On optimization level High, the compiler can generate incorrect code when fields in static structs are read or written in functions that are visible outside the module. The observable effect is that changes to the field are moved across calls to external functions that can call back to the module via the externally visible functions. In this example, the update value.a = 42 is moved to a position after the call to call_external() even though call_external() might access value.a by calling read_value() .
#include <stdint.h> #include <stdio.h> static struct { int a; int b; } value; int predicate(int x); void call_external(void); int read_value(void) { return value.a; } void do_stuff(void) { if(predicate(value.a)) { value.a = 42; call_external(); } else { value.a = 43; } }
-
On optimization level High, the compiler can generate incorrect code for expressions inside loops where the expression is a sum of two linear expressions in the loop variable. In this example, the compiler will miscompile the expression (scale - y) * O1 + y * O2 as it is the sum of (scale-y)*O1 and y*O2.
for (int32_t y = 0; y < scale; y++) { const int32_t T0 = ((scale - y) * O1 + y * O2) / scale_square; O[j] = T0; j += O_cols; }
-
[EWARM-10308] The compiler does not guarantee correct alignment of the stack pointer when a non-secure state is entered (via a function pointer). If the stack pointer is not correctly aligned, an alignment fault might occur.
-
[EWARM-10303, TPB-3673] In rare cases, where access to data is via a pointer and the pointer variable is updated, the compiler might generate code that does not write to, or read from, the pointed to values correctly.
-
[EWARM-10285, TPB-3671] Some pragma directives, for example #pragma call_graph_root, can only be used on a definition. Trying to use one of these pragma directives in another situation results in an internal error instead of the desired diagnostic.
-
[EWARM-10257] The double precision versions of isnan() and isinf() for 32-bit Arm, only check the upper 32 bits of the floating point to deduce whether it is NaN or Inf.
-
[EWARM-10219, TPB-3662, TPB-3666] In some C++ cases involving multi-file compilation, templates, and in-class field initializers, the compiler can terminate with an internal error:
assertion failed at: "trans_copy.c", line 1403 in prepare_for_trans_unit_copy.
-
[EWARM-8778, TPB-3522] Constant-evaluation of some constexpr aggregate copy operations can result in error Pe028 ("expression must have a constant value").
Example:
struct X { constexpr X(int i) : i(i) { } constexpr X(X const &x) : i(x.i) { } int i; }; struct A { X m[1]; }; constexpr X x{1}; constexpr A a1{x}; constexpr A a2 = a1; // an error is issued for the copy assignment
None
V9.30 2022-06-02
Program corrections-
[EWARM-10021, TPB-3652] On optimization level High and above, the analysis in the compiler can fail to infer all accesses to fields in struct variables. This can make the compiler erroneously generate an internal error.
-
[EWARM-10009, TPB-3650] The compiler can generate incorrect exception tables in some switch statements. This can result in crashes or worse if the switch statement is exited via an exception. The problem only occurs when there are destructors to be run for some objects local to blocks in the switch statement.
-
[EWARM-9994, TPB-3646] The compiler can enter an infinite loop for code that uses a character pointer to write to an un-initialized boolean variable.
-
On optimization levels Medium and High, the compiler can generate incorrect code when a function declared __weak accesses module-local variables with static storage duration. The error is not confined to the weak function, and can trigger in any function that accesses one or more of the module-local variables that are accessed by the weak function. A triggering example is shown below.
static int a = 0; int b = 0; extern int c, d, e; extern void g(void); __weak int h(void) { return a; } void f(void) { a = c / e; b = d * a; g(); }
-
[EWARM-9980, TPB-3648] On optimization levels Medium and High, the compiler can generate incorrect code for arrays that are accessed with different element sizes in the same function (typically char and another scalar type). For an array, for example int test[NUM], the compiler can fail to identify that test and (char*)test refer to the same array, and treat them as two separate entities when optimizing, changing the order of loads and stores of one of them without regard to the other one.
-
On optimization level High, the compiler can generate incorrect code for functions that contain nested loops or if statements, where a single field in a struct pointed to by a pointer is updated several times, and where one of the branches in the nested statements changes the value of the pointer. A triggering example is shown below. In this example, the compiler will erroneously insert a read of msg->error after the assignment msg=0.
typedef struct message_s { uint32_t error; uint32_t id; void * handle; } message_t; message_t *notify(void * handle, message_t * msg) { if (msg->handle == handle) { if (msg->id == 36) { msg->error = 0; } else if (!f(msg)) { msg->error = 12; } else { msg = 0; } } else { msg->error = 22; } return msg; }
-
[EWARM-9974, TPB-3638] The compiler generates incorrect Dwarf .debug_aranges sections. There should be internal padding to ensure that the tuples are aligned correctly, but there isn't.
.debug_aranges sections can be used by debuggers to accelerate lookup in some cases. The IAR C-SPY Debugger is not affected by this problem.
-
[EWARM-9869, TPB-3631] On optimization levels Medium and High, the compiler can generate incorrect initialization of C++ variables with static storage duration declared as inline. The problem can occur when the constructor contains only simple assignments and is placed in one individual module.
-
In a template class with an integer template parameter, referring to the class itself using an enumeration constant that is the same as the template parameter can fail.
For example:template<int ABC> struct A { enum { DEF = ABC }; template<int BAR> static void foo() {} static void FFF() { using C = A<DEF>; C::foo<0>(); // Error here } };
-
[EWARM-9784, TPB-3619] On optimization level High, when enabling exceptions, the compiler can generate incorrect code due to an error in the static-to-auto conversion optimization.
This code can trigger the issue:
// Let problematic_variable be a static variable. // Let c1, c2, c3 and c4 are bool. void problematic_function() { if (c1) { switch (problematic_variable) { case 0: problematic_variable = 0; break; case 1: if (c2) { problematic_variable = 1; } else if (c3) { if (c4) { // exeptions wil be handled by jump-on-exception function_call(); } else { problematic_variable = 2; } } else { problematic_variable = 3; } break; } } return; }
Static-to-auto conversion can place the frequently used static variable problematic_variable into a temporary variable temp for a limited period of time. A version of the code during the optimization process could be:
void problematic_function() { temp = problematic_variable; // added by static to auto convention if (c1) { switch (temp) { case 0: temp = 0; // added by static to auto convention break; case 1: if (c2) { temp = 1; // added by static to auto convention } else if (c3) { if (c4) { problematic_variable = temp; // added by static to auto convention // exeptions wil be handled by jump-on-exception function_call(); } else { temp = 2; // added by static to auto convention } } else { temp = 3; // added by static to auto convention } break; } } temp = problematic_variable; // added by static to auto convention problematic_variable = temp; // added by static to auto convention return; }
Due to the two instructions added at the end, most of the code in the switch statement is wrongly optimized away.
-
[EWARM-9780] When compiling C++ code for Cortex-M0 and including the <atomic> header, the compiler issues the message "Error[Pe020]: identifier is undefined" 44 times, instead of simply reporting that C++ atomic is not supported for Cortex-M0.
-
On optimization level High, the compiler can generate incorrect code due to an error in the static-to-auto conversion optimization. The problem can trigger for loops iterating over an array where the current array element is assigned multiple times during one iteration, as in the example below. The effect of the error, is that the memory location immediately after the array is read and possibly modified.
static _Bool x[2] = { 1, 0 }; void f(void) { static int y[2]; for(unsigned int i = 0u; i < 2u; i++) { switch(y[i]) { case 1: if(!x[i]) { y[i] = 2; } break; case 2: if(!x[i]) { y[i] = 1; } break; default: y[i] = 0; break; } } }
-
[EWARM-9718, TPB-3609] An if statement that has a floating-point compare with a floating-point constant that is subnormal or very close to subnormal (one or two epsilons above), produces incorrect code.
-
[EWARM-9709] The source file memset_s.c incorrectly refers to memcpy_s in an error message.
-
On optimization level High, the compiler can generate incorrect code for loops with multiple exits that read from the same array, indexed both by the loop counter and the loop counter plus one.
uint32_t test_func(uint32_t i) { uint32_t k; for (k = i + 1; k < (TEST_BUFF_LEN - 1); k = k + 1) { if (test_var_buff[k] == test_var_buff[k+1]) { return 2; } } return 3; }
-
The compiler can terminate with an internal error when processing the declaration of a multi-dimensional array of a forward-declared enum type that is later defined.
Example:enum E; extern enum E arr[3][2]; enum E { a, b };
-
[EWARM-9251, TPB-3583] The compiler cannot leverage constant values in auto variable struct members. This causes missed optimization opportunities for inlining and loop unrolling.
-
[EWARM-9066] In AArch64 mode, for functions declared _task or noreturn, the compiler incorrectly preserves callee-saved registers (X19-X29 and (D8-D15), and in the case of _noreturn, also the link register (LR/X30).
-
[EWARM-7413] In threaded applications, the linker option --manual_dynamic_initialization now also suppresses automatic initialization of the main thread's thread local variables, to avoid unnecessary dependence on the table driven initialization for applications that want entirely manual initialization.
-
New supported architectures
- The support for Armv8-M has been extended with instructions and intrinsic functions for CDE (Custom Datapath Extension).
- The support for Armv8-A has been extended to cover up to revision 4 (Armv8.4-A). This also enables support for Armv8-R AArch64 (needed for Cortex-R82 support)
- The support for Cortex-R82 also includes a variant without FPU, Cortex-R82.no_fp.
-
Diagnostic message Ta023 has now been promoted to a soft error: Error[Ta023]: Call to a non __ramfunc function from within a __ramfunc
The main use for __ramfunc is together with a flash driver (or similar), where you need to make sure that no code in flash is called by the driver. For other purposes it is fairly easy to place a function in RAM, using, for example, a named section. If you still want to use __ramfunc for other purposes, you can use --diag_supress to eliminate the error. (This was also needed before, to eliminate the warning.)
-
Libraries and library selection has changed
- With the introduction of the new Libc++ library which supports C++17, the C++ library has been split into three parts. For more information, see the section Prebuilt runtime libraries in the IAR C/C++ Development Guide.
- The support for Cortex-R82 and Cortex-R82.no_fp (currently the only supported 64-bit Arm configuration without an FPU) means that v has been added to many library names, to indicate FPU support. When linking for Cortex-R82.no_fp, libraries without v in the name are selected. (This is consistent with how libraries with/without FPU support are named for 32-bit Arm).
- In C++17, some functionality that was deprecated in C++14 is now removed. You can define the preprocessor symbol _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES to enable support for these features when using the Libc++ library.
- The composition and naming conventions of some prebuilt library files for C++ library functions have changed.
-
The compiler now defines the preprocessor symbols __STDC_IEC_559__ and __STDC_IEC_559_COMPLEX__, in compliance with the IEC 60559 floating-point standard in the C standard. They were mistakenly not defined in earlier versions of the compiler.
Additional GNU C language extensions
- The GCC typeof operator is now supported. Example: typeof(expr) var;
- The GCC C extension "Cast to Union Type" is now supported. Example: z = (union foo) x;
These compiler options have been added:
- --libc++
Makes the compiler and linker use the Libc++ library. - --no_normalize_file_macros
Disables normalization of paths in the symbols __FILE__ and __BASE_FILE__. - --warn_about_incomplete_constructors
Makes the compiler warn about constructors that do not initialize all members. - --warn_about_missing_field_initializers
Makes the compiler warn about fields without explicit initializers.
- --libc++
These predefined preprocessor symbols have been added:
- __LIBCPP
Defined when the Libc++ library is used. - _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
Adds support for deprecated C++17 features. - #include_next
Searches for a file only in the directories on the search path that follow the directory in which the current source file is found.
- __LIBCPP
#pragma once has been added. It prevents a header file from being processed more than once.
The GCC-style attribute transparent_union is no longer supported.
New warning Pa205 "implicit conversion from float to double" for systems with a single-precision only FPU. The warning is an alert that a double-precision library implementation will be used for the operation.
C++ designated initializers and incomplete constructors now complies to the C++20 standard. See the documentation on the compiler options --warn_about_missing_field_initializers and --warn_about_incomplete_constructors for more information.
V9.20 2021-11-02
Program corrections-
In EWARM 9.20.3-FS
In EWARM 9.20.4
[EWARM-9088, TPB-3547] When inlining functions, the compiler can fail to see that variables from different inlined functions are not alive at the same time. This causes the resulting program to use more stack space than the same program compiled without inlining. Usually, the difference is only a few bytes, but when several inlined functions contain large arrays, the increase can be substantial.Work around:
Disable inlining. Inlining can be disabled for an entire file by using the command line option --no_inline. To prevent specific functions from being inlined, use #pragma inline=never. To prevent inlining into specific functions, use #pragma optimize=no_inline. -
In EWARM 9.20.3-FS
In EWARM 9.20.4
[EWARM-9492, TPB-3578] The compiler can terminate with an internal error in cases that involve a const static inline member variable with a non-constant in-class initializer.
Example:struct X { static const char a[]; const static inline char d = a[0]; }; int main() { return X::d; }
-
In EWARM 9.20.3-FS
In EWARM 9.20.4
[EWARM-9459] Some of the source files from Dinkumware which are used to build the C/C++ library are not in the library source distribution. The distribution contains the files needed to rebuild the C/C++ template library project, but does not include various floating-point related library functions. -
In EWARM 9.20.3-FS
In EWARM 9.20.4
[EWARM-9066] In AArch64 mode, for functions declared _task or noreturn, the compiler incorrectly preserves callee-saved registers (X19-X29 and (D8-D15), and in the case of _noreturn, also the link register (LR/X30). -
In EWARM 9.20.2
Work around:
[EWARM-9484] The compiler can generate incorrect code for calls to functions with the
__cmse_nonsecure_call attribute on Arm v8.0-M devices with an FPU, when compiled with the --cmse option. Register R5 is clobbered by the code sequence that immediately follows the return from the function call.
Consider if turning off the hardware workaround is an option, using the option --enable_hardware_workaround no-fix-cmse-cve-2021-35465. As per https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35465, turning off the hardware workaround might be possible if either:- only Non-secure values are stored in the Floating-point or MVE registers (S0-S31, FPSCR, and VPR), or
- the software being developed is solely for use on devices where the erratum has been fixed in hardware.
__cmse_nonsecure_call int (*f)(int a) = 0; #pragma optimize=none int wrapper(int a) { return f(a); }
-
[EWARM-9398] When compiling for 64-bit Arm MCUs with a Neon co-processor, the scheduler sometimes reorders the instructions LD1 and ST1 relative to other memory operations on the same memory location.
-
[EWARM-9307, TPB-3568] In the C++ library, the general templated constructor and copy assignment operator of std::function accept basically any object, but according to C++ Library issue 2132, these functions should be excluded from consideration if the object is not callable. This can cause unwanted ambiguity when std::function objects are involved in overloading.
-
The size of a function with the __exception attribute is limited to 128 bytes. This limitation is unreasonable, because the code needed to save and restore registers in the presence of a function call is more than 128 bytes.
A warning is issued for an exception function with a size greater than 128 bytes, for example:
Warning[Ta161]: Exception function "Synchronous_Handler_A64" has size 292 bytes. Maximum size of a vector is 128 bytes
See also EWARM-8868 -
[EWARM-9305] The compiler can generate incorrect code for interrupt handlers that use Advanced SIMD/NEON instructions performing saturating arithmetic. In particular, the QC bit in the FPSR register is not guaranteed to be preserved across interrupts.
See also EWARM-8868 -
The compiler can generate incorrect code if a binary operator is applied to a scalar and a vector operand, in such a way that an implicit scalar-to-vector conversion occurs.
Example:
See also EWARM-9082, EWARM-9303uint32x2_t f(uint32x2_t v) { return v + 1; }
-
In C++, some uses of constexpr variables of structure type can result in an internal error ([PaType - MemoryAttribute]: no memory attribute set). For example:
struct CC { int base; }; constexpr CC D{ 0x1 }; CC fun() { return D; }
-
The intrinsic functions _get_SB and _set_SB for 32-bit Arm are documented, but they are not implemented. If they are used, the compiler issues a warning:
Warning[Pe223]: function "__get_SB" declared implicitly
If the compiler warning is ignored, the linker will issue an error:
Error[Li005]: no definition for "__get_SB"
-
[EWARM-9217, TPB-3559] On optimization level Medium and above, the compiler can generate different code for the same source on different invocations for code containing variables with static storage duration and nested control structures. The code is expected to be correct in all cases.
-
When compiling for 64-bit Arm at High optimization level, an internal error (Access violation) is issued when the compiler fails to combine writes of zero to multiple consecutive addresses, due to an immediate offset being too large for the instruction used.
This happens with higher probability:- with the option --no_unaligned_access (which limits the available immediate offsets)
- without the option --no_clustering (static clustering leads to larger offsets).
-
[EWARM-9178, TPB-3557] On optimization level High, the compiler can generate incorrect code when common subexpression elimination is turned off.
-
On optimization level High, the compiler can generate incorrect code when the same test is performed multiple times and the tested expression contains constants that can be simplified by simple algebraic rules. A triggering example is shown below. If this flaw is present, the compiler will erroneously deduce that the second test of 7-x != 4 is always true and the generated code will print exit 2 when x is 3.
void f(int x) { if (7 - x != 4) { printf("exit 1\n"); return; } if (7 - x != 4) { printf("exit 2\n"); return; } printf("exit 3\n"); return; }
-
When smart stack protection (--stack-protection) is enabled, the compiler will sometimes allocate separate stack locations for variables that can share locations. A triggering example is shown below. In this example, the analysis will incorrectly infer that the variables j1 and j2 are alive at the same time and cannot share the same location on the stack. Although the usage of the stack locations is not optimal, the generated code is still correct.
int ff(int *); int f(int i) { switch (i) { case 1: { int j1; i = ff(&j1); i += j1; break; } case 2: { int j2; i = ff(&j2); i += j2; break; } } return i; }
-
[EWARM-9105, TPB-3548] The compiler can generate incorrect code for functions with a stack parameter when the top-most loop has more than one entry point, for instance if the top-most loop is a DO loop and starts with an IF statement.
-
In some C++ cases involving defaulted member functions with exception support disabled, the compiler can emit spurious errors and warnings about incompatible exception specifications.
For example:class Other final { public: ~Other() {} }; class Base { public: virtual ~Base() = default; }; template <typename T> class Derived : public Base { public: // ***** Spurious error Pe766 here ~Derived() override = default; private: Other other; }; // ***** Spurious warning Pe768 here class Derived2 : public Derived<int> {};
-
[EWARM-9082] For 64-bit Arm, the 128-bit NEON vector types should be 16-bytes aligned, but this is not enforced. In some cases, this can lead to a linker error, in other cases to a hardware exception in runtime.
See also EWARM-9302, EWARM-9303 -
On optimization level High, the compiler can generate incorrect code when the destination of a pointer can be written both explicitly and by calls to memcpy or memmove. One triggering example is shown below.
void f(char *p, signed long v, char m) { char tmp[2] = { 4, 2 }; char r; switch (m) { case 1: { *p = ((char)(v)); } break; case 2: { *p = ((char)((v * 255) / 100)); r = ((char)((v * 255) % 100)); if ((r >= 50) && ((*p) < 255)) { (*p)++; } } break; case 3: { *p = ((char)(v)); } break; case 4: { memcpy(p, &tmp[0], 2); } break; case 5: { memcpy(p, &tmp[0], 2); } break; } }
-
[EWARM-8986, TPB-3539] The compiler produces a stack overflow error for source code that contains an expression that encompasses over 32,000 nested ?-: expressions.
-
[EWARM-8984, TPB-3537] In compiler platform 10.8, the --no_cse command line option disables common sub-expression elimination also for compiler-generated constants. This, in combination with the Embedded Workbench IDE adding --no_cse to the compiler command line also for optimization levels None and Low, can lead to larger and slower code than for earlier compiler platforms.
-
[EWARM-8965, TPB-3534] In C mode, a structure field can hide a typedef with the same name. For example:
typedef struct refPic { struct refPic *refPic; } refPic; typedef struct { refPic refPic[20]; refPic refPicList[20]; } picBuffer;
The declaration of the refPicList field is incorrectly rejected.
-
[EWARM-8893] When using 32-bit pointers (in 32-bit mode, and in 64-bit mode with ILP32), an internal error is issued when attempting to report "Error[Ta162]: Located address is too high" because of a variable located outside the 32-bit address space.
-
[EWARM-8868] The compiler can generate incorrect code for interrupt handlers that perform floating point/advanced SIMD operations and/or call one or more functions. The upper 8 bytes of the 16 byte SIMD registers will not be preserved across interrupts.
See also EWARM-8862, EWARM-9305, EWARM-9306 -
[EWARM-8862] The compiler can generate incorrect code for nested interrupt handlers. Register X16 is clobbered by the function entrance sequence for the interrupt handler.
See also EWARM-8868, EWARM-9304 -
[EWARM-8860] Object attributes set by the compiler make the linker issue "Warning[Lt010]: Inconsistent enum container size". This happens also when the underlying type of the enum is fixed (C++11), which is incorrect, because an enum with a fixed size does not contribute to inconsistencies regarding enum size.
-
Using alignas to set the alignment of a static data member with an in-class initializer results in a spurious error Pe1887 ("alignment attribute must also appear on definition").
Example:struct X { alignas(8) static constexpr short sh[2]{42, 17}; };
-
When compiling for Thumb2 instructions set at optimization level High, the instruction scheduler can move instructions across an IT block, even if the IT block contains an instruction with side effects.
In the following example, the if statement could be flattened to an IT block, and the assignment could be scheduled before the if statement:
if (((64 - 1u) < (levelState - 1u))) { __set_BASEPRI(64); } State->Level = levelState;
Instructions with side-effects that can be affected by this bug are generated from these intrinsic functions:
__set_BASEPRI
__set_PRIMASK
__set_CONTROL
__set_FAULTMASK
__set_BASEPRI
__set_interrupt_state
__set_MSP
__set_PSP
__set_FPSCR
__MCR
__MCR2
__TT
__TTT
__TTA
__TTAT
__arm_wsr
__arm_wsrp -
In C++ mode, compilation sometimes fails for constexpr objects with internal self-referencing.
Example:struct S { int i; constexpr S(): i{} {} }; struct X { constexpr X(): p(&u.i) {} // Note: p references inside u S u; int *p; }; struct Y: X { constexpr Y() {} }; constexpr Y y; // Error[Pe2807]: initialization is not constant
-
The warning Go029 can trigger erroneously for the first assignment to a field in a bitfield struct.
struct A { int x : 8; int y : 8; }; struct A f(int x, int y) { struct A id; id.x = x; // Triggers Go029 erroneously id.y = y; return id; }
-
In C++, the compiler can emit a spurious warning Pe940 ("missing return statement at end of non-void function") in a template context, if the immediately preceding statement is an if constexpr where the condition is false (that is, the else part is active), and the end of the else part is unreachable (for example, if the else part ends with a return statement).
Example:
template<int n> class Class { public: static long test(long x) { if constexpr(n < 0) { return 0; } else { return 1; } } // Warning[Pe940]: missing return statement at end of non-void function };
Additional GNU C language extensions
pure
andconst
function attributes- GNU style statement expressions
- GNU style case ranges
- GNU style designated initializer ranges
- Binary literals with a
0b
prefix
V9.10 2021-02-19
Program corrections-
In EWARM 9.10.2
[EWARM-8687, TPB-3510]On optimization level Medium and higher, the compiler can generate incorrect code when the value of a de-referenced pointer is used in the condition part of an if statement, the same value is changed in the if statement, and both branches of the if contain a return statement.
The observable effect is that the erroneous code chooses the return value based on the updated value of the de-referenced pointer instead of the original value. The error can trigger for both examples below, as the compiler sees return 0 in the first example as part of the else branch of the if statement.
int test_and_clearA(uint16_t mask, uint16_t *flags) { if ((*flags & mask) != 0) { *flags &= ~mask; return 1; } return 0; } int test_and_clearB(uint16_t mask, uint16_t *flags) { if ((*flags & mask) != 0) { *flags &= ~mask; return 1; } else { return 0; } }
-
In EWARM 9.10.2
[EWARM-8670]When compiling for Armv4 (ARM7TDMI, ARM9TDMI) an interrupt service routine (ISR) with the __irq keyword will return from interrupt to an address four bytes before the interrupted instruction, if:
- the ISR contains a function call that is not inlined, or
- for some other reason the link register LR is saved to the stack.
-
In EWARM 9.10.2
[EWARM-8654]Range checking for the opcode parameter is incorrect for these intrinsic functions:
- _MCR, MCR2, MRC, _MRC2: 0 to 8 is accepted, 0 to 7 is valid. Specifying 8 will result in an internal compiler error.
- _MCRR, MCRR2, MRRC, _MRRC2: 0 to 8 is accepted, 0 to 15 is valid. Specifying 9 to 15 will result in a range error.
- _arm_rsr64 and _arm_wsr64: 0 to 7 is accepted, 0 to 15 is valid. Specifying 8 to 15 will result in a range error.
-
In EWARM 9.10.2
[EWARM-8639, TPB-3507] On optimization level High, the compiler can generate incorrect code when a function that contains calls to functions declared as noreturn or C++ functions not declared as noexcept is inlined, and both the inlined function and the function it is inlined in modify the same variable. -
In EWARM 9.10.2
[EWARM-8595] When the common subexpression optimization is explicitly disabled, the compiler can exit with an internal error for code containing shifts where the shift count is a constant expression containing calls to intrinsic functions. Note that the Embedded Workbench IDE explicitly disables common subexpression elimination on optimization levels None and Low. -
In EWARM 9.10.2
[EWARM-8557, TPB-3490] The compiler can appear to hang when processing code that contains an initializer for a flexible array member (a language extension).Example:
struct X { int i; int arr[]; } x = { 1, 2 };
In this case, the variable x will be allocated space for two int values, even though its type (struct X) is only as large as a single int.
-
[EWARM-10949, TPB-3746] On optimization level High, the compiler can generate incorrect code for functions that contain local variables with static storage duration, if they call a small function in the same module that in turn can call a function declared as {{noreturn}}. In the triggering example below, an indeterminate value will be written to the variable {{idx}} at the end of the function.
int *f(int x); void __attribute__((noreturn)) fail(void); static inline void check(_Bool condition) { if (!condition) fail(); } void g(int a, int b) { static int idx = 0U; int* pA = f(idx); check(pA != 0); *pA = a; if (b != 0) ++idx; }
Work around:
Prevent inlining of small functions that contain calls to functions declared as noreturn. Either use the #pragma optimize=no_inline directive, turn off inlining for the entire module, or reduce the optimization level to Medium or lower. -
[EWARM-8549, TPB-3488] Using the GCC packed attribute in such a way that at least one bit field is allocated into more bytes than its type would occupy, causes the compiler to terminate with an internal error (assertion failed at: "layout.c" ...).
Example:struct __attribute__ ((packed)) S { short a : 2; char b : 8; short c : 6; };
Note that the b bit field will be located partly in the first byte and partly in the second, but the type of the bit field (char) is only one byte. Changing the type of the bit field to something that is two bytes will make this work as intended, but this is not possible in all cases.
-
In EWARM 9.10.2
[EWARM-8441, TPB-3484] The compiler can terminate with an internal error when using the option --header_context in some cases involving the use of the #line directive. -
[EWARM-8300, TPB-3471] In C++, a constant expression consisting of an address cast to an enumeration type can in some circumstances cause the compiler to terminate with an internal error ("[PaInitializerEDG - Traverse]: funny address type"). One such circumstance is when such a constant expression is used as the initializer for a variable.
-
[EWARM-8273, TPB-3465] In some cases involving zero-width bit fields, the compiler can terminate with an internal error ("[Front end]: assertion failed at: "layout.c", line NNNN in set_field_size_and_offset").
-
[EWARM-8271] When compiling for a core based on FPU architecture VFPv3 or later, sign-conversions can go wrong if either:
- the conversion is from a signed integer type to an unsigned integer type, and the value converted was previously converted from float, and the float value is a multiplication with a power of two, or
- the conversion is from an unsigned integer type to a signed integer type, and the value converted was previously converted from float, and the float value is a multiplication with a power of two.
Example:
unsigned short f(float *a, int i) { return (int)(a[i] * 8.0f) + 0x8000ul; }
For this example, the return value is saturated to unsigned short, so any negative value becomes zero, and any value larger than 65535 becomes 65535.
-
The compiler can generate incorrect code if strcpy, memcpy, memmove, or any other C library function that returns its first parameter is used for changing the value of a local variable at least twice in the same function. As an example, the function f below will return 1 if b->a1 is 10, regardless of the value of b->a2, because the analysis misses that memcpy(&a, &(b->a2)) changes the value of a.
The problem only occurs when the same local variable (a in the example) is changed multiple times by a C library function that uses the returns 1 function effect pragma.int f(struct B const *b) { int a; memcpy(&a, &(b->a1)); if (a == 10) { memcpy(&a, &(b->a2)); } if (a != 20) { return 1; } return 0; }
-
[EWARM-8145] The file cmain.s incorrectly contains the labels _main and _call_main.They have no documented use and they are not reserved, so they should be available for other use.
-
[EWARM-8009, TPB-3428] If the construction part of a new expression throws, the compiler should arrange for the storage allocated by operator new to be deleted. However, in most cases the compiler incorrectly emits this deletion also for exceptions thrown by other parts of the expression of which the new expression is part.
Example:throw new MyError(x);
In this case, the compiler will emit code to always call operator delete for the memory allocated by operator new, leading to possible accesses to already deleted memory and/or double delete.
-
[EWARM-7997, TPB-3427] Using the --enum_is_int option when compiling a C++ source file that includes the C++ system headers giving input/output facilities might generate faulty code.
-
[EWARM-7949, TPB-3426] Using GNU statement expressions (an experimental feature enabled by extended language support) in C++ causes the compiler to terminate with an internal error assertion failed: push_or_repush_object_lifetime.
-
[EWARM-7813, TPB-3391] Forgetting to put parentheses in a function call should result in warning Pa131, but for some intrinsic functions, like __disable_interrupt, the compiler fails to emit this warning.
-
[EWARM-7810, TPB-3394] The gnu format attribute (_attribute_((format))) is incorrectly marked as not supported. Using it generates spurious warnings.
-
[EWARM-7786, TPB-3374] Under some circumstances, such as when the fields of a structure type are only ever accessed via a global pointer variable that is defined in a separate file from the accesses, debug information about the fields is not emitted.
-
[EWARM-7747, TPB-3369] With an optimization level of medium and higher, the compiler can generate incorrect initialization values for C++ objects with static storage duration that have constructors defined in the same modules. A triggering condition is when the constructor contains an if or switch statement. The bug does not trigger if the constructor is declared as constexpr.
-
[EWARM-7528, TPB-3323] C++ in-class definitions of friend functions in template classes can sometimes be instantiated unnecessarily. This can lead to a variety of errors, including infinite template instantiation recursion and incomplete types being used.
-
[EWARM-7470, TPB-3316] The compiler can terminate with an internal error for some C++ code when checking of MISRA-C: 2004 rule 11.4 is enabled.
-
[EWARM-7442, TPB-3308] The compiler can terminate with an internal error when checking of MISRA-C: rule 5.3 (typedef reuse) is enabled, in the context of multi-file compilation (--mfc).
-
[EWARM-7430, TPB-3304] The clang preprocessor macro __has_attribute(attr) incorrectly expands to 1 for gnu/clang attributes that are not actually supported.
-
[EWARM-7313, TPB-3272] The compiler does not support the _attribute_((packed)) attribute correctly. For cases where this results in a bitfield that spans more bytes than would normally be required for its type, the compiler can terminate with an internal error, or, possibly, generate incorrect code.
Example:struct __attribute__((packed)) { short a : 5; short b : 13; short c : 14; };
The bitfield b is of a type that normally only requires two bytes, but in this case parts of it will reside in three different bytes (3 bits in the first byte, 8 bits in the second, and 2 bits in the third byte). This type of bitfield is not handled correctly.
-
[EWARM-7305, TPB-3270] The C++17 structured binding feature (auto [x, y] = ...) does not work for any type where std::tuple_size is needed. Compilation fails with an error that states that no matching instantiation of std::tuple_size is found. Affected types include instantiations of std::pair, std::tuple, and std::array.
- None.
V8.50 2020-02-17
Program corrections-
In EWARM 8.50.9
[EWARM-8150, TPB-3453] When the C++17 feature constexpr if is used in a C++ constructor or destructor, the compiler can terminate with an internal error:["Front end]: assertion failed at: "...\lower_init.c", line 18985"
-
In EWARM 8.50.9
[EWARM-8118, TPB-3448]The compiler can exit with an internal error when compiling code where a volatile pointer is used to access a field in a non-volatile struct.
struct A { int x; int y; }; volatile int t; volatile int a_x, a_y; int main(void) { struct A a = { 1, 2 }; volatile int *vp = &a.y; t = (*vp); a_x = a.y; a_y = a.y; return 0; }
-
In EWARM 8.50.9
[EWARM-8086, TPB-3442]On optimization level High, the compiler can generate incorrect code when a pointer-type field in a struct is dereferenced, incremented, and then updated using the value of the original dereference as in the example below. The problem can also trigger if this pattern occurs after inlining.
struct A { unsigned char *x; unsigned char *y; }; int g4( struct A *ptr ) { unsigned char len = *ptr->y++; ptr->y = ptr->y + len; return 0; }
-
In EWARM 8.50.9
[EWARM-8085]At medium optimization or higher, an unaligned load of a volatile member can be optimized away as if the access was not volatile. This can happen if the optimization is correct for a non-volatile member, which is the case if the load is preceded by a store of a known value to the same address.
Example:
#pragma pack(1) typedef struct { volatile unsigned int x; } T; void f(T * p) { p->x = 5; while ((p->x & 16) == 0); }
-
In EWARM 8.50.8
[EWARM-8074, TPB-3438] A regression in the compiler causes missed optimization opportunities and can lead to slower code, increased code size, and larger stack usage. -
In EWARM 8.50.9
[EWARM-8025] Reading a two-byte struct to be either passed as a register parameter, or as a return value in register, can lead to reading four bytes. The extra two bytes are not used, but if the location where the struct is loaded from is at a protection boundary, an MPU may generate a fault. -
In EWARM 8.50.9
[EWARM-8011] At high optimization levels, a call to intrinsic functions __MRRC or __MRRC2 will lead to a compiler internal error. -
In EWARM 8.50.8
[EWARM-7937]Summary
The compiler performs an incorrect boundary check in the float division function for T16 and T32 code. Results that are close to Inf (infinite) erroneously become Inf when the exponent of the result is one below Inf. In other words, when the result of a division exceeds |1.701411835e + 038| (bit pattern 0x7F000000 or 0xFF000000), it becomes a signed Inf.Details
The boundary of the exponent of the result is set to 0xFE instead of 0xFF, which makes near Inf results Inf instead. The boundary check values 0xFE and 0xFF depend on which method that is used for calculating and packing the final result. In an earlier change to the float division optimization, the optimizer switched to a method where the most significant bit in the result mantissa is omitted, as a more optimal approach. The calculation of the exponent then also changed because it did not need to be adjusted for a set msb in the result mantissa, but the value in the boundary check for overflowed results (Inf) was not adjusted accordingly. To understand this in detail, inspect the code of the division function for float (T32 in this case):dXn: bit 0 = Guard bit bit 1-7 = The lowest 7 bits of the result mantissa (before rounding) dAux: bit 0-6 = 0 bit 7-22 = bit 7-22 of the result (before rounding) bit 23-30 = 0 bit 31 = Sign of the result dExp: bit 0-7 = The result exponent (before rounding) <XX>: Was 0xFE before the bug fix and 0xFF after. CMP dExp,#<XX> ; Check if it is overflow. BGE OvFlw ; => Generate overflow. ORRS dXn,dAux,dXn,LSR #1 ; Collect the result and set carry flag. ADC dXn,dXn,dExp,LSL #23 ; Round and pack with exponent BX lr Final result in dXn (r0): bit 0-22 = The mantissa (without the implicit msb bit) bit 23-30 = The exponent bit 31 = The sign bit
-
In EWARM 8.50.7
[EWARM-7941, TPB-3420] The compiler can terminate with an internal error ("assertion failed at: "overload.c", line xxxx in function_template_call_argument_deduction") in some cases that involve instantiating a class template without using brackets (a C++17 feature).
Example:template<unsigned MAX = 10> struct XXX { XXX() : mmm(MAX) { } unsigned mmm; }; int main() { XXX xxx; // NOTE: Not using brackets return xxx.mmm; }
-
In EWARM 8.50.7
[EWARM-7882] In Armv8-M a function with the attribute __cmse_nonsecure_entry clears registers before returning, in order to not leak information from secure mode to non-secure mode. If such a function is compiled for FPU and has the return type float, the result register S0 is also cleared, which means the return value does not reach the caller. -
In EWARM 8.50.6
[EWARM-7859, TPB-3399] If #pragma weak is placed before a declaration and there is a definition of the same function/variable later, the compiler incorrectly does not make the definition a weak definition. -
In EWARM 8.50.7
[EWARM-7836, TPB-3395]On optimization level High, the compiler can generate incorrect code when there is an assignment to a dereferenced pointer followed by two or more loops in sequence, where the first loop reads an array or dereferences a pointer of the same type or of type char* and the second loop modifies the assigned pointer. A triggering example is shown below.
In this example, the bug triggers when the Byte type is either char or uint16_t. The observed effect, in this case, is that the assignment *value=0 is not performed.
bool cvt16(const Byte bytes[], int size, uint16_t *value) { bool result = true; *value = 0U; int16_t tCnt = (int16_t)size - sizeof(uint16_t); int16_t a = 0; while (a < tCnt) { if (0U != bytes[a]) { result = false; } a++; } while (a < size) { (*value) <<= 8; (*value) |= bytes[a]; a++; } return result; }
-
In EWARM 8.50.7
[EWARM-7762, TPB-3371] std::unique_ptr<T>, where T is an array type, is missing a default argument for the nullptr_t overload of the reset member function:
reset(nullptr_t = nullptr);
-
In EWARM 8.50.7
[EWARM-7752, TPB-3370] If a preinclude file is specified, the compiler uses its name as the name of the module, instead of using the name of the main source file. This mainly affects code coverage. -
In EWARM 8.50.4
[EWARM-7735, TPB-3365] If the declaration of a function uses the __weak keyword and the definition does not, the function is incorrectly generated as a weak symbol. -
In EWARM 8.50.4
[EWARM-7713, TPB-3363] The compiler can terminate with an internal error ('[Front end]: assertion failed at: "lower_name.c", line 2542 in mangled_encoding_for_function_type') in some cases that involve the use of a lambda function in certain scopes (like the condition scope in an if statement). -
In EWARM 8.50.7
[EWARM-7688, TPB-3358] A floating-point expression that is cast to an integer type N, where one operand is a floating-point constant with a value that is exactly representable as an integer, and the other operand is an integer expression with type T, is evaluated in T, rather than the type N. For example, the expression (uint32_t)((uint16_t)a*32768.0) is evaluated in uint16_t rather than uint32_t, possibly leading to unexpected results. -
In EWARM 8.50.7
[EWARM-7540, TPB-3325] On optimization level High, the compiler can incorrectly move pointer-based loads and stores across the definition of the pointer variable. This problem can occur when a pointer is repeatedly de-referenced inside a loop, and the pointer variable is defined or first set inside the same loop. -
In EWARM 8.50.4
[EWARM-7531, TPB-3324] The compiler can fail to compile some C++ source code that involves constexpr array access with a non-zero index, erroneously emitting error Pe028: "expression must have a constant value", adding "[note]: attempt to access storage one position past an object treated as an array of one element". -
Internal error when compiling a function with attribute __naked that ends with an inline asm statement that contains a literal pool load, if there is another function in the module. For example:
__naked int* f(void) { __asm volatile("LDR R0, =x"); }
-
In EWARM 8.50.7
[EWARM-7440, TPB-3309] On optimization level High, the compiler can generate incorrect code for functions that write to variables with static storage duration and have a loop nesting that is not strictly hierarchical (that is, when two loops intersect and neither is completely inside the other). -
[EWARM-7421, TPB-3295] Compilation can fail if a structure field has the same name as a type.
-
[EWARM-7365, TPB-3306] When compiling for Armv8-M with the --cmse (secure mode) option set, a call to a function with the attribute __cmse_nonsecure_entry will unexpectedly return in non-secure mode.
-
[EWARM-7358, TPB-3279] The compiler can terminate with an internal error ("[Front end]: assertion failed at: "lower_init.c", line 3396 in add_constructor_call") in some cases that involve C++ multiple inheritance.
-
[EWARM-7357, TPB-3278] In some cases, the compiler does not properly take using declarations into consideration for conversion functions and erroneously emits an error.
Example:struct X { operator bool() const; }; struct Y { operator bool() const; }; struct D: X, Y { using X::operator bool; }; bool foo(D d) { return d; // Incorrectly reported as ambiguous }
-
[EWARM-7349, TPB-3277] When remarks are enabled, the compiler can sometimes emit spurious remarks with no source position, for example: "Remark[Pe831]: support for placement delete is disabled".
-
[EWARM-7312, TPB-3271] The compiler can terminate with an internal error when code contains a constant that consists of a __section_begin or __section_end operator with an offset, converted to a function pointer.
Example:#pragma section = "SEC" typedef void (*fun_t)(void); void foo(void) { fun_t fp = (fun_t)((long)__section_begin("SEC") + 1); fp(); }
-
[EWARM-7306] When compiling for baseline profile M devices (Cortex-M0/M0+/M1/M23), a function definition with the attribute __svc that contains a function call which is not inlined, results in an internal error.
-
[EWARM-7270, TPB-3262] Mistakenly, the compiler never does emit warning Pa149 ("some enum values are not handled in this switch statement..."). This warning is for switch statements on an enum type, where there is no default case, all cases are for enum constants of the given type, and some enum constants are not handled.
-
[EWARM-7264, TPB-3261] The compiler can terminate with an internal error ("assertion failed: lower_constant: bad kind") in some cases that involve braced initialization of a multi-level aggregate class like std::array with a dynamic value more than one level down, when exceptions are disabled.
Example:#include <array> struct tValues { int val; }; int fun(); std::array<tValues, 1> arr{{ { fun() } }};
-
[EWARM-6955, TPB-3196] The compiler sometimes fails to update the debug information for variables whose storage location changed by being moved from one processor register into another processor register.
- None.
V8.42 2019-12-12
Program corrections-
The compiler can terminate with an internal error in some cases that involve the initialization of a block-local anonymous union. Example:
int val; void foo(void) { union { int x; char y; } = { val }; };
-
[EWARM-7146, TPB-3243] The C++ library class std::ratio cannot be used in constexpr expressions.
-
[EWARM-7143, TPB-3241] The compiler will terminate with an internal error if a static class constructor is initialized with a constant array element with a known value that has an aggregate type.
-
[EWARM-7085, TPB-3226] In some cases, the compiler generates a call to memset to zero-initialize a variable or part of a variable. Normally, at higher optimization levels, this call is inlined or otherwise optimized. When the target variable is volatile, the call is not inlined or otherwise optimized.
-
[EWARM-7056, TPB-3220] The compiler can terminate with an "out of memory" error in some cases that typically involve many constant address expressions for addresses in large objects.
-
On optimization level High, the compiler can exit with a null pointer exception in some cases. This occurs when compiling code where a pointer is used to loop backward over a buffer, and the start and stop values are expressed as addresses of buffer elements with constant index. See this example:
char b[5]; char *c, *d; int e(void) { c = &b[1]; d = &b[5]; while (d >= c) d--; return 0; }
-
Compiling code that initializes a variable with the address of an array type member variable of an object, can cause an internal error. For example, (C++, but this can happen in similar cases in C as well):
struct A { int x; }; struct B { A a[1][1]; }; B b; A* x = &b.a[0][0];
-
On optimization level High, the compiler can generate incorrect code for loops with a constant trip count and a body that contains bit operations introduced by inlining. See this example:
const uint8_t aVar[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; char gData[32]; inline void g(uint8_t x) { gData[x] = (x & 0x3f); } #pragma inline=never void f(void) { for (int j = 0; j < (32); j++) { g(aVar[j]); } }
-
On optimization level High, the compiler can fail to terminate when function inlining is used together with the loop unrolling optimization, and the inlined function contains a loop and returns the value of a function call. This sample code triggers the problem:
char c[2]; int j(void); int h(int x) { for (int l = 0; l < 2; l++) *c = x; return j(); } int n() { int a = h(4); return a; }
- None.
V8.40 2019-05-24
Program corrections-
In EWARM 8.40.2:
[EWARM-6992, TPB-3198] On optimization level High, the compiler can generate incorrect code for loops where the loop test is inside a switch statement and the loop variable is updated by post-incrementation, as in this example:char buf[10] = {1,2,3,4,5,6,7,8,9,10}; int main(void) { int value = 255; for (int i = 0;;) { switch(buf[i++]) { default: continue; case 10: break; case 1: value = 1; break; case 2: value = 2; break; } break; } printf("%d\n", value); }
-
In EWARM 8.40.2:
[EWARM-6956, TPB-3190] For most C runtime library functions, redeclaring the function inside a C++ namespace after including the relevant system header will display the false error message:Error[Pe337]: linkage specification is incompatible with previous "..."
-
In EWARM 8.40.2:
[EWARM-6940, TPB-3189] The compiler can terminate with an internal error in some cases involving aggregate initialization of a structure containing an array of structures with one or more const data members. -
In EWARM 8.40.2:
[EWARM-6939] It is not possible to use the 2-operand variants of the SUB and SUBS instructions.
See also EWARM-6765 -
In EWARM 8.40.2:
[EWARM-6935, TPB-3188] The compiler can terminate with an internal error in some cases involving aggregate initialization of a class/struct/union with one or more base classes. -
In EWARM 8.40.2:
[EWARM-6924, TPB-3184] When compiling C++ code, the IAR C/C++ Compiler can terminate with an internal error in some cases involving template class in-class data member initializers. -
In EWARM 8.40.2:
[EWARM-6921, TPB-3181] The inline functions for the generic functions isunordered and islessgreater have the wrong return types in C. This triggers MISRA-C:2004 rule 10.1 messages in the compiler and in C-STAT. -
In EWARM 8.40.2:
[EWARM-6912, TPB-3197] In some complicated template cases, the compiler can erroneously emit error Pe871 ("template instantiation resulted in unexpected function type of ... (the meaning of a name may have changed since the template declaration ...") -
In EWARM 8.40.2:
[EWARM-6885, TPB-3178] The configuration setting to make all enumeration types at least the size of n int has no effect. Enumeration types can still get a smaller underlying type if all enumeration constants fit. -
In EWARM 8.40.2:
[EWARM-6878, TPB-3174] On optimization level Medium and above, the compiler can generate incorrect code for modules that contain both weak function definitions and calls to those functions. -
In EWARM 8.40.2:
Example:
[EWARM-6849, TPB-3169] The compiler can terminate with an internal error (Internal error: [Front end]: assertion failed at: "...\lower_il.c") in some cases that involve using the address of a member variable in an aggregate field initializer.
#include
struct XXX { int mI; std::array mA = \{ &mI, 0 }; }; -
In EWARM 8.40.2:
[EWARM-6838, TPB-3159] Code that contains very large functions with extensive use of if statements and variables with static storage duration can take a long time to compile. -
In EWARM 8.40.2:
[EWARM-6819, TPB-3154] The compiler can generate incorrect code for expressions of the type *(&i + f()) = 1; when i is a scalar variable with automatic storage duration. When inlining is enabled, that is, on optimization level High, this problem is triggered also by the example below.static void change(int *x, int val) { x += f(); *x = val; } void params(int i, int j) { change(&i, 1); change(&j, 2); printf("i=%d,j=%d\n", i, j); }
-
In EWARM 8.40.2:
[EWARM-6808] The signature for the function cmse_check_address_range in the header file arm_acle.h has been updated to use void* instead of void const* for the pointer type, as specified by "ARMv8-M Security Extensions: Requirements on Development Tools" (ARM-ECM-0359818). -
In EWARM 8.40.2:
[EWARM-6754, TPB-3115] Using the gnu-style attribute noreturn on a typedef of a function pointer, causes the compiler to terminate with an internal error. Example:typedef void (*foo)() __attribute__((noreturn));
-
In EWARM 8.40.2:
[EWARM-6744] When a non-ramfunc function is inlined into a __ramfunc function, warning Ta023 "Call to a non __ramfunc function from within a __ramfunc function" is issued. This is incorrect; after the call is inlined there is no call, and the inlined code is inside the caller, which is a __ramfunc function. -
[EWARM-6825] The speed-optimized implementation of memcmp for Cortex-M0, M0+, and M23 can trigger a HardFault on the target system when the pointer parameters are not co-aligned modulo 4, in other words when the last two bits of the pointers have different values.
-
[EWARM-6768, TPB-3127] The compiler can exit with an internal error when compiling C++ code that contains initialization expressions with C99-style named designators. Note that named designators are not allowed by the C++ 14 standard.
-
[EWARM-6753] The compiler can exit with an internal error when compiling code with an if statement that contains a call to one of the intrinsic functions __iar_builtin_VRINTA_F64, __iar_builtin_VRINTM_F64, __iar_builtin_VRINTN_F64, __iar_builtin_VRINTP_F64, __iar_builtin_VRINTA_F32, __iar_builtin_VRINTM_F32, __iar_builtin_VRINTN_F32, or __iar_builtin_VRINTP_F32.
float fx(float a, int rm) { if (rm == 1) { a = __VRINTM_F32(a); } return a; }
-
[EWARM-6750] If a C++ template class contains a single float, in some cases the caller and the callee do not agree on whether the return type is a homogeneous aggregate. When compiling with Vector Floating Point (VFP) support, this means that the callee can return a value in one register (S0), and the caller uses the value in another register (R0).
-
[EWARM-6737, TPB-3112] On optimization level Medium and higher, the compiler can exit with an internal error when it processes code that contains both functions with #pragma inline=forced and functions with #pragma optimize=none. See this example:
void f1(void); #pragma inline=forced void f2(int a) { f1(); } #pragma inline=forced void f3(int a) { f2(a); } #pragma optimize=none int main(void) { int a = 0; f3(a); }
-
[EWARM-6726, TPB-3111] Using variable templates in conjunction with multi-file compilation (--mfc) can result in an internal error ("Internal Error: [Front end]: assertion failed: may_have_correspondence:
bad symbol kind ..."). -
[EWARM-6719] When loading constants that can be expressed as the bit-inversion of a rotated immediate value, the compiler and assembler can generate invalid ARM-mode instructions.
-
[EWARM-6716] The compiler fails to take side effects of the LDREX instruction into account, which can result in the instruction being removed if the loaded data is not used.
-
[EWARM-6701, TPB-3100] The compiler can terminate with an internal error ("assertion failed at: ...\interpret.c, line 4425") when compiling an expression that contains a section begin/end operator with an offset. For example:
(char*) __section_begin("MyOverlay") + 1
-
[EWARM-6700, TPB-3102] On optimization level Medium and above, the compiler can exit with an internal error for code that extracts parts of an integer, using a union that contains a struct and an integer like in the example below:
struct A { char a; char b; }; union B { struct A c; int d; }; int f(int g) { int h; union B k; for (int i = 0; i <= g; i++) { if (k.c.b) { h = k.d; } } return h; } } return h; }
-
[EWARM-6685, TPB-3093] The compiler can exit with an internal error when compiling C++ code if it encounters type punning casts of constants, like in this example:
const int a = 0x7FA00000; struct b { float c; b() : c(*(float *)&a) { } }; void d() { b e; }
-
[EWARM-6536, TPB-3110] The compiler can terminate with an internal error when #pragma _printf_args or _scanf_args is used on a C++ function that returns a temporary object that requires destruction.
-
[EWARM-6531, TPB-3057] The compiler can emit spurious warnings (Pa118) about mixing bool and non-boolean types in comparison expressions.
-
[EWARM-6335, TPB-2997] The compiler can terminate with an internal error in C++ mode in some cases involving initialization of an aggregate with integer members and a non-constant more than one level down.
- None.
V8.32 2018-10-12
Program corrections-
In EWARM 8.32.3
[EWARM-6657, TPB-3083] On optimization level High, the compiler can exit with an internal error when compiling code that contains loops with shifts inside. -
In EWARM 8.32.3
[EWARM-6634, TPB-3081] The compiler can terminate with an internal error for code that uses the variadic template operator sizeof... in a constant expression. -
In EWARM 8.32.3
[EWARM-6615, TPB-3077] On optimization level High, the function inlining optimization can cause the compiler to generate invalid code if the C++ operator placement new is used more than once in the same function, and at least twice places objects at the same address. As an example, consider the code below. When this code is compiled, the call to the constructor for YYYYY will incorrectly be removed on optimization level High, if the function inlining optimization is enabled.void Bug::Bug() { mI = new (mBuffer) XXXXX(); mI = new (mBuffer) YYYYY(); int data = mI->V(); if (data != 0) { showNr(data); } }
-
In EWARM 8.32.2
[EWARM-6594, TPB-3073] Multi-file compilation (–mfc) with C++ files where at least one file includes the <new> header and at least one file does not, incorrectly generates this error:Error[Pe1061]: declaration of enum "std::align_val_t" is incompatible with a declaration in another translation unit (...)
-
In EWARM 8.32.2
[EWARM-6555, TPB-3064]The compiler can crash when compiling code where two copies of the same 32-bit value are combined into one 64-bit value as shown in the example below.
uint64_t combine(uint32_t v) { return ((uint64_t)v << 32) | (uint64_t) v; }
-
[EWARM-6518, TPB-3053] In modules where the type of an integer bitfield is specified with an explicit signed modifier, the compiler will sometimes produce debug information where the signed integer types used this way are incorrectly given names that include the signed modifier. This can lead to a degraded debug experience, because it can cause the debugger to fail to unify structure types correctly.
-
[EWARM-6454, TPB-3043] The compiler can terminate with an internal error in some cases involving an & operator where one operand is an integer constant expression involving a non-type template parameter.
-
[EWARM-6416, TPB-3042] Compiling source code that contains an if constexpr statement with no else part, and a false condition causes the compiler to terminate with an internal error.
-
[EWARM-6414, TPB-3027] The warning message Pe182 ("bitwise operation drops significant bits from a constant") can be issued incorrectly. It exists to warn about cases like
if (uchar & 0x400)
but it is sometimes issued in cases where no such problem exists.
C18 support
The default Standard C is now C18 (ISO/IEC 9899:2018).C++17 support
The compiler now supports all C++17 features. The C++ library supports C++14 with no C++17 additions.
V8.30 2018-06-15
Program corrections-
In EWARM 8.30.2
[EWARM-6480, TPB-3040] A regression causes compilation of files containing large constant integer-only arrays to run out of memory. -
In EWARM 8.30.2
[EWARM-6471, TPB-3039]The compiler could issue a spurious error in some cases involving variadic member function templates.
Example:
struct A { struct B { void g() { A a; a.f(1); } }; void h(int){} template<typename... Ts> void f(Ts... args) { h(args...); // Spurious Pe018 (expected a ")") error here } }; int main() { A::B B; B.g(); }
-
In EWARM 8.30.2
[EWARM-6455, TPB-3034] The compiler incorrectly issues the Pe831 remark (support for placement delete is disabled) for the builtin declaration of operator delete when compiling with exceptions disabled. -
In EWARM 8.30.2
[EWARM-6447, TPB-3032] Returning a part of a union with an offset will return the part without offset if the function is inlined. For example,
union un { long long a; long b[2]; } ; long f() { un x; ... return x.b[1]; // returns x.b[0] when inlined }
-
In EWARM 8.30.2
[EWARM-6440] The template C++ library does not build for Cortex-M4 with VFP-v4. -
In EWARM 8.30.2
[EWARM-6438] When checking for MISRA-C:2004 rule 2.4 deviances, the compiler mistakenly triggers for Shift JIS multibyte characters in comments where the second byte is ';' or '}'. -
In EWARM 8.30.2
[EWARM-6409] On optimization level Medium and above, the compiler can generate incorrect code for min and max like question mark expressions like x < y ? y : x. If the type of the expression is smaller than int and the order of variables in the comparison is different from the order in the colon-part, the used value of one of the variables is not always extended properly. -
In EWARM 8.30.2
[EWARM-6394] A low-level optimization pass can in rare cases create an unpredictable STR instruction when the source register is the same as the base register, and write-back is used. -
[EWARM-7459, TPB-3314] On optimization level Medium and higher, the compiler can generate incorrect code if the common sub-expression elimination optimization is enabled.
-
[EWARM-6896] On optimization level Medium and above, the compiler can in some rare cases generate incorrect code when a Vector Floating Point (VFP) coprocessor or the Vectorization transformation is used. The problem is not triggered by a specific construct in the source code.
The problem can only be detected by inspecting the compiler list files. If a function pushes a VFP register that is not used within the function, it is an indication that the problem might have occurred and that this function needs a more detailed inspection.
-
The symbol {{__ARM_BIG_ENDIAN}} from ACLE (ARM C Language Extensions) is defined incorrectly as {{0}} for little-endian projects. The symbol should not be defined for little-endian projects.
-
The compiler can generate incorrect code for min and max-like qmark expressions when the condition compares two variables and the value of the expression is the value of either variable casted to a narrower type. The same bug can also trigger for if statements where the condition compares two variables and the then and else clause only assigns the value of either variable to another variable with a narrower type.
An example of the first case is shown below. The triggering criteria is the qmark expression, the if statement is there to prevent the compiler from removing the qmark.
int b; void e(unsigned int a, int c) { unsigned int d = (a > c) ? (unsigned short)c : (unsigned short)a; if (d) b = d; }
-
[EWARM-6322] On optimization level High, when FPU support is enabled, and the target FPU has 32 D registers, the compiler can generate incorrect code for loading floating-point constants that can be represented with a 1-bit exponent and a 6-bit mantissa.
-
[EWARM-6309, TPB-2989] On optimization level High, the code generated by the compiler can differ between invocations for source code where 1. the value of a local variable is conditionally set to two different constant values, 2. all uses of this variable are part of an identical subexpression, and 3. at least one but not all of these subexpressions is part of a larger bit-wise OR. This error does not affect the correctness of the code.
This code can trigger the issue:
int f(int x) { int a = (x == 5 ? 10 : 7); int b = 3 * a; int c = 7 | (3 * a); return b + c; }
while this code can't
int f(int x) { int a = (x == 5 ? 10 : 7); int b = 3 * a; int c = 7 - (3 * a); return b + c; }
As a special case, the issue can be triggered by bitfield struct assignments when the address of the struct is conditionally set to two different constant values, if all uses of the struct address are part of identical subexpressions. In this case, the subexpression that contains the bit-wise OR is part of the bitfield assignment.
-
[EWARM-6306] Using the intrinsic function _RBIT() or _rbit() on an architecture that does not support the instruction RBIT can cause an internal error on optimization level Medium or higher.
-
[EWARM-6279, TPB-2975] The library static variable _Isdst_rules is defined in both the 32-bit and the 64-bit code for time-handling. This can give an redefinition error at linkage.
-
On optimization level High, the compiler can crash with an internal error or possibly generate incorrect code when compiling loops like the example below. The necessary conditions to trigger this problem are: a) The loop variable is a pointer that is stepped using pointer arithmetic. b) Inside the loop, the loop variable is indexed by a sum of two values that are not changed within the loop.
void f(int *x, int b, int c, int d) { for (int *a = x; *a < 1 ; a = a + d) { a[0] = a[c + b]; } }
-
[EWARM-6250, TPB-2963] On optimization level None the compiler can exit with an internal error when compiling code that contains an anonymous union where one of the data members is a bitfield.
-
[EWARM-6240, TPB-2961] When performing MISRA C checking in C++ mode, the compiler can erroneously report a violation of rule 12.5 (operands of && and || must be primary expressions) for the right-hand operand if that operand is not of bool type.
-
[EWARM-6238] On optimization level Medium and above, and when compiling for Thumb targets, the compiler can generate incorrect code when the value of a Boolean variable is set to the result of a variable compared to a constant. Typical code that can trigger the bug is y = (x > 5 ? 0 : 1), but code that can be transformed into this form by the compiler can also be affected.
-
The compiler can fail to compile files with C++ code that use variadic function templates with default template arguments.
If a variadic function template has a default template argument that contains a pack expansion that uses an enclosing non-variadic parameter, a
substitution failure can result. This in turn will cause one of a number of errors, typically "no instance of ... matches the argument list".Example:
struct C {}; template <typename... Ts> struct A; template<typename, typename> struct B { static constexpr bool v = false; }; template<bool... T> struct F; template <bool... Bs> using E = B< F<Bs...>, F<Bs...> >; template<typename T, typename... _Us> struct D { static constexpr bool v = true; }; template<typename Ts, typename ...> struct H { template<typename... Us, bool b = E<D<Ts, Us>::v...>::v> H(Us&&... us); }; // Error "no instance of constructor ... matches the argument list" here H<A<C(int)>> h{1};
[EWARM-6198, TPB-2948] In some cases involving constexpr constructors of objects with class subobjects, the compiler can spuriously emit error Pe028 ("expression must have a constant value") with the (incorrect) note "access to uninitialized subobject".
[EWARM-6184, TPB-2943] The constructors and compound assignment operators of the explicit specializations of the std::complex template (for float, double, and long double) take component values by reference instead of by value.
[EWARM-6183] Using one of the ACLE intrinsic functions (__arm_rsr, __arm_rsr64, __arm_rsrp, __arm_wsr, __arm_wsr64, or __arm_wsrp) to access special registers in a C++ inline function can cause the compiler to terminate with an internal error.
[EWARM-6182, TPB-2944] A failed assert doesn't write the argument expression in the output.
[EWARM-6143] On optimization level High, the compiler can generate incorrect code when a pointer is assigned a value that is equal to it own address. The problem only occurs when compiling for the Thumb2 instruction set and is more likely to trigger when the assigned pointer is a field in a struct variable.
[EWARM-6116, TPB-2915] The #warning preprocessor directive now generates a separate diagnostic, instead of the same one as the #error preprocessor directive, only with a different severity.
C++14 constexpr void expressions can cause the compiler to terminate with an internal error ("[Il2cvm - CollectLiterals]: Unexpected constant kind.").
Example:
constexpr void foo() { } int main() { foo(); }
[EWARM-6079, TPB-2918] The compiler can terminate with an internal error instead of diagnosing the error when an array is declared with a size that is an address cast to an integer type.
On optimization level High, the compiler can generate incorrect code when simplifying address expressions in loops, if the address expression is inside another loop that is nested inside the first. As an example, consider the loop below. The compiler will simplify the array expression in two steps, first in LOOP C then in LOOP A, but in the second step it moves the initialization to a location where cc is not defined without replacing it with its initial definition. This problem will only occur when there is an extra level of nesting between the loops.
int f(int *data, int x, int c, int rc) { int v = 0; /* LOOP A */ for (int r = 0; r < rc; r++) { /* LOOP B */ while (!v) { /* LOOP C */ for (int cc = c + 1; (cc < (c + x)); cc++) { v = (data[cc * rc + r]); /* SIMPLIFY */ } } } return v; }
The following source code gives an erroneous error:
const std::function<int*(int*)> func = [](int *pn){ return pn; };
The parser does not correctly parse function modifiers like override when the underlying function declarator is parenthesized.
Example:
struct A { virtual void (*f())() = 0; }; struct B : A { virtual void (*f())() override; };
- None.
V8.22 2018-01-22
Program corrections-
In EWARM 8.22.2
[EWARM-6208, TPB-2953]Converting a value via a templated conversion operator to an instantiation of the returned class template can fail with a misleading error.
Example:
template<class T> struct A {}; struct B { template<class T> operator A<T>& (); }; struct S {}; void foo(A<S> &); void bar() { B b; foo(b); // Error here }
-
In EWARM 8.22.2
[EWARM-6192, TPB-2945] The compiler can in some circumstances incorrectly fold expressions containing a subscript applied to an integer cast to pointer type.Example:
int *p = &((int*)0x1000)[1];
Expressions like this will sometimes result in a pointer value without the offset.
-
On optimization level High, the compiler can generate incorrect code for loops when 1) The number of laps in the loop can be expressed as a simple arithmetic expression that contains one of the variables updated in the loop, 2) The initial value of this variable is an expression that contains another variable that is also updated in the loop, and 3) The updates that the loop performs on both these variables can be replaced by arithmetic expressions that contain the number of laps.
An example that triggers the bug is shown below. Note that 1) The number of laps in the loop is n = x / 10. 2) The initial value of x is x = y / 10 and y is modified in the loop. 3) The loop can be replaced with x = x - 10 * n and y = y - 100 * n.
unsigned int x; unsigned int y = 4712; int f(void) { x = (y / 10); while (x >= 10) { x -= 10; y -= 100; } return x; }
-
[EWARM-6128, TPB-2920] When generating list files in Raw encoding or the system default locale encoding, the compiler can emit an erroneous warning (Ms014) about being unable to correctly encode some characters.
-
[EWARM-6109] If a function parameter (or return value) is a "Homogeneous Aggregate" that should be passed in VFP registers, it can instead be passed in core registers (or on the stack). See "Procedure Call Standard for the ARM Architecture" for the definition of a "Homogeneous Aggregate".
A composite type that is not correctly identified as a homogeneous aggregate due to this bug is (or contains) a type that has two fields that do not have the same type. For example:
struct { float fa[2]; float f1; float f2; } Homogeneous_Aggregate;
The type above is not symmetrical: the field fa has type float[2], but the fields f1 and f2 do not.
A compiler with this bug is compatible with other compiler versions with this bug. For the highly specific cases described above, a compiler with this bug is however not compatible with a compiler that does not have this bug.
A runtime failure can occur if the caller and callee are implemented in different modules, and the modules are compiled with incompatible compilers.
-
[EWARM-6069] When the runtime support library for ARMv7-A/R rt7Sx_tl.a is specified on the linker command line for an application using division, the linker can report "Error[Lt039]: Incompatible architecture attributes" also in cases when there is no incompatibility.
This bug can cause the linker to produce a faulty binary without reporting an error. The binary will be faulty in the sense that it contains the UDIV instruction also for a core that does not support that instruction. This can happen if all of the following conditions are fulfilled:
- One of the runtime support libraries rt7Sx_tl.a or rt5E_al.a is specified explicitly on the linker command line (or one of the big-endian variants, rt7Sx_tb.a or rt5E_ab.a).
- Some library used by the application, and selected by the automatic library selection, uses a library division routine. If this library is specified on the command line, error Lt039 is reported.
- The target CPU does not support the UDIV instruction in Thumb mode.
- The application itself has no reference to any of the library division routines. If it does, error Lt039 will be reported.
Note that division by a constant can be optimized to use multiplication (optimization level High), which reduces the number of references to division routines from an application.
The library routines that use integer division include the printf family of routines, and several software floating-point routines.
-
[EWARM-6052] A call to an intrinsic function from an inline function that is compiled as Arm mode by default on a target where the intrinsic function is not available in Thumb mode erroneously gives the compile-time error [Ta097]. This only happens with C99 inlining.
-
[EWARM-6034, TPB-2907] The compiler can terminate with an internal error ("assertion failed: compare_constants: bad constant kind") in some cases involving compound literals in || or && expressions.
-
[EWARM-5945] When compiling for Thumb (not Thumb2), a reference to a table of strings with an
expression like [x - 1] can result in linking error "Error[Lp002]: relocation failed: value out of range or illegal".
None
V8.20 2017-10-16
Program corrections-
In EWARM 8.20.2
[EWARM-6013, TPB-2874] The compiler could terminate with an internal error (...decl_inits.c, line 5177) when using a braced initializer for a member array of objects with constructors. -
In EWARM 8.20.2
[EWARM-5993, TPB-2871] Member variables in constant and constexpr-declared objects of types with constexpr-declared constructors will not be recognized as constant when identifying known values. This leads to very inefficient (but still correct) code for this case. -
In EWARM 8.20.2
[EWARM-5985, TPB-2908] On optimization level High, a negative constant offset in an index expression with an unsigned type smaller than int will change into a positive offset. For example, if the index expression type is unsigned char, the expressioni - 15u
becomes(int)i + 240
. -
In EWARM 8.20.2
[EWARM-5984, TPB-2854] On optimization level High and above, the analysis in the compiler can fail to account for updates to fields in struct variables, if the update is performed in an inlined function. This can make the compiler erroneously infer that this field has a constant value. -
In EWARM 8.20.2
[EWARM-5941] On optimization level High and above, the compiler can generate erroneous output for min and max expressions, for example x < y ? x : y, if one of the values is constant. -
In EWARM 8.20.2
[EWARM-5937, TPB-2845] On optimization level Medium and above, the order in which variables with static storage duration are placed in the output file is not deterministic. This has no effect on the correctness of the code. -
In EWARM 8.20.2
[EWARM-5932, TPB-2835] The compiler might generate incorrect exception information for function calls that return an aggregate type through a return value pointer, if either the result is placed in a variable that has an alias or if the destination address is complex to compute, and the calling convention is such that the return value pointer is not returned from the function. -
In EWARM 8.20.2
[EWARM-5842, TPB-2830] When using --no_static_destruction and there is a thread local variable needing destruction, the compiler can terminate with an internal error (assertion failed at "...\lower_init.c", line 21513). -
[EWARM-5947, TPB-2828] The optimizer combines shifts operations (<< or >>) distributed in a binary expression (+ - & | ^) even though the shift counts are not identical. An example with ‘+’ as the binary operator and left shifts in both arguments:
((c*16)<<1) + (((c-1)*4)<<1) is first simplified to
(c<<5) + ((c-1)<<3) which is then incorrectly rewritten as
(c + c-1)<<3
This error occurs if both shift counts are simplified expressions in themselves, as in the example above. The expression can be explicit in the source code or the result of previous optimizations. Because of this, there is no effective workaround. -
[EWARM-5927, TPB-2841] Some partial template class specializations, that differ only in decltype expressions, are incorrectly considered identical by the compiler.
Example:
template<class Ty> Ty declval(); template<bool a> struct b {}; template<> struct b<true> {typedef void type;}; template<typename T1, typename T2 = void> struct d; template<typename U> struct d<U, b<decltype(f(declval<U>()))::g>> {}; template<typename U> struct d<U, b<decltype(f(declval<U>(), declval<U>()))::g>> {};
The final two partial specializations are incorrectly considered identical.
-
[EWARM-5874, TPB-2825] The compiler can fail to emit code to properly initialize other members when compiling a constructor for a class that has an anonymous struct (an IAR extension) inside an anonymous union member.
-
[EWARM-5855, TPB-2820] The compiler sometimes failed to update the debug information for variables whose storage location changed, for example by being moved from the stack into a processor register.
-
[EWARM-5833, TPB-2809] The compiler can terminate with an internal error ("[GoMain - CheckScopes]: Incorrect scope information from parser.") in some cases involving std::initializer_list constructors with default parameters.
-
[EWARM-5825, TPB-2804] The compiler can issue spurious errors when compiling a constexpr constructor for a class that uses an anonymous struct (an IAR extension) inside an anonymous union.
-
[EWARM-5803] Compiling a function where the accumulated size of stack variables is large (more than 1024 bytes) can result in an internal error.
-
[EWARM-5797, EW26712] A compiler-internal error could occur when compiling for VFP, for example if a value consisting of four double values is copied. The problem can occur for 64-bit, 128-bit, and 256-bit containers, that is: two float values, two double values, four float values, or four double values.
-
[EWARM-5747, EW26638] iarchive terminates with an internal error if any of the paths uses non-ascii characters.
-
[EWARM-5741, EW26627] The compiler can terminate with an internal error in some cases when _section_begin/_section_end is used in an expression with a constant offset.
-
[EWARM-5736, EW26616] The MISRA-C:2004 rule 5.2 is triggered if a parameter name in a function declaration is the same as a variable in the enclosing block.
-
[EWARM-5702, EW26550] On optimization level -Om and above the compiler can generate erroneous code for strcmp when the parameters are pointers to constant strings and at least one of the pointers doesn't point to the beginning of the corresponding string.
-
[EWARM-5701, EW26548] A function containing a call to itself, and the recursive call is followed by a switch, can trigger an internal error on optimization level Medium or High.
-
[EWARM-5570, EW26345] An internal error would occur when compiling an inline assembler statement with a VFP instruction within an IT-block for a target that does not support VFP.
-
[EWARM-5269, EW25735] The life time of variables on the stack are not handled correctly over calls to setjmp. This may cause two variables with non-overlapping life times to be assigned the same location on the stack and the value might not be preserved for the variable live at the setjmp call.
Initial support for the Arm v8-R architecture
This release provides basic supports for the Arm v8-R/R52 architecture.Stack protection
The IAR C/C++ compiler for Arm now supports stack protection. A canary value will be placed between the stack variables and the return address so that the system can detect corruption of a function return address before the function returns to that address. The compiler will use heuristic to determine whether a function needs stack protection or not. If any defined local variable has the array type or a structure type that contains a member of array type, the function will need stack protection.
V8.11 2017-04-11
Program correctionsOn all optimization levels, the compiler can generate incorrect code for assignment to bitfield members if the right-hand sign expression updates any variable, for example by using post-increment. A typical example triggering the bug is shown below.
[EWARM-6162, TPB-2942]#include
struct A { int a; int b:8; }; int main(void) { struct A v1 = {0,1}; struct A v2 = {2,3}; v2.b = v1.a++; if(v2.b == 0) { printf("OK\n"); } else { printf("BAD\n"); } return 0; } On optimization level High, speed,
do
loops with a post increment or post decrement operation in the loop test can be optimized incorrectly.
[EW26455]In some very rare cases the compiler can end up in an infinite loop.
[EW26475]Modulo expressions where the divisor is
-1
orU{CHAR,SHRT,INT,LONG}_MAX
are not handled when the divisor is extended to a larger unsigned type.
[EW26479]On optimization level High a
for
orwhile
loop that is preceded by anif
statement where the condition is identical to the loop condition can be optimized incorrectly, if any of the variables in the test is modified between the if statement and the loop test, and the variable has a type that is smaller thanint
.
[EW26492]The AFE1 assembler cannot handle characters in comments with values over
0x7F
in default mode.
[EW26495]In EWARM 8.11.2:
Sometimesvget_lane_xxx
orvgetq_lane_xxx
can generate internal error. [EW26156]In EWARM 8.11.2:
When compiling large functions for Thumb-2 it can happen that two basic blocks are more than 1Mb apart, so that a conditional wide branch cannot reach. Previously the compiler would fail, either by not terminating, or by reporting an internal error. This is now handled by using two instructions.
[EW26189]In EWARM 8.11.2:
When compiling for a core that has VFP, but does not have NEON, accessing an object of type T1 in an object of type T2 could lead to internal error if the type T2 consists of two objects of type T1, and T1 consists of two objects of type double.
[EW26205]In EWARM 8.11.2:
The compiler can terminate with an internal error in C++ mode when an assignment to a structure with bitfields is made using list-initialization.
[EW26520]In EWARM 8.11.2:
In some rare cases, conditions where a variable is compared to a constant can be optimized incorrectly on optimization level High or Medium.
[EW26525]In EWARM 8.11.2:
The functionisblank()
incorrectly returns true for characters thatisspace()
returns true for.
[EW26556]In EWARM 8.11.2:
Variables defined with__ro_placement
are not accessed correctly when compiled forRWPI
.
[EW26569]In EWARM 8.11.2:
The functionsiswctype
andwctype
are missing functionality for the blank operator.
[EW26581]In EWARM 8.11.2:
putchar(-1)
erroneously assumes that-1
isEOF
when the standard says it should be handled as the character0xFF
.
[EW26588]In EWARM 8.11.3:
On optimization level High, the compiler can generate invalid code for dereferencing a pointer when the pointer is the result of an arithemtic expression containing subtraction.
[EW26629]In EWARM 8.11.3:
A generated thunk call with a structure parameter larger than four bytes and not an even four bytes in size could cause an internal error.
[EW26633]In EWARM 8.11.3:
If an ELF-segment has a size of 0 bytes and the last line in the Intel-hex/Motorola S-record file of the immediately preceeding segment contains less than 16 payload bytes, the incomplete line is not output and the bytes that should reside there are lost.
This problem was introduced in version V10.1.4.185.
[EW26644]In EWARM 8.11.3:
On optimization level High, code can be optimized incorrectly if it contains multiple accesses to the same array element (a[i]
) and one of the accesses occurs where the optimizer can compute a constant value for the index expression (for example:if (i == 42) x += a[i]
.
[EW26655]In EWARM 8.11.3:
When compiling for targets with dsp-extensions the compiler can generate a signed multiplication instruction for multiplying two unsigned values shifted 16-steps right.
[EW26663]In EWARM 8.11.3:
On optimization level Medium and above, the compiler erroneously optimizes as if static variables declared as__no_init
were zero-initialized.
[EW26692]In EWARM 8.11.3:
On optimization level Medium and above, the compiler sometimes generates erroneous output for code containing a switch statement where the expression dereferences a pointer that later will be incremented.
[EW26713]In EWARM 8.11.3:
Zero-initialized absolute variables are treated as if they were__no_init
(not initialized at program startup).
[EW26715]In EWARM 8.11.3:
Value initialization (which is what happens to objects whose initializer is an empty set of parentheses) of an array of objects, some of whose subobjects have a user-provided default constructor, incorrectly does not zero-initialize the other subobjects.
[EW26717]In EWARM 8.11.3:
The compiler option--no_unaligned_access
is not honored for Thumb-2 when performing a structure copy on two-byte structures.
[EWARM-5810, EW26735]In EWARM 8.11.3:
On optimization level High, code can be optimized incorrectly if it contains multiple accesses to the same array element (a[i]
) and one of the accesses occurs where the optimizer can compute a constant value for the index expression (for example:if (i == 42) x += a[i];
). [EWARM-5761, TPB-2775]In EWARM 8.11.3:
Complex expressions involving a negation of a subtraction where one of the terms is a multiplication where one of the factors is a subtraction can be optimized incorrectly, on optimization level high. Example:return (- ( ((x - y) * - 2) - z) ) / 48;
The compiler makes a silent code generation error when optimizing a complex expression involving a unary negation, a constant, and several binary operations. If the compiler, during the optimization, transforms the expression so that the constant gets negated the code generation can be faulty.
[EWARM-5740, EW26625]In EWARM 8.11.3:
The initialization code for C-RUN (bounds checking) included unaligned accesses.
[EWARM-5861]
Cortex-R8
Support for code generation and debugging of ARM Cortex-R8 cores.
V8.10 2017-03-10
Program correctionsInitializing an array of aggregates, parts of which are plain-old-data, with a braced initializer list with fewer entries than the number of elements in the array could cause the compiler to terminate with an internal error (assertion failed in decl_inits.c).
[EW26298]A function containing two (or more) identical tests that occur in or as arithmetic expressions can in some cases be optimized incorrectly on optimization level High.
[EW26325]On optimization level Medium or High accesses to a
const __weak
structure or array variables can be optimized incorrectly.
[EW26346]Missing an
ENDM
when recording a macro causes an internal error when using the macro.
[EW26360]The template project for rebuilding DLIB libraries contained a file difftime_i.c, which requires a header file that is not included in the distribution. The file difftime_i.c is no longer part of the project.
[EW26372]Some complex array address expressions can trigger an internal error.
[EW26388]Warning Pe111 (statement is unreachable) is incorrectly not issued for code after a call to a noreturn function.
[EW26389]In rare cases the intra-crossjump optimization can remove code that is still used.
[EW26429]Variables with static or thread storage duration can be optimized incorrectly on optimization level Medium or High, if they are incremented or decremented with a constant amount and there is only a single use in the rest of the function.
[EW26446]Functions where the address of an array with automatic storage duration is passed to an inline assembler statement can be optimized incorrectly on optimization level High.
[EW26448]The compiler might produce an internal error after a Pe291 error, "no default constructor exists for class X".
[EW26522]The square root function in the floating point library returns
+0.0
forsqrt(-0.0)
and not-0.0
as the standard specifies.
[EW26590]The compiler cannot concatenate wide string literals with character string literals.
[EW26602]cosh(Inf)
doesn't seterrno
toEDOM
.
[EW26608]
Support for the C11 language standard
The compiler and libraries add support for the latest C language standard ISO/IEC 9899:2012.
- The new C library binary object interface is incompatible with earlier EWARM versions.
- C11 is the default language. C89 may be used as well (not 100% backwards compatible).
- The C11 thread mechanism is not supported, and
atomic
is only supported for certain ARM cores. - Support for TLS variables and secure C functionality is included.
Support for the C++14 language standard
The compiler and libraries now support the latest C++ standard ISO/IEC 14882:2015.- The new C++ library binary object interface is incompatible with earlier EWARM versions.
- It is not possible to upgrade an earlier EC++ or earlier C++ application into using the new C++ without porting the code, i.e. the C++ language is not backwards compatible
- The compiler supports C++ with or without exceptions and RTTI.
- The compiler supports
atomic
for certain ARM cores. - Embedded C++ and Extended Embedded C++ have been removed.
The compiler now has proper support for encodings. This means that you can use UTF-8, UTF-16, UTF-32, or the system locale in strings and characters.
V7.80 2016-10-17
Program correctionsThe compiler can exit with an internal error when compiling or preprocessing a source file with certain
#pragma
directives inside a macro argument. Typically this can happen if there is an#include
directive inside an unterminated macro invocation.
[EW26221]On high optimization level, loops equivalent to memcpy, memset, or memclr can be optimized incorrectly if the upper limit in the loop is a function call.
[EW26223]The Global Optimizer could under certain circumstances generate non-canonical intermediate code. The structure of this (otherwise correct) code was not expected by the code generator, resulting in an internal error.
[EW26232]On high optimization level, a scalar variable (
v
) with automatic storage duration can be optimized incorrectly if
• the only visible assignments tov
assign it0
or1
,
• the function contains one or more calls that assignv
indirectly,
• the calls that assignv
all have a pragmafunction effects
that statesno_state
, and
• the function masks out the lowest bit ofv
(as inv & 1
).
[EW26241]The compiler can exit with an internal error if member function code for a class template uses the
dynamic_cast
operator from or to pointers or references to the class template type itself.
[EW26248]The optimization of accesses to stack parameters for Thumb-1 code is performed in memory-dependent order. This results in different code generated for small changes of the environment.
[EW26267]Using
#pragma weak
to define a weak alias and then using that alias in the same compilation unit can result in the compiler exiting with an internal error.
[EW26268]In EWARM 7.80.2:
Expressions of the form((S.A >> (32 - N)) | (S.B << N))
could be rewritten as a rotate instruction (ROR
), whenA
andB
were fields in the same structS
.
[EW26210]In EWARM 7.80.2:
Solved a locale issue that created problems with Japanese characters in the project file path.
[EW26278]In EWARM 7.80.4:
Initializing an array of aggregates, parts of which are plain-old-data, with a braced initializer list with fewer entries than the number of elements in the array could cause the compiler to terminate with an internal error (assertion failed indecl_inits.c
).
[EW]In EWARM 7.80.4:
A function that contains two (or more) identical tests that occur in or as arithmetic expressions can in some cases be optimized incorrectly on optimization level High.
[EW26325]In EWARM 7.80.4:
On optimization level Medium or High, accesses toconst __weak
structure or array variables can be optimized incorrectly.
[EW26346]
V7.70 2016-06-17
Program corrections-
On optimization level High, static variables can be optimized incorrectly, if there are no visible reads from the variable in the translation unit and the address of the variable occurs in the initializer of another variable and the address has been cast to an integer type.
[EW26045] -
Casting a signed character to an unsigned type to a pointer type can trigger an internal error.
[EW26051] -
Internal error when generating VFP code for a multiplication of a
short
by1.0f
converted back toshort
.
[EW26068] -
When compiling for an ARM core with DSP extensions (architectures ARMv7E-M, ARMv5E), an expression of the form
a - ((b * c) >> 32)
wherea
is a 32-bit value andb, c
are 64-bit values, can get the wrong result.
[EW26084] -
The assembler-level optimizer could get trapped in a meta-stable state due to a sequencing issue in the flow of control analysis.
[EW26088] -
In EWARM 7.70.2:
Using path names with national characters (characters outside 7-bit ASCII) in ielftool does not work properly in some circumstances:
* Specifying such characters for a raw binary, SimpleCode, or ELF output file results in a file in an incorrect location with an incorrect name.
* The verbose console output is incorrect in most cases for such characters in input files as well as output files.
[EW26101] -
In EWARM 7.70.2:
Vectorization of accesses to floating-point numbers does not handle negative scaling or negative increments correctly.
[EW26170] -
In EWARM 7.70.2:
In some rare cases forced inline functions can trigger an internal error on optimization level Low.
[EW26172] -
In EWARM 7.70.2:
Loops where the loop counter is incremented both with a loop-invariant non-constant expression and a constant can trigger an internal error on optimization level High.
[EW26175] -
In EWARM 7.70.2:
When compiling for Thumb-2, inline assembler statements could be placed within an IT block, which would often result in error Ta117 (IT block ends prematurely)
[EW26200] -
In EWARM 7.70.2:
On optimization level Medium or High, inline assembler statements can be incorrectly optimized if a variable occurs as an output parameter and the variable is assigned prior to the inline assembler statement.
[EW26201]
-
Initial support for the new ARMv8-M architecture
This release supports both the ARMv8-M Baseline and Mainline implementation. The ARMv8-M architecture is focused on bringing security to applications in the embedded and IoT market.
An example project can be found in the directory<installation path>\arm\src\ARMv8M_Secure
.This is a quick reference to CMSE related extensions that are available but not otherwise documented. We refer to ARM documentation regarding the CMSE programming model, see for example the "ARMv8-M Security Extensions: Requirements on Development Tools".
The extensions below are only available when building for ARMv8-M, baseline (
--cpu 8-M.baseline
) or mainline (--cpu 8-M.mainline
).The CMSE programming model specifies that secure code and non-secure code are built as separate executable files. The level of set-up peformed by the secure code and the location of the entry point to non-secure code is however not specified in the CMSE programming model, so the two executable files must agree on these points in order to interface correctly.
The linker will automatically create a secure gateway veneer for each entry function, as determined by the attribute
__cmse_nonsecure_entry
. These veneers are generated in the sectionVeneer$$CMSE
, which should be placed in a NSC region. Consult the documentation for your ARMv8-M core to determine how to program the SAU (Security Attribute Unit).ICCARM attributes related to CMSE
ATTRIBUTE
__cmse_nonsecure_entry
DESCRIPTION
When building secure code (using--cmse
), use this attribute to declare an entry function to secure mode.
This corresponds to__attribute__((cmse_nonsecure_entry))
in the CMSE programming model.
Parameters or return values located on the stack or in VFP registers are not supported for functions with this attribute.ATTRIBUTE
__cmse_nonsecure_call
DESCRIPTION
When building secure code (using--cmse
), use this attribute for non-secure function calls. This disallows function definitions with this attribute and ensures a secure executable file only contains secure function definitions. This corresponds to__attribute__((cmse_nonsecure_call))
in the CMSE programming model.
Parameters or return values located on the stack or in VFP registers are not supported for functions with this attribute.ICCARM options related to CMSE
OPTION
--cmse
Enable CMSE secure object generation
DESCRIPTION
This option enables support for creating CMSE secure executable files, using the CMSE attributes__cmse_nonsecure_entry
and__cmse_nonsecure_call
. The option--cmse
corresponds to-mcmse
in the CMSE programming model.IASMARM options related to CMSE
OPTION
--cmse
Enable CMSE secure object generation
DESCRIPTION
This option enables the use of instructions that are only available in secure mode.ILINKARM options related to CMSE
OPTION
--import_cmse_lib_out FILE|DIRECTORY
Produce import library for building non-secure image
DESCRIPTION
Use this option when linking a secure image, to create an import library which is then used when linking a corresponding non-secure image. The import library is an object file that consists of a symbol table: each symbol specifies the address of a secure gateway for an entry function of the same name as the symbol.OPTION
--import_cmse_lib_in FILE
Read previous version of import library for building non-secure image
DESCRIPTION
Use this option when updating an import library. Entry functions that exist in the provided import library will be placed at the same address in the updated import library.
V7.60 2016-03-31
Program corrections-
Some errors in initialization expressions can be diagnosed with error Pe001 (last line of file ends without a newline) instead of the appropriate error.
Example:union XXX var = 0;
[EW25472] -
Instruction scheduling could move a stack access (using a register other than
SP
) across a stack pointer adjustment, which could lead to a corrupt stack if an interrupt occurs.
[EW25810] -
SPC volatile reads produce a false positive when some part of a volatile read consists of a multi-dimensional array.
[EW25817] -
Using the value of a subexpression containing an assignment operator on a bitfield can sometimes cause the compiler to terminate with an internal error.
[EW25853] -
When simplifying expressions looking like
(x & c1) | (y | (x & c2))
the compiler would extract the wrong constant ify
was of the formx & {expr}
. This in turn would cause the compiler to try to constant-foldc1
with a non-constant value resulting in a NULL pointer and an inevitable NULL pointer crash.
[EW25854] -
When generating code for VFP, a parameter of a union type consising only of floating-point members of the same type was incorrectly handled as the corresponding struct type. In some cases this would result in an internal error, and in other cases a read of memory after the union.
[EW25855] -
In some cases an internal error is reported when generating code in ARM mode for a switch where all integer values within a range have the same destination label, and the distance from the first to the last value in the range cannot be represented as a shifted immediate. Note that due to optimizations, case values that consist of equivalent code could get assigned the same label.
[EW25860] -
Functions with block-local static variables that are initialized with a variable address can be optimized incorrectly.
[EW25864] -
Some loops with the accumulation pattern could (incorrectly) be vectorized if the loop contained other uses of the accumulator.
[EW25867] -
Medium or higher optimization calls to
strcmp
, where an argument is a reference to an element in a const multi-dimensional char array, can be optimized incorrectly.
[EW25868] -
Loops containing an invariant compare to zero can be vectorized incorrectly.
[EW25871] -
Using a compound literal as part of the initializer for a block-local static variable in C could cause the compiler to terminate with an internal error in some cases that should have produced an
expression must have a constant value
error instead.
[EW25873] -
Array accesses after the loop counter has been decremented can be vectorized incorrectly.
[EW25875] -
A loop can be vectorized incorrectly if it contains references to an auto array used only inside the loop.
[EW25878] -
Loops can be vectorized incorrectly if they contain signed
short
orint &
operations with negative constants. (This can occur in bitfield operations where the underlying type is signed.)
[EW25880] -
Using a local assembler label with the same name as a hexadecimal constant without the initial
'0'
in the same inline assembler statement could cause the compiler to terminate with an internal error.
[EW25882] -
Left-shifting an 8-bit value more than 16 steps could trigger an internal error during vectorization.
[EW25885] -
On medium and high optimization, partial accesses to scalar static variables can be optimized incorrectly.
[EW25890] -
When the optimization goal is size, a loop containing an array element assignment, where the right hand side is a variable and the same variable occurs in the index expression (
a[i] = i
), can be optimized incorrectly if the compiler can deduce that the loop body will be executed exactly once.
[EW25893] -
No error message is emitted for some unallowed aggregate types (example: a struct with a single zero-length array member).
[EW25897] -
The compiler could terminate with an internal error when compiling a function ending with a conditional loop where the end of the loop cannot be reached.
[EW25932] -
Faulty backtrace information was generated for a non-SWI function definition in Thumb-2, if there was a previous Thumb-2 SWI function definition in the same compilation unit. The known symptom is that instruction stepping in the debugger slows down.
[EW25945] -
Functions taking parameters whose types involved the type
va_list
could be given incompatible mangled names when compiled in full C++ mode when<stdarg.h>
(or<cstdarg>
) was not included before all other system library headers.
[EW25962] -
Compiling with runtime bounds checking enabled in Thumb mode could make the compiler terminate with an internal error (
ElfOutput: Stack usage label missing!
).
[EW25981] -
In EWARM 7.60.2:
On High optimization,do
loops with signed compare in the loop test can be optimized incorrectly.
[EW25986] -
In EWARM 7.60.2:
Optimizing floating-point compares that contain a constant might change the constant slightly too much in rare cases.
[EW26011] -
In EWARM 7.60.2:
Attempting to clobber a locked register in an inline assembler statement would result in an internal error instead of a more descriptive error message.
[EW26013] -
In EWARM 7.60.2:
When an optimization removes the last use of a callee-saved register, the now unused register is in some cases no longer saved. This changes the stack layout, which was not reflected by DWARF debug information.
[EW26026] -
In EWARM 7.60.2:
Theextend-and-add
instruction allows the third operand to be rotated before extending but this was overlooked in the optimization code, causing the compiler to crash when the operand was rotated.
[EW26027] -
In EWARM 7.60.2:
In--macro_positions_in_diagnostics
mode, using_Pragma(""diag_xxx = ..."")
in a macro does not have the expected effect on diagnostics caused in the rest of the expansion of the macro.
[EW26032] -
In EWARM 7.60.2:
The compiler sometimes retains some unnecessary writes to the virtual function table pointer in constructors for abstract classes that previous versions of the compiler managed to remove.
[EW26038] -
In EWARM 7.60.2:
Compiling with--no_unaligned_access
could result in an internal error for example when indexing an array with unaligned 2-byte elements (the problem occurrs when an offset register is used in the twoLDRB/STRB
instructions used to load/store the unaligned 2-byte element).
[EW26042] -
In EWARM 7.60.2:
In rare cases a volatile inline assembler statement could be removed if it was legal to remove the corresponding non-volatile inline assembler statement. This could happen only when a copy of the inline assembler statement was introduced by some optimization: the volatile attribute of the copy would be memory dependent (uninitialized).
[EW26047] -
In EWARM 7.60.2:
Static storage duration variables of reference type initialized to an lvalue are not placed in ROM.
[EW26076]
V7.50 2015-11-10
Program corrections-
Variables that are placed in a user-specified section/segment and explicitly initialized with a zero value are incorrectly optimized by the compiler to be zero init instead of copy init.
[EW25498] -
The debug heap is now better at detecting erroneous writes outside allocated heap space. Erroneous writes can still go undetected but more of them are now detected.
[EW25682] -
When performing heap leak checking, a heap block with a payload size of 0 (typically the result of a
malloc(0)
call) is always considered to be leaked.
[EW25684] -
When performing heap leak checking and the delay list is active, all heap blocks on the delay list are reported as leaked.
[EW25685] -
When compiling for VFP, the
VLDR
instruction is in some cases used for loading (possibly) unaligned data, which can happen when__packed
or#pragma pack
is used, The result is a "hard fault" interrupt in cases where the address is actually unaligned.
[EW25708] -
The lifetime of variables on the stack are not handled correctly over calls to
setjmp
. This might cause two variables with non-overlapping lifetimes to be assigned to the same location on the stack and the value might not be preserved for the variable life at thesetjmp
call.
[EW25735] -
On optimization level High a use of a variable (v) can be incorrectly optimized if
1) v's last use for that definition appears in a binary operation with another variable (c),
2) c is assigned a constant value in one or more of the basic blocks predecessors,
3) the binary operation is an identity operation for one of the constants that c is assigned, and
4) v has an indirect definition.
[EW25739] -
Long long
additions of0xFFFFFFFF00000000
or subtractions of0x100000000
can be incorrectly optimized.
[EW25745] -
When generating Thumb-2 code at optimization level High, a byte assignment into an array on the stack can in rare cases result in an unpredictable
STRB
instruction (the stack pointer is used as offset register).
[EW25778] -
In EWARM 7.50.2 The Neon intrinsic function
vcombine_<type>(X,Y)
can now emit theVSWP
instruction when needed.
[EW25765] -
In EWARM 7.50.2 When vectorization is enabled, a loop containing multiple accesses with pre-/post-decrement through the same pointer variable can trigger an internal error.
[EW25794] -
In EWARM 7.50.3:
On optimization level High, loops can be incorrectly optimized if they contain multiple basic blocks, one or more inline assembler statements, and array accesses passed as arguments to the inline assembler statements.
[EW25814] -
In EWARM 7.50.3:
On optimization level High, infinite loops can, in some rare cases, cause the compiler to get stuck in an infinite loop.
[EW25831] -
In EWARM 7.50.3:
Reduction loops can be incorrectly vectorized if they contain casts fromchar
toint
(orshort
tolong long
).
[EW25833] -
In EWARM 7.50.3:
On optimization levels Medium and High, an auto array with just one element can in some circumstances trigger an internal error.
[EW25903]
V7.40 2015-02-19
Program corrections-
The library function that is used for Cortex-M0/M0+/M1 (ARMv6-M) to multiply two single-precision floating-point numbers can for some inputs produce an erroneous value for the least significant bit of the result.
[EW25075] -
Inline assembler did not correctly handle a pseudo-instruction in an IT block, when the pseudo-instruction expands to more than one instruction (
MOV32
expands to two instructions). This only affects THUMB mode, and only architectures that have the IT instruction (ARMv6T2, or later: not ARMv6-M).
[EW25112] -
C-RUN no longer causes a write operation to flash memory when attempting to track bounds for a pointer stored at address 0. A runtime error is instead reported. The problem has been observed when a Cortex-M vector table is written in C or C++: the initial stack pointer is located at address 0, and its bounds are tracked. The solution is to build the vector table without tracking of pointer bounds.
[EW25122] -
In some cases the reduction pattern can trigger an internal error during vectorization.
[EW25144, EW25154] -
Including
stdarg.h
is case sensitive. When attempting to includeStdarg.h
the compiler would include a faulty file. Instead, the compiler now reportsFatal error[Pe1696]: cannot open source file
.
[EW25156] -
The compiler can terminate with an internal error when processing the dynamic initialization of a
const static
member variable of POD type of a template class. Example:
[EW25157]template<class T> struct C { static const int a; }; extern const int k; template<class T> const int C<T>::a = k;
-
A function with
#pragma optimize
that has both level and goal flags does not get the correct optimization.
[EW25169] -
The normalization loop of the result mantissa had no initial test whether the MSB of the mantissa was set or not. In some cases one could get a faulty result and in some rare cases the normalization could end up as an infinite loop. This was only a problem for the
fmod()
function adapted for the ARMv4 instruction set.
[EW25170] -
When linking a C++ application using exceptions for an ARMv7-M core without VFP and using an explicit
--cpu
option, the linker would report a false error indicating that the exception engine inrt7M_tl.a
uses VFP instructions incompatible with No vfp.
[EW25188] -
When compiling with C++ exceptions and VFP support enabled, if a function or function type taking a parameter of type
std::complex<>
or returning an object of typestd::complex<>
occurs before the first public variable or function definition in a module, the code for that function, or calls to that function type, can be incorrectly generated.
[EW25215] -
The compiler can terminate with an internal error in some cases, involving aggregate initialization of variables with automatic storage duration in template code where at least one aggregate element is not a constant.
[EW25228] -
In EWARM 7.40.2:
The compiler sometimes incorrectly reports a violation of MISRA C:2004 rule 17.4 (array indexing only with arrays) when accessing an array field of a structure variable with static storage duration.
[EW25240] -
In EWARM 7.40.2:
The compiler can terminate with an internal error when the initialization of a struct variable supplies values for a flexible array member at the end.
[EW25245] -
In EWARM 7.40.2:
Casting the address of a struct variable to another type of struct variable of different size and performing a structure assignment can trigger an internal error on optimization level high.
[EW25249, EW25296] -
In EWARM 7.40.3:
Internal error was reported when compiling an empty nested interrupt function for ARMv6 or newer cores that are not in the architecture profile M.
[EW25229] -
In EWARM 7.40.3:
A function that takes stack parameters and uses a lot of NEON registers in different sizes can in some rare circumstances end up with an incorrect offset to the stack variables.
[EW25336] -
In EWARM 7.40.3:
In some very rare cases, automatic function inlining of functions with complex conditional code can trigger an internal error.
[EW25346] -
In EWARM 7.40.3:
When the##
operator is used between a comma and__VA_ARGS__
, and__VA_ARGS__
expands to no tokens, the compiler incorrectly issues warning Pe1665 (concatenation does not create a valid token).
[EW25348] -
In EWARM 7.40.3:
Relative relocations are now allowed from within a movable block to outside that movable block, if the destination is not movable. The effect is that position-independent code (compiled with--ropi
) can now call code that is not position-independent.
[EW25359] -
In EWARM 7.40.3:
When using the optimization level High, Size, optimizationwhile (n--)
loops can be incorrectly optimized. The optimized loop does not execute its final iteration.
[EW25383] -
In EWARM 7.40.3:
The compiler can terminate with an internal error if a static function that has been optimized away is used in a#pragma
calls directive.
[EW25387] -
In EWARM 7.40.3:
Zero-initialization no longer overwrites the start of the next block when the size of zero-initialized data is not a multiple of four.
[EW25395] -
In EWARM 7.40.3:
TheVLDR
andVSTR
instructions are no longer used for unaligned access of an integer that is later converted to a floating-point number.
[EW25407] -
In EWARM 7.40.3:
When using the optimization level Medium, optimization a sequence of common subexpressions, containing pointer indirections, can be incorrectly optimized if the sequence occurs in parallel flows of control.
[EW25415] -
In EWARM 7.40.3:
Casting the address of a small auto array to a pointer type and assigning the whole array an object of another type can in some cases trigger an internal error.
[EW25442] -
In EWARM 7.40.5:
On optimization level High, additions of invariant floating-point values can be hoisted out of loops, even if--relaxed_fp
was not enabled. This might affect how the values are rounded.
[EW25450] -
In EWARM 7.40.5:
Instruction scheduling can incorrectly move an instruction, for example a store instruction, past an IT block containing instructions with side effects that would otherwise prohibit such a move, such asWFI
orWFE
. The effect would in this case be that the store instruction is not executed until after the core returns to operating state, instead of before.
[EW25466] -
In EWARM 7.40.5:
The declarations for the intrinsic functions__get_LR
,__set_LR
,__get_SP
, and__set_SP
are missing in the header fileintrinsics.h
.
[EW25471] -
In EWARM 7.40.5:
In some cases, source code where the::
operator is used after something that is not a class or a namespace can cause the compiler to terminate with an internal error after diagnosing the problem.
[EW25478] -
In EWARM 7.40.5:
The compiler can terminate with an internal error if the initialization of a function local static storage duration variable extends a flexible array member.
[EW25483] -
In EWARM 7.40.5:
The compiler sometimes miscompiles calls via a pointer to member function where the member function returns an object by calling a copy constructor.
[EW25501] -
In EWARM 7.40.5:
The settings from#pragma default_function_attributes
and#pragma default_variable_attributes
are not reset at the start of each compilation unit when using--mfc
(multi-file compilation).
[EW25508] -
In EWARM 7.40.5:
Preprocessor output of code using any system header file contains references to a built in type_VA_LIST
, making the output less useful for further processing than it should be.
[EW25553] -
In EWARM 7.40.5:
The compiler can fail with errorPe1152
when#pragma weak
is used and multiple source files are compiled together (--mfc
).
[EW25556] -
In EWARM 7.40.5:
Loops with multiple accumulators in the same loop can be incorrectly vectorized.
[EW25574] -
In EWARM 7.40.5:
When compiling for VFP, an assignment between two overlapping homogenous structures containing more than two floating-point numbers can fail.
[EW25576] -
In EWARM 7.40.5:
A read operation of packed short and unsigned short data can give incorrect result if--no_unaligned_access
is used with thumb2 code.
[EW25578] -
In EWARM 7.40.5:
C-RUN: In some cases, 64-bit signed multiplication with overflow checking would produce a positive resultX
when the correct result is-X
.
[EW25587] -
In EWARM 7.40.5:
The optimizer can incorrectly use a value from the initializer of aconst __weak
symbol.
[EW25617] -
In EWARM 7.40.5:
Casting of a function pointer to an integer is now handled properly.
[EW25620] -
In EWARM 7.40.5:
In some cases when a loop copying from (or to) the stack is recognized and rewritten as a call to__aeabi_memcpy
(or__aeabi_memcpy4
), another stack variable is allocated to the same stack location even though they are in scope at the same time.
[EW25663] -
In EWARM 7.40.5:
The optimizations hoist-out-of-if is done in a memory-dependent order. This results in different code generated for small changes of the environment.
[EW25672] -
In EWARM 7.40.5:
When performing heap leak checking and some RAM content is not placed contiguously (for example some RAM content on0x20000000
and some on0x40000000
), the leak checker can incorrectly access memory between the areas. This can result in access violations and/or spurious diagnostics.
[EW25683] -
In EWARM 7.40.7:
In some very rare cases useless instructions could end up in the generated code, making it produce unintended results. This has now been fixed.
[EW25702]
- None.
V7.30 2014-09-24
Program corrections-
The rather naive algorithm for checking whether a symbol is used or not might lead to unexpected warning messages from the compiler.
[EW23132] -
In some cases involving the name of an array in an aggregate initializer with some omitted brackets, the compiler can erroneously warn that the array appears to be unused.
[EW23448] -
The compiler says that it checks MISRA-C:2004 rule 5.4 when it does not.
[EW24679] -
The compiler gets the size of a parenthesised string literal initializer wrong for a variable of unknown array size when clustering is on and the literal is placed as a constant in the code.
[EW24888] -
Loops that can be replaced by a call to
memcpy
,memset
, ormemclr
can, on High, Size optimization, be incorrectly optimized if the loop test contains a post-increment/post-decrement operation.
[EW24928] -
The MISRA-C:2004 rule 9.2 erroneously triggers for an initializer
{0}
for a complex type.
[EW24938] -
The compiler no longer attempts to rename registers within inline assembler instructions.
[EW24942] -
In EWARM 7.30.3:
Instruction scheduling for ARMv7-M results in an internal error when the last instruction in anIT
block is a branching instruction, and there is no other control-flow to the branch target.
[EW24982] -
In EWARM 7.30.3:
MISRA-C:2004 rule 14.2 gives a message for theassert()
macro.
[EW24992] -
In EWARM 7.30.3:
Array expressions where the array address is a known constant value can trigger an internal error when vectorization is enabled.
[EW25012] -
In EWARM 7.30.3:
The compiler can fail to preserve accesses to bitfields where the individual bitfield is declaredvolatile
(as opposed to the entire struct/union being declaredvolatile
).
[EW25020] -
In EWARM 7.30.3:
When designated initializers for members of an anonymous union in EC++/C++ are used in extended language mode, the compiler can erroneously emitError[Pe2358]: a designator for an anonymous union member can only appear within braces corresponding to that anonymous union
if some braces are omitted.
[EW25025] -
In EWARM 7.30.3:
The compiler can terminate with an internal error when achar
array member is initialized with a string literal in a constructor.
[EW25046] -
In EWARM 7.30.4:
On High optimization a loop can be optimized incorrectly, if
1) a variable (V) is assigned the result of a function call,
2) the function call is inlined, and
3) V is used in conditional code that exits the loop with break.
[EW25027] -
In EWARM 7.30.4:
Vectorized code does not handle truncation of right shifts with unknown shift counts correctly.
[EW25061] -
In EWARM 7.30.4:
If vectorization is enabled, an integer variable cast to a pointer type being used as base address for an array access can trigger an internal error.
[EW25067] -
In EWARM 7.30.4:
The MISRA-C:2004 rule 5.3 message is mistakenly issued for atypedef
situated in a header file that is included in two or more source files when compiling in multi-file compilation mode.
[EW25081] -
In EWARM 7.30.4:
static
initialized variables placed in a named section (using#pragma location
or the@
operator) that are not referenced in the module can cause an internal error in the compiler.
[EW25096] -
In EWARM 7.30.4:
When computing the minimum or maximum value in a vector, certain patterns with types of different sizes can trigger an internal error when vectorization is enabled.
[EW25102] -
In EWARM 7.30.4:
If vectorization is enabled, loops containing a shift with a variable shift count can in some cases trigger an internal error.
[EW25104] -
In EWARM 7.30.4:
On the High optimization level, loops where the loop variable is postincremented or postdecremented in the loop condition can be optimized incorrectly if the loop variable has not be assigned in the function.
[EW25124]
- None.
V7.20 2014-05-19
Program corrections-
Setting an alignment higher than 16 in a
#pragma pack
directive can trigger an internal error in the compiler.
[EW24509] -
The
strftime
library function intime.h
cannot be used in AEABI mode. Further,time.h
can not be included in a C++ source module in AEABI mode.
[EW24666] -
In EWARM 7.20.2:
Loops that rely on integer overflow in the step expression can in some cases be incorrectly optimized.
[EW24248, EW24256] -
In EWARM 7.20.2:
A boolean function call can be incorrectly optimized if its result is used in the expression following immediately after the function call, and that expression also contains an indirect access through a pointer.
[EW24710] -
In EWARM 7.20.2:
while
loops andfor
loops with an empty step expression can, in some cases, be incorrectly optimized if the last statement in the loop is another loop.
[EW24742] -
In EWARM 7.20.2:
In EC++/C++, whenstdarg.h
(orcstdarg
) was included before any other standard header,(std::)va_list
was not defined.
[EW24746] -
In EWARM 7.20.2:
In some rare circumstances assignments, to global variables or indirect assignments through pointers, in conditional code can be optimized incorrectly.
[EW24748] -
In EWARM 7.20.5:
Runtime checking for unsigned integer overflow might result in a false positive for pre/post-decrement, due to an intermediate representation as addition with a negative value which in unsigned arithmetic will most often result in overflow.
[EW24763, EW24851, EW24916] -
In EWARM 7.20.5:
In some cases involving syntax errors in string literals, compilation can fail to terminate or terminate with an internal error.
[EW24806] -
In EWARM 7.20.5:
The common sub-expression optimzation sometimes incorrectly changes the inserted bounds checking code into making the compiler produce an internal error.
[EW24849, EW24853, EW24913] -
In EWARM 7.20.5:
A warning message is corrected, changedto complex
intotoo complex
.
[EW24869] -
In EWARM 7.20.5:
When an auto aggregate is partially initialized by solely non-constant values, the compiler fails to emit code to zero-initialize for the remaining parts of the aggregate.
[EW24920] -
In EWARM 7.20.5:
At the medium optimization level, code can be incorrectly optimized around function calls in conditions. An indirect load that occurs on both paths after the condition can incorrectly be performed before the call.
For bitfield assignments, other bitfields in the same bitfield container might be reset to the value prior to the call.
[EW24922]
- None.
V7.10 2014-02-21
Program corrections-
The error messages
Pa053
andPa054
now use ELF terminology.
[EW24093] -
The compiler should issue an error for referring to a struct declared
__packed
if the struct was not defined with__packed
. A warning should be emitted when defining a struct without__packed
, if there was a previous declaration with__packed
.__packed struct X {...} * x;
should not add__packed
to bothstruct X
andx
.
This program correction supersedes the note about the temoporary solution of EW24270 in EWARM 6.70.2, which read "IAR extended type attributes before the type in field declarations in C are incorrectly applied to the type instead of the field."
[EW24270] -
Pre- or post-inc (
++v
orv++
) of a variablev
placed in a global register (using#pragma location
or@
) would result in internal error.
[EW24381] -
Generating code for multiplication in Thumb-1 mode could result in internal error.
[EW24385] -
In some cases, the compiler can terminate with an internal error when reporting an error involving a function.
[EW24387] -
fileno
in the DLIB library will return error status for a legitimite file.
[EW24393] -
The MISRA-C rule 14.10 is not properly checked when using c99.
[EW24402] -
The high part of the old value and the low part of the new value could be loaded from a parameter variable smaller than 32 bits, if the parameter was passed on the stack and later updated in place.
[EW24429] -
The loop counter could incorrectly be wrapped in
memcpy()
for ARMv7-M when building with--no_unaligned_access
for a small unaligned copy, depending on the data being copied.
[EW24432] -
An assigment from a variable of a structure type to itself can in some cases result in writing to memory immediately following the variable location.
[EW24458] -
At medium or higher optimization levels a zero-extend can be hoisted out of a loop when the extended bits are known to be preserved after bitwise logical operations. The optimization is performed also for sign-extend operations, for which the extended bits are not known to be preserved.
[EW24459] -
In a very rare situation, related to static clustering, incorrect code might be generated.
[EW24464] -
In EWARM 7.10.3:
In ARM mode, and in Thumb mode for devices with the Thumb-2 ISA, the backtrace adjustment for the auto-area might be missing or faulty for some rather large sizes of the auto-area. In case this occurrs, C-SPY will show the wrong address for variables placed in the auto-area, for example in the Locals window.
[EW24499] -
In EWARM 7.10.3:
#pragma default_variable_attributes
has no effect on variables with const or volatile type.
[EW24525] -
In EWARM 7.10.3:
MISRA C:2004 rule 14.10 erroneously gives an error for the constructionif (x) f1(); else { if (y) f2(); }
.
[EW24533] -
In EWARM 7.10.3:
The compiler can erroneusly report a non-existing violation of MISRA C 2004 rule 14.10 (finalelse
afterif...else if
) in some cases involving nested if statements.
[EW24545] -
In EWARM 7.10.3:
In some cases the compiler generated code for an expression on the form~x & (y << k)
that corresponds tox & ~(y << k)
. This would occur when anLSL
instruction is replaced by a shifted operand within aBIC
instruction, and the operands of theBIC
instruction are swapped even though it is not a commutative operation.
[EW24548] -
In EWARM 7.10.3:
When generating code for Thumb-2 a test can go the wrong way for unsigned compare less/greater-than (or equal) if one operand is negated and the value for that operand is zero.
[EW24561]
- None.
V6.70 2013-10-29
Program corrections-
On medium and high optimizations, a pointer variable
p
can be optimized incorrectly ifp
is assigned the address of an array element, where the index expression is an other array expression or an indirect load, and the value of the index expression changes between the assignment ofp
and the use(s) ofp
.
[EW24173] -
In EWARM 6.70.2:
When generating code for Thumb1, any stack accesses that either explicitly or through compiler optimizations get a negative offset from SP, will result in an internal error.
[EW24231] -
In EWARM 6.70.2:
Loops containing two or more expressions where the loop variable+/-
a constant offset is multiplied with a loop-invariant expression, might be incorrecly optimized if the constant offset differs between the expressions.
[EW24238] -
In EWARM 6.70.2:
A loop-invariant truncating type conversion could incorrectly be hoisted to a location before a use of the value being converted.
[EW24243] -
In EWARM 6.70.2:
When generating code for VFP in Thumb2, if the program contains a code sequece that selects the smallest of two floating point values the compiler might issue an internal error.
[EW24246] -
In EWARM 6.70.2:
Putting a partial update of a local short variable at the end of a loop body or a conditional block can sometimes make the compiler crash.
[EW24247] -
In EWARM 6.70.2:
A sign- or zero-extend operation can be optimized away if a mask is found that creates a value such that the preceding extend has no effect. This can happen also if the mask depends on the extend operation, which then produces the wrong value when the extend is removed.
[EW24255] -
In EWARM 6.70.2:
CSmith found a problem that makes the compiler generate incorrect code.- A packed struct with padding inside just before a bitfield which only uses a part of its container.
- An initializer to a variable of the struct.
- The compiler can deduce the value from the initializer.
If all of the above occurs, the compiler can propagate the wrong value for the bitfield.
[EW24258] -
In EWARM 6.70.2:
On high optimization, masking assignments, likeg &= 1
used inside an&&
or||
condition might be incorrectly optimized if there are no other uses ofg
inside the function.
[EW24278] -
In EWARM 6.70.2:
Loops with unsigned loop variables that are initialized with negative values might be incorrectly optimized.
[EW24280] -
In EWARM 6.70.2:
Diagnostic column positions can sometimes be incorrect when a complete macro invocation is present earlier on the same line.
[EW24308] -
In EWARM 6.70.2:
In non-strict C89/(E)EC++/C++ modes, unsuffixed integer literals larger thanLONG_MAX
but smaller thanULONG_MAX+1
are incorrectly given a type ofunsigned long
instead oflong long
. In particular, when used in an expression with the prefix-
operator, the result is thus a positiveunsigned long
value rather than a negativelong long
value, as would be expected. Example: -2388135082 becomes 1906832214.
[EW24323] -
In EWARM 6.70.2:
The compiler does not generate stack usage analysis information for some virtual function calls when multiple or virtual inheritance is involved.
[EW24329] -
In EWARM 6.70.2:
For code using C++ pointers to data members, an assertion atlower_il.c
, line 13418 can trigger erroneously.
[EW24331] -
In EWARM 6.70.2:
A MISRA C rule 5.1 (31 significant characters) violation diagnostic message is erroneously emitted for a program making use of the IAR Systems runtime routines__iar_unaligned___aeabi_memmove4
and__iar_unaligned___aeabi_memmove8
.
[EW24337]
- None.
V6.60 2013-06-27
Program corrections-
A pointer parameter, cast to an integer type, used in a switch expression no longer causes an internal error during function inlining.
[EW23758,EW23941] -
An internal error no longer occurs when compiling C++ with VFP support if there is a flow for C++ exceptions to an interrupt function.
[EW23804] -
MISRA-C:2004 rule 5.4 is now supported correctly.
[EW23907] -
In some cases when compiling for Thumb2 the compiler did not sign-/zero-extend a 16-bit value as needed before performing a right shift, if the shift count was not constant. This has been corrected.
[EW23961] -
The compiler does not change the underlying MISRA-C:2004 type for an explicit
C
cast. This can generate erroneous MISRA-C:2004 errors for rules that check against the underlying type.
[EW23988] -
In EWARM 6.60.2:
In a leaf function compiled for Thumb2 at high optimization level, in some cases a comparison between zero and the result of a multiplication could result in faulty code for the comparison if other statements in the function are relatively simple.
[EW24014] -
In EWARM 6.60.2:
Usingmemcpy
to modify the content of an automatic variable of a type shorter thanint
might trigger an internal error in the compiler. Example that triggers the problem:
[EW24037]void f (int *x) { short a; memcpy (&a, 0, 0); if (a == 1 || a == 2) *x = 0; }
-
In EWARM 6.60.2:
In some very rare cases, two compilations of the same file might not produce identical results.
[EW24044] -
In EWARM 6.60.2:
Reading a 16-bit value from an unaligned source, such as a pointer to packed structure, casting it to the opposite signedness and then casting it to a 32-bit value might produce invalid code.
[EW24066] -
In EWARM 6.60.2:
assert()
now generates a message. Note, the behaviour is changed in 6.60.2, read more in Release notes for the IAR C-SPY Debugger for ARM.
[EW24102] -
In EWARM 6.60.2:
Specifying a non-static member function in#pragma
calls results in error Pe028 (expression must have a constant value).
[EW24137] -
In EWARM 6.60.2:
When mangling template names, IAR Systems type qualifiers, like__packed
, in template type arguments are not taken into account, which can lead to internal errors in the compiler, errors when linking, or silent use of the wrong code. Example:Given the template
The bug leads to problems if the same template is instantiated in such a way that the only difference is in type qualifiers in its template type arguments. Memory qualifiers are correctly taken into account.template<typename T> struct X;
bothX<int>
andX<int __packed>
get the same mangled name.
[EW24140] -
In EWARM 6.60.2:
A left-shift of a masked result (bitwise AND) of a signed right-shift can sometimes be expressed without the right-shift. If the optimization is correct it might still not be performed depending on the order between addresses allocated by the OS.
[EW24143]
Advanced heap update
Available functionality of the advanced heap is listed inarm\inc\c\iar_dlmalloc.h
. The statistic functions of the advanced heap can be used through this header file.
V6.50 2012-11-10
Program corrections-
The calculation of leap days was incorrect in the time system in the library. This has been corrected.
[EW23273] -
In some rare cases the compiler could end up in an infinite loop. This has been corrected.
[EW23308, EW23573] -
The compiler no longer terminates with an internal error when
--macro_positions_in_diagnostics
is used.
[EW23337] -
Incorrect code was generated for varargs constructors in some cases. This has been corrected.
[EW23358] -
The compiler now generates useful stack backtrace also for a non-returning interrupt function.
[EW23363] -
The underlying type for the
__section_size()
(and its alias__segment_size()
) operator was erroneous. This could lead to, for instance, MISRA-C:2004 rule10.1 errors if that operator was used. This has been corrected.
[EW23390] -
The function prologue/epilogue for an interrupt function (
__irq
or__fiq
) now stores/restores also the VFP registersD16
through toD31
, when available.
[EW23418] -
The compiler now generates correct debug information for variables placed on the stack in functions ending with an infinite loop.
[EW23422, EW23439] -
If error
Pa128
(truncating cast in constant expression) was suppressed or turned into a warning when casting from a pointer to a smaller integer, the compiler aborted with an internal error. This has been corrected.
[EW23444] -
Accesses to volatile auto structs could be incorrectly optimized. This has been corrected.
[EW23458] -
Combinations of left shifts, right shifts, multiplications with a power of 2, and divisions with a power of 2 in array index expressions could be incorrecly optimized. This has been corrected.
[EW23526] -
An indirect expression through an initialized global or static
const
pointer could be optimized incorrectly. This has been corrected.
[EW23543] -
An array index expression could be incorrectly optimized if the index expression was used in a loop (L), and if a variable (V) was assigned a value that was invariant in L, and V occured multiple times in the index expression.
[EW23571] -
In EWARM 6.50.2:
In some rare cases a static or global variable in nested loops could be optimized incorrectly if an inner loop contained potential aliasing, for example as a function call or indirect accesses, and the variable was modified in both the inner loop and the outer loop. This has been corrected.
[EW23566] -
In EWARM 6.50.2:
Patterns where a pointer to a pointer was used in pointer arithmetics no longer trigger an internal error.
[EW23579] -
In EWARM 6.50.2:
Accesses where the address of an array is cast into a pointer to a data type larger than the element type and several array elements are accessed at once, no longer trigger an internal error.
[EW23581] -
In EWARM 6.50.2:
For Cortex-M4F, the standard library calllongjmp
now restores the VFP registers correctly.
[EW23583] -
In EWARM 6.50.2:
The__iar_Mutex
no longer allocates a lock in the normal library.
[EW23584] -
In EWARM 6.50.2:
An address of an auto variable cast tovoid
no longer trigger an internal error.
[EW23602] -
In EWARM 6.50.2:
Right shift (arithmetic as well as logic) no longer cause theZeroExt
property to become negative.
[EW23613] -
In EWARM 6.50.2:
The filesdata_init.c
(replacingdata_init3.c
) andrle_init.c
(replacingrle_init3.c
) are no longer missing from the IAR Embedded Workbench installation.
[EW23616] -
In EWARM 6.50.3:
Partial assignments in the initialization of loop variables could trigger an internal error. This has been corrected.
[EW23634] -
In EWARM 6.50.3:
In ARM mode, a signed comparison of a shifted value with 0, for example(x >> 16) < 0
, could result in an internal error. This has been corrected.
[EW23665] -
In EWARM 6.50.3:
The media instructionSMMUL
was incorrectly generated for unsigned (zero-extended) operands. This has been corrected.
[EW23682] -
In EWARM 6.50.3:
The header fileinit_streams.h
is now included in the library source code shipped with the full product.
[EW23709] -
In EWARM 6.50.3:
Now the MISRA-C:2004 rule 12.7 uses the underlying type to determine whether the rule has been violated.
[EW23717] -
In EWARM 6.50.4:
An indirect assignment could be optimized incorrectly if the right hand side expression was masked with a constant and the only use was in a test, comparing the value, possibly masked with the same constant as in the assignment or a constant with fewer bits set, to zero. For example:
p->foo = x & 0x02;
...
if (p->foo & 0x02)
This has been corrected.
[EW23796] -
In EWARM 6.50.4:
Loops that contains indirect assignments where the address expression consists of both loop dependent variables and loop invariant variables could be optimized incorrectly if the loop was followed by an assignment to the same address expression. This has been corrected.
[EW23815] -
In EWARM 6.50.6:
When compiling for Thumb2 with High optimization level (-Oh
,-Ohs
, or-Ohz
), if the value of aswitch
expression had additional uses after it was evaluated, these uses could in some rare cases yield some other value.
[EW23873] -
In EWARM 6.50.6:
When using a string literal to initialize an array and the string literal contained too few bytes, the compiler did not initialize the last bytes of the array properly. The missing bytes were read from after the string literal. This has been corrected.
[EW23891]
- None.
V6.40 2012-06-05
Program corrections-
Using 16-bit and 8-bit integer variables as bitfields no longer causes an internal error.
[EW22858] -
In some rare cases the compiler could loop when compiling a signed expression containing multiple shifts. This no longer happens.
[EW22896] -
Using multi-file compilation,
--mfc
, with files that use inline assembler statements could result in an internal error.
[EW22905] -
In some rare cases the stack frame of a function could be optimized in such a way that the debug information would be erroneous (off by four, for example). This means that in the debugger, a stack variable could appear to reside in some location which will probably not hold the expected value. This no longer happens.
[EW22907] -
A module containing a pointer to a member function constant for a virtual function could in some cases result in a
symbol_lookup_M31
internal error in the compiler for the typeinfo object for the owning class.
[EW22918] -
A volatile load could incorrectly be removed if it was part of an expression that was shifted so far that none of the bits from the load were used.
[EW22974] -
An
asm
statement following immediately after a constructor call caused an internal error.
[EW22982] -
A Common subexpression elimination (CSE) was erroneously lifted due to faulty bitfield handling. This has been fixed.
[EW22988] -
Fixed a problem with using
#pragma call_graph_root
on a__weak
function definition. In Thumb mode, the result was an internal error in the compiler. In Arm mode, the result was that the linker in some cases used a section symbol (something like.text_17
) instead of the function symbol for these functions.
[EW22996] -
An
asm
statement containing a local label in a function in a module where the function is inlined twice produced an internal error. This has been fixed.
[EW23006] -
The compiler no longer generates
IT
instructions insideIT
blocks, which caused an internal error.
[EW23020, EW23083] -
Using the address of a C99 compound literal to initialize a pointer in an aggregate caused an internal error in the compiler.
[EW23021] -
In some rare cases partial accesses were incorrectly optimized.
[EW23028] -
The compiler had a bug that could cause the display of stack-allocated local variables to be incorrect in debuggers other than C-SPY.
[EW23042, EW23047] -
Now an
unsigned long
to anunsigned int
cast in a static initializer does not generate an error.
[EW23054] -
The compiler, the linker, and the elftools returned error status when run without options. This has been fixed.
[EW23057] -
The cross call optimization could not handle a sequence that started with a label and had one back-jump to that label in the sequence and one back-jump to it after the sequence. This has been fixed.
[EW23063] -
Inline assembler expressions with volatile arguments could fail in register allocation.
[EW23086] -
In some cases a common subexpression could be hoisted across a condition controlling the execution of the expression.
[EW23087] -
Index expressions mixing signed and unsigned types could in some rare cases cause an internal error.
[EW23088] -
The compiler could erroneously inline
__weak
function definitions.
[EW23112] -
C-SPY no longer generates an error when the debugged application contains a C symbol with the name c or d.
[EW23131] -
The choice of using the 64-bit implementation for the time interface did not work when using low optimization levels. This has been fixed.
[EW23162] -
The compiler issued an internal error when checking the code
(void (**)(void)) 1
for violation of the MISRA C:2004 rule 17.5. This has been fixed.
[EW23164] -
The linker now selects the correct libraries when linking an application without code, also for Cortex-M devices.
[EW23204] -
For Thumb2, at optimization level Medium, expressions of the form
(x >> K) & M
could result in code that cleared too many bits (for a constantK > 0
andM = (1 << N) - 1
for a constantN > 0
).
[EW23214] -
The endian attribute for pointers and arrays is now supported in the compiler, which makes this issue obsolete.
[EW23220] -
Fixed a pathological case where a static variable used as index expression in a static array could trigger an internal error.
[EW23229] -
In EWARM 6.40.2:
TheLDRD
instruction could be used for copying an 8-bytestruct
with less than 4-byte alignment, which could result in an exception (hard fault) when running the application. This no longer occurs.
[EW23272] -
In EWARM 6.40.2:
When compiling for Thumb2, a zero-initializer for a single byte array on the stack no longer generates code that clears two bytes of memory.
[EW23298] -
In EWARM 6.40.3:
A bitwise AND (&
) between an 8-bit variable and a constant wider than 8 bits does no longer generate an internal error.
[EW23295, EW23362, EW23365] -
In EWARM 6.40.3:
In some rare cases multiple tests of the same variable could be incorrectly optimized. This has been corrected.
[EW23360] -
In EWARM 6.40.3:
At optimization level medium (or higher), the updates of an address passed to the__PLD
or__PLI
intrinsic functions could be optimized away. This has been corrected.
[EW23387] -
In EWARM 6.40.4:
Loops with multiple exit tests (a test containing&&
or||
counts as multiple tests) could be optimized incorrectly, if one test tested a loop counter, another test tested a value loaded indirectly from a pointer, and the pointer was incremented or decremented on each iteration through the loop.
[EW23318]
Inline assembler
New operand constraints and modifiers.CMSIS update
CMSIS version 3.01 is now included in the product.
V6.30 2011-10-22
Program corrections-
The diagnostic messages now refer to the correct rule numbers when MISRA C 2004 is chosen.
[EW22347] -
The underlying type of a constant expression is now evaluated as for any other expressions. This deviates from the specific constant expression rule in MISRA-C:2004 6.10.4. Both IAR Systems and the MISRA-C committe feels that this rule doesn't reflect the intention.
[EW22373] -
Initalizing a member
char
array with a string literal in a class constructor no longer results in an internal error.
[EW22503] -
The intrinsic function
__REV16
is now available when compiling for Cortex-M0.
[EW22715] -
Complement
~
of an unsigned expression is no longer optimized incorrectly when the expression contains a right shift or a bitwise and with a constant.
[EW22725] -
C++ temporary objects needed when initializing file-scope and namespace-scope variables are now created properly.
[EW22751] -
A signed test for less than, less equal, greater than or greater equal on an expression that is shifted immediately before the test now gives correct result.
[EW22752] -
In EWARM 6.30.3:
Using the__packed
attribute in situations that involve template functions no longer causes an internal error.
[EW22776] -
In EWARM 6.30.3:
On the high optimization level, a mix of signed and unsigned values in complex array index expressions no longer causes an internal error.
[EW22787] -
In EWARM 6.30.3:
Passing a constant as argument to an intrinsic function that inserts a specific assembler instruction no longer causes an internal error in C++ mode.
[EW22808] -
In EWARM 6.30.3:
In rare cases the induction variable optimization could cause an internal error. This has been corrected.
[EW22815] -
In EWARM 6.30.3:
Using the multi-file compilation option--mfc
with one or more zero-size source files no longer causes the compiler to terminate with an internal error.
[EW22828] -
In EWARM 6.30.3:
The debug information in ELF files now refers to the correct source file name when the command line option--preinclude
is used.
[EW22848] -
In EWARM 6.30.3:
When some diagnostics (in particular, the undefined behavior warnings about unordered accesses etc) were triggered on uses of fields in a block-local anonymous struct/union variable, the compiler aborted with an internal error. This problem has been corrected.
[EW22850] -
In EWARM 6.30.3:
The thread-exit function now correctly deallocates the potentially allocated daylight saving time structure.
[EW22862] -
In EWARM 6.30.3:
An instructions inside an IT-block is no longer a candidate for dead-code removal, since removing it will leave the IT-instruction inconsistent.
[EW22864] -
In EWARM 6.30.5:
Common subexpression elimination (CSE) could go wrong in rare cases when equivalent bitwise or-expressions occurred at multiple locations, and at least one but not all were rewritten as a bitfield instruction. This no longer happens.
[EW22932] -
In EWARM 6.30.6:
A function containing two? :
expressions (or equivalentif
statements) with identical tests where two different variables were assigned the same values could be optimized incorrectly if the first variable was reassigned in the basic block following the? :
expression. This has been corrected.
[EW22965] -
In EWARM 6.30.6:
The compiler could incorrectly optimize the expressionuchar = ~0 (int & 1)
. This has been corrected.
[EW22972] -
In EWARM 6.30.8:
Some assignments could be incorrectly optimized if the left-hand side was an indirection (through a pointer or reference) or a global or static variable and the right-hand side was a function call. Exceptions thrown from those calls were not correctly handled.
The optimization intra cross jump did not always create correct code when one of the sequences it tried to optimize was exception code. This has been fixed.
[EW23094, EW23185] -
In EWARM 6.30.8:
Range checks, such as((unsigned char) x)-48 < 10
, could sometimes be performed without zero-extending the variablex
.
[EW23141]
- None.
V6.21 2011-07-05
New features- None.
-
Location information (from
#pragma location
or the@
operator) now carries over properly from a function declaration to the function definition.
Example:
int foo(void) @ "XXX";
The function
int foo(void) { return 1; }foo()
should be placed in the sectionXXX
, but it was not.
[EW22448] -
Redeclaring
main
with non-matching location strings and suppressing the resulting error caused an internal error in the compiler. Now the error cannot be suppressed in this situation.
[EW22450] -
Commutative operations with multiple constants are no longer optimized incorrectly even if one or more of the operations is of a smaller type.
[EW22470, EW22484] -
For a nested interrupt handler,
LR
is now adjusted.
[EW22472] -
String literals in inline and template functions were turned into non-const variables. Now the variables are
const
instead, and end up in ROM, the way they should.
[EW22475] -
Corrected an internal error.
[EW22479] -
In EWARM 6.21.4:
For certain small switch statements the compiler generated different code for different invocations. This has been fixed.
[EW22520] -
In EWARM 6.21.4:
In some rare cases a store to a struct member in an auto object was optimized incorrectly if the object member was read once before the address of the object was passed to a function.
[EW22537] -
In EWARM 6.21.4:
The compiler now avoids widening partial definitions.
[EW22539] -
In EWARM 6.21.4:
When the Thumb-1 instructionADD.N Rdn,Rdn,SP
is widened the equivalent Thumb-2 instructionADD.W Rdn,SP,Rdn
is used, sinceADD.W Rdn,Rdn,SP
is unpredictable.
[EW22555] -
In EWARM 6.21.4:
The compiler no longer places too many constants or string literals between a branch and its target, which for a Thumb-1 function whereLR
is not pushed could result in "Internal error: Jump distance to far for B".
The compiler also no longer places too many constants or string literals between anADR
instruction and its target, which could result in "Internal error:[AsmLine - OgAsm]: Error[400]: Expression out of range".
[EW22611] -
In EWARM 6.21.4:
The compiler no longer crashes when compiling a reference toASR
,LSR
,LSL
,ROR
, orRRX
.
[EW22614]
V6.20 2011-04-29
New featurestime.h
has an optional 64-bit interface that supports years from -9999 up to 9999. For more information see the Development guide.
-
When compiling a C file with the
--use_c++_inline
option, the C99 rule that a public inline function definition cannot reference functions or variables with internal linkage is no longer checked.
[EW22161] -
Loops where the final statement in the loop body is a switch will no longer trigger an internal error on High optimization.
[EW22183] -
The C++ C system headers (
errno.h
, etc) can now be included inside anextern "C"
block.
[EW22188] -
A
while
loop with multiple returns in the loop body will no longer trigger an internal error.
[EW22195] -
Now the compiler can handle macro parameters that contains multibytes.
[EW22214] -
Compilation of modules with a very large number of constant data symbols is now considerably faster.
[EW22243] -
When the
offsetof
macro is used in a macro argument for a user-defined macro, the compiler no longer produces unwanted warnings about the contents of theoffsetof
macro.
[EW22250] -
The symbol
__vector_table
is now included when linking with the filearm\src\lib\thumb\cstartup_M.c
delivered with the product.
[EW22252] -
The compiler now correctly handles multibyte characters in a comment and the source line splice mechanism.
[EW22276] -
The unrolling of a one-trip loop with multiple tests and empty loop body now works also when the second test is used to determine that only one iteration of the loop shall be executed.
[EW22295] -
Complex expressions involving left-shifts and subtractions will always be optimized correctly.
[EW22306] -
In some cases the compiler could generate a Thumb-2
ADD
instruction with negative 8-bit immediate, which the assembler would convert to a narrowThumb-1SUB
instruction. This has been corrected.
[EW22308] -
MISRA C rules were erroneously applied to the constant expression for the address in a
#pragma location
or after the@
operator, resulting in spurious diagnostics when MISRA C checking was enabled. This has been corrected.
[EW22321] -
The compiler no longer produces an internal error when generating code for Thumb-2 and trying to split a 64-bit store into two 32-bit stores (for example due to alignment) when the address operand is of the form
[<Rn>,<Rm>,#<imm>]
.
[EW22324] -
Now the compiler can produce an error for a nonstandard implicit cast of a function to a pointer-to-member.
[EW22337] -
Trampoline functions
__iar_via_rw_<Rn>
are now generated as a writable section fragment, so that__ramcode
functions can be used also in cases were such a function is needed.
[EW22346] -
In EWARM 6.20.2:
The compiler no longer exits with internal error when optimizing conditional jumps.
[EW22404] -
In EWARM 6.20.2:
For cores with media extensions, the compiler no longer generatesADD
instead of{S,U}XTA{B,H}
.
[EW22407] -
In EWARM 6.20.2:
The compiler no longer reports internal error when generating code for Thumb-2 and trying to split a 64-bit load into two 32-bit loads (for example due to alignment) when the address operand is of the form[<Rn>,<Rm>,#<imm>]
.
[EW22415] -
In EWARM 6.20.2:
In static initialization of a structure or an array of structures, fields following an unnamed bit-field no longer get incorrect values.
[EW22416] -
In EWARM 6.20.2:
The compiler erroneously issued warning Pe021 (type qualifiers are meaningless in this declaration) when using the keyword__packed
on a struct or class definition.
[EW22417] -
In EWARM 6.20.2:
Loops withgoto
statements no longer trigger an internal error for any case.
[EW22420] -
In EWARM 6.20.2:
The compiler no longer abort with an internal error for aggregate initializers consisting entirely of constant integers in some cases involving non-integer, non-aggregate types nested more than two levels down in the unspecified parts of the initializer.
[EW22424] -
In EWARM 6.20.3:
When generating Thumb-2 code, access to 32-bit floating point values on a large stack frame no longer causes internal error.
[EW22439] -
In EWARM 6.20.3:
Pointer constants involving a cast from an integer could get an incorrect type, leading to spurious errors or internal errors. This has been corrected.
[EW22441]
V6.10 2010-11-04
New featuresThe product now uses the current C standard defined in 1999, known as C99, as the default C language. The previous major version of the product used the former C standard defined in 1989, known as C89. C89 can still be used in the compiler by using the
--c89
option. The product will not be totally backwards-compatible though, because the support for some C99 features has been withdrawn. Variable length arrays, VLAs, in C99, are not supported in the default C language. They can be enabled with the option--vla
. The C library supports all C99 functionality, and more, but only if used with the C99 language or with any C++ language. If used with the C89 language, C99-added functionality will not be allowed.The implementation of EC++ and EEC++ has not changed in any major way.
Support for the C++ language has been added. By default, it fully supports the 2003 C++ standard, but can be used with exceptions and/or runtime type information disabled by using
--no_exceptions
and--no_rtti
respectively.Thread-safe libraries
The DLIB library now supports being used in a threaded environment. Some library systems, like the heap and the file structure, will be guarded by locks. Other library systems, likelocale
anderrno
, will have their static data allocated in thread-local storage. The DLIB thread support can either be supported by your chosen RTOS or can be manually implemented. For more information see the Development guide.The compiler and assembler now automatically know where the library's system headers reside. You can control the compiler using the options:
--dlib_config
, to choose a configuration in the DLIB library.--system_include_dir
, to override the directory to use as system header base.--no_system_include
, to turn the automation off.
The compiler can now optimize some floating-point expressions more agressively by using the option
--relaxed_fp
. If enabled, the compiler tries to reduce the floating-point type used in floating-point expressions. This can cause a small loss of accuracy.
-
The library function
fpclassify()
handles normal and subnormal numbers correctly.
[EW21098] -
Small
memcpy
calls are no longer transformed to assignments unless both the source and destination addresses have correct alignment.
[EW21193] -
The compiler now checks that different kinds of variables are no placed in the same section.
[EW21351] -
An internal error should no longer occur if
__segment_begin()
or__segment_end()
is used in conditional code.
[EW21770, EW21838, EW21905] -
Loops that decremented an unsigned loop counter past zero could in some cases be incorrectly optimized.
[EW21795] -
Now all system headers do not generate MISRA errors.
[EW21799] -
When optimizing, the the compiler now handles an initializer containing a function pointer with an offset.
[EW21870] -
The endian attribute is not supported for pointers or arrays. Now an endian attribute can no longer be specified for pointers or arrays.
[EW21887] -
Reversal of byte order is now correctly performed also for combinations of endian attributes and unaligned accesses. Previously, this was in some cases not handled.
[EW21888] -
At optimization level High, speed-optimizing small loops similar to
could in some cases be incorrectly unrolled and cause an internal error.int test(int n) { while (n-- > 0) if (!foo(n)) break; return n; }
[EW21949] -
A class with a member that is a nameless struct, or an array of nameless structs, where at least one of the members is not a PoD, could cause an internal error while compiling.
[EW21958] -
A while loop with a preincrement or predecrement in the loop test could be incorrectly optimized if the final part of the loop body was a do loop.
[EW21999] -
The compiler will no longer merge instruction sequences (through cross call or cross jump optimizations) that are not equal, due to the register operand of a Thumb-2 compare-and-branch instruction (
CBZ
orCBNZ
).
[EW22000] -
When an
enum
is specified as a parameter or return type before it has been defined, the compiler will no longer record the wrong num size (attributeTag_ABI_enum_size
) in the ELF file.
[EW22013] -
In Thumb-2, the compiler no longer issues an internal error in an attempt to widen
MULS.N
toMULS.W
(which is not a Thumb-2 instruction) to achieve a 4-byte alignment of a following instruction or label.
[EW22018] -
The compiler can now handle a function symbol as an argument to compiler optimized functions like
memcpy
.
[EW22052] -
In EWARM 6.10.2:
Nestedfor
loops where the inner loop's initial or final value was the outer loop's variable, multiplied with a constant scaling factor or with a constant offset, no longer causes an internal error on high optimization.
[EW22078] -
In EWARM 6.10.2:
Somewhile
loops with multiple exits no longer causes an internal error on high optimization.
[EW22080] -
In EWARM 6.10.2:
Constant data is now placed in the.rodata
section if the compiler has not generated a directADR
reference. If there is anADR
reference, the constant data is placed in the.text
section.
[EW22081] -
In EWARM 6.10.2:
Standard C++ is now enabled also for the kickstart products.
[EW22089] -
In EWARM 6.10.2:
Now the MISRA-C:2004 rule 20.2 checker can handle a long preprocessor symbol define.
[EW22117] -
In EWARM 6.10.2:
For Cortex-M3, the compiler no longer attempts to generate a sub-routine for identical instruction sequences (cross-call) that end with a call to a software interrupt function (SWI
), which would result in an internal error.
[EW22118] -
In EWARM 6.10.2:
The compiler no longer removes code that uses the result of anSTREX
instruction (the instruction can be generated by using the__STREX
intrinsic function).
[EW22119] -
In EWARM 6.10.2:
The compiler no longer uses a signed 16-bit value as the immediate operand for theMOVT
instruction. A 16-bit unsigned value is used instead, becauseMOVT
expects an immediate value between 0 and 65535.
[EW22121] -
In EWARM 6.10.2:
Evaluating a function address without using the result no longer causes an internal error.
[EW22146]
V5.50 2010-04-21
New features-
The following C library floating-point functions, for devices without VFP, have been optimized for speed and size:
sqrt
,sqrtf
,modf
,modff
,fabs
,fabsf
,fmod
,fmodf
,floor
,floorf
,ceil
,ceilf
,ldexp
,ldexpf
,frexp
,frexpf
. -
The following C library floating-point functions, for devices with VFP, have been optimized for speed and size:
sqrt
,sqrtf
,modf
,modff
,fabs
,fabsf
,fmod
,fmodf
,floor
,floorf
,ceil
,ceilf
,ldexp
,ldexpf
,frexp
,frexpf
,asin
,asinf
,acos
,acosf
,atan
,atanf
,atan2
,atan2f
.
-
While optimizing a function that contained code that prevented the end of the function to be reached, the compiler would erroneously leave a label after the last reachable instruction. This label was later interpreted as a leak of flow-of-control out of the function and an internal error was generated.
[EW21541] -
A call to the map index operator now default-constructs the value if the key is not found even for base types.
[EW21592] -
Using designated initializers (a C99 feature available in EC++ when IAR extensions are enabled) with a static storage duration object that needed C++ dynamic initialization could cause incorrect initialization.
[EW21649] -
The use of intrinsics for
LDC
andSTC
could in some cases crash the compiler (access violation).
[EW21657] -
A function,
f
, updating a global variable, could be incorrectly optimized, if
f
had multiple return statements,- at least one of the return statements was inside a loop, and
f
was inlined in another function.
-
For a function call where the compiler inserts a call to
memcpy
to construct a stack parameter, the registerR1
is no longer assumed to survive the call tomemcpy
.
[EW21668] -
The compiler no longer generates unaligned memory accesses for Cortex-M0.
[EW21687] -
The compiler no longer generates branch instructions without size specifiers (
.W
or.N
) for Thumb-2 capable cores (in Thumb mode), because doing so sometimes could result in an internal error.
[EW21699] -
In EWARM 5.50.5:
Using an enumerator constant directly as a floating-point value no longer produces a corrupt value.
[EW21704] -
In EWARM 5.50.5:
Array pointer decay of a block local static array with template parameter dependent size no longer results in an internal error.
Example:
template
[EW21728]struct Q { C * get() { static long x[sizeof(C)]; return (C *)x; } }; -
In EWARM 5.50.5:
The instruction scheduling for ARM11 no longer issues an internal error when scheduling aPKHBT
instruction with a shifted operand.
[EW21745] -
In EWARM 5.50.5:
TheUSAT
instruction (for unsigned saturation) is now generated with correct bitwidth also in Thumb-2 mode (was off by one).
[EW21768] -
In EWARM 5.50.5:
Cast fromdouble
tolong long
no longer generates faulty values for very large inputs with a non-zero fractional part. Values in the range [2^32, 2^52] were affected.
[EW21786] -
In EWARM 5.50.5:
An internal error no longer occurs for conditions where the test is a? :
expression on the form:
if ((condition1 && condition2) ? 1 : 0)
[EW21807] -
In EWARM 5.50.5:
Range checks for the address of a function parameter is now translated correctly: it could earlier in some cases result in internal error.
[EW21826] -
In EWARM 5.50.5:
The compiler is now able to inline a function that in its body calls a function with the__noreturn
attribute.
[EW21841] -
In EWARM 5.50.7:
An internal error is no longer issued when multiple constant-table references are placed in the same IT-block for a function that is so large that anLDR (immediate)
instruction cannot reach outside the function.
[EW21968] -
In EWARM 5.50.7:
Loops that contain conditional accesses through an invariant pointer variable are no longer incorrectly optimized.
[EW21992] -
In EWARM 5.50.7:
A signed division of an expression with a negative divider no longer gets optimized into using an unsigned division.
[EW22043]
V5.41 2009-12-14
New features- None.
-
cstartup_M.c
now includes default interrupt handlers.
[EW21314] -
Expressions on the form
if (expr < 0) v = -expr;
are no longer optimized incorrectly.
[EW21340] -
A test inside a loop is no longer optimized incorrectly if
a) the loop had constant values for the initial and the final iteration,
b) the test compared an expression to a constant, and
c) the calculation of the expression would overflow or underflow for either the initial or final iteration.
[EW21363] -
Complex |-expressions no longer cause infinite loops during optimization.
[EW21380] -
Registers might be spilled to the stack frame when there are more live variables than registers. A spilled large register parameter (more than 8 bytes) no longer results in an internal error.
[EW21386] -
The linker is now more relaxed concerning attribute checking when linking with explicitly specified libraries.
[EW21387] -
Absolute addressed variable accesses no longer loose the
volatile
attribute during optimization.
[EW21400] -
Debug information for classes inheriting from a base class whose primary base was inherited virtually is no longer generated incorrectly. The old problem could result in incorrect display of base classes in C-SPY.
[EW21411] -
An error from the assembler in inline assembler code is no longer reported as a compiler internal error.
[EW21436] -
The compiler now encodes the character value 255 in a string literal using an escape sequence, to work around the fact that the assembler interprets such a value as end of file.
[EW21443] -
Registers are no longer renamed in situations where unused registers become used after renaming, to avoid situations where such registers would not be saved on the stack.
[EW21449] -
The compiler now generates correct code instead of reporting an internal error in situations where an entry in a constant table is duplicated so that it can be reached by all its references.
[EW21471] -
In EWARM 5.41.2:
Integral expressions in loops are no longer optimized incorrectly when the expression adds or subtracts a constant to/from a variable(x + ... + C)
, and the variable is assigned the same constant subtracted/added from/to the loop index variable(x = i - C)
.
[EW21493] -
In EWARM 5.41.2:
Two tests on the form
expr1 > c1 && expr2 < c2
or
expr1 < c1 || expr2 > c2
are no longer incorrectly optimized as a range test whenexpr1
is not identical toexpr2
.
[EW21498] -
In EWARM 5.41.2:
A bitwise and operation between a constant and a value loaded from memory will sometimes be transformed into a truncated load, which loads only a part of the variable from memory. For a 64-bit variable (in other words,long long
) the truncated load will no longer result in an internal error.
[EW21517] -
In EWARM 5.41.2:
Complex array index expressions in loops no longer result in an internal error.
[EW21545] -
In EWARM 5.41.2:
Types smaller that 32 bits must sometimes be sign- or zero-extended before being compared (using for exampleCMP
,TST
, orTEQ
). Sign- and zero-extends are now generated when needed also for cases when the result of bitwise and/xor operations are compared with zero (in other words, cases for which aTST
orTEQ
instruction is generated).
[EW21550] -
In EWARM 5.41.2:
Correct values are now produced when the intrinsics__CLZ
,__REV
, or__REVSH
are used with a constant argument.
[EW21561]
V5.40 2009-07-10
New features- None.
-
An if-then-else statement could be optimized into a question mark expression even at low optimization levels, which would make the debugger confused as to which is the current statement. The optimization has now been disabled at optimization levels 'low' and 'none'.
[EW20828] -
The compiler no longer generates a message for the usage of
long long
in system headers even though the options--strict_ansi
and--warnings_are_errors
are used.
[EW20844] -
The final value of variables in loops transformed into a
memcpy
ormemset
call could, in some cases, be off by one.
[EW20886] -
Fixed an internal error in the compiler when trying to match an out-of-line template member function definition to the correct declaration. The problem occurred when two or more template member functions differed in the this qualifiers of a pointer to member function type parameter.
Example:
[EW20920]struct X { template
int fun(Y (Z::*fp)()); template int fun(Y (Z::*fp)() const); }; template int X::fun(Y (Z::*fp)()) { return 1; } -
The MISRA C error
Pm020
was incorrectly reported as a warning and the corresponding rule number was omitted from the error message.
[EW20925] -
When compiling multiple input files (
--mfc
) in Embedded C++ mode, the compiler could get an internal error[assertion failed at: ".\src\parser\edg\lower_il.c", line 2484]
in some circumstances.
[EW20927] -
Loops where a global variable (
g
) just held a result (g
passed no value between loop iterations) could in some cases be incorrectly optimized.for (...) { g = ... if (...) break; g = ... }
[EW20952] -
The compiler and assembler produced object files where group section header table entries did not appear before the entries of all their members, as required by the ELF format.
[EW20988] -
After a
memcpy
call, where a buffer (b
) was assignedn
characters from a string literal of lengthn
(all characters except the zero termination), ab[n] = 0
assignment could erroneously be removed.
[EW20991] -
Associative expressions containing both a division and a modulo operation could in some rare cases be incorrectly optimized.
[EW21010] -
When compiling EEC++ for Thumb, a class that inherits from three or more classes where a virtual method has three or more arguments, one of the generated thunks was faulty (when compiling with multiple inheritance there is sometimes a need for a piece of code that adjusts the 'this' pointer. This piece of code is known as a 'thunk').
[EW21014] -
For a struct
x
of 8 bytes or more, allocated as a register variable with two fieldsa
andb
, a simple if statement that can be reduced to a question mark expression (such asx.a < x.b ? x.a : x.b
) could result in an internal error.
[EW21017, 21108] -
Member accesses to auto structs assigned with
memcpy
could in some cases be incorrectly optimized.
[EW21020] -
When compiling for VFP, a function call with a variable argument list where an argument passed on the stack is converted from
double
toint
could result in an incorrect stack pointer value.
[EW21023] -
When compiling with
--legacy RVCT3.0
for Thumb mode, and a constant is shared between functions of the same compilation unit, the compiler could in some cases generate one of the functions in a segment part with two bytes alignment. Four bytes alignment is required in such cases to correctly resolve theR_ARM_THM_PC8
relocation.
[EW21031] -
The code generator could fail to detect that an object had been placed with stricter alignment than required by the type. This would, in turn, cause the compiler to crash when the code generator at a later stage expected the higher alignment.
[EW21059] -
When a switch statement inside a loop is generated as a table with negative offsets, the same register could be reused for two different purposes at table lookup.
[EW21100] -
The compiler could terminate with an internal error in some cases involving enum types defined in a template class.
[EW21101, 21112] -
When optimizing loops where the loop limit is the result of an expression involving possibly negative values in a bitwise AND operation, the compiler could in some cases erroneously conclude that the loop body would execute at least once and eliminate the test of the initial iterator value against the limit. The result of this is incorrect loop code for the case when the loop body should not be executed at all.
[EW21118,21120] -
In EWARM 5.40.4:
The runtime library no longer assumes that unaligned access is supported in Cortex-M0 or Cortex-M1.
[EW21262] -
In EWARM 5.40.4:
Scalar stack parameters smaller than 32-bit are now properly sign- or zero extended before the function is called.
[EW21271] -
In EWARM 5.40.4:
Compilation of a file using either of the intrinsics__get_interrupt_state
or__set_interrupt_state
no longer results in an internal error.
[EW21272] -
In EWARM 5.40.4:
MISRA C is now available in EWARM-CM.
[EW21324] -
In EWARM 5.40.4:
The compiler now generates correct debug information for calls to C++ member functions defined in another module. The step into debugger command for such a call now works properly.
[EW21327]
V5.30 2009-01-23
New features- __task extended keyword
By default, functions save the contents of used preserved registers on the stack upon entry, and restore them at exit. Functions that are declared__task
do not save all registers, and therefore require less stack space. This is typically used by realtime operating systems.
-
Creating a variable with a class/struct/union type with type errors in one or more of its fields could earlier result in an internal error. This has been corrected.
[EW20367] -
In some unusual cases the compiler could terminate ungracefully. Ungraceful terminations are now prevented.
[EW20380] -
Stack usage reported in the listfile is now again a safe approximation.
[EW20410] -
In some cases two pre/post increment/decrements in two consecutive expressions could cause an internal error. This problem has been corrected.
[EW20419] -
Irregular loops could in some rare cases be optimized incorrectly. This problem has been corrected.
[EW20428] -
Specifying a designated initializer on a field inside more than one level of anonymous unions/structs could earlier cause an internal error in the compiler. This problem has been corrected.
[EW20439] -
An inline-assembler operation can now correctly generate an error for absolute addressing in ELF.
[EW20489] -
The compiler could fail when generating code for certain loop constructs. This has been corrected.
[EW20503] -
In some cases an address expression inside two nested loops could use a variable before it had been assigned a value. This has been corrected.
[EW20531] -
At medium optimization level (or higher) for Cortex-M3, compilation of certain combinations of the constant 256 and the question mark operator (
a?b:c
) could earlier result in an internal error with the message "illegal state". This has been corrected.
[EW20537] -
Variables of small type (for example
char
) could earlier be incorrectly hoisted as a loop counter even though it might wrap. This has been corrected.
[EW20563] -
A
do
loop copying consecutive shorts, integers, or long longs have now a correct byte count when translated into a memcpy call.
[EW20570] -
Return value temporaries created for functions that use a return value pointer did not get marked as having had their address taken. This has been corrected.
[EW20572] -
In some cases the code could be optimized incorrectly if pointers of different types were used to access the same memory address. This has been corrected.
[EW20581] -
Certain operations (typically bit-wise) involving template static data members of integer type could cause an internal error when compiling template code. This has been corrected.
[EW20608] -
A loop could in some cases be incorrectly optimized if it updated a global variable preceded by an indirect store of the same type as the global variable.
[EW20627] -
The compiler no longer tries to put
CPSIE/CPSID
in an IT-block.
[EW20652] -
The min and max templates should now be optimized correctly after function inlining.
[EW20654] -
The compiler no longer crashes after issuing the error Pe020.
[EW20684] -
The intrinsic function __set_CPSR() generated the wrong assembler instruction. This has been corrected.
[EWARM-268]
V5.20 2008-06-24
New features-
Support for vector floating point (VFP) coprocessors.
-
The compiler no longer removes reads from uninitialized volatile auto variables from the code.
[EW19167] -
A thunk with fall through is now padded properly whenever it is needed.
[EW19481] -
Source lines after a
#line
directive are now included in compiler list files.
[EW19654] -
The compiler can now handle segment/section names that are the same as assembler instruction names, register names, etc.
[EW19674] -
Out-of-line definitions of member functions of a template class are now made properly tentative.
[EW19678] -
Declaring a class-specific two-operand operator
delete
in a class template no longer causes the compiler to crash.
[EW19707] -
The compiler no longer crashes after emitting an error indicating an extraneous
typename
keyword in a template.
[EW19796] -
MISRA C rule 23 no longer gives an error for non code symbols.
[EW19802] -
Realloc no longer leaves the heap in a broken state after a call that tries to allocate more memory than there is in the heap.
[EW19803] -
The compiler no longer crashes when generating DWARF debug information for a class-external
typedef
of a class-scopedenum
type with more than 9 constants.
[EW19820] -
When performing
memcpy
in Cortex-M3 and the source and destination pointers have different alignments, the last 16 bytes are now copied also in cases where the size is:
size = 32 + ((4 -(DstPtr & 3)) & 3) + (y * 16); // y = 0, 1, 2 e.t.c.
[EW19837]
-
Instruction scheduling will no longer lift pop of LR over a function/library call.
[EW19872] -
A call to
memmove
with aligned parameters is no longer incorrectly transformed into__aeabi_memcpy4
instead of__aeabi_memmove4
.
[EW19878] -
Masking a
long long
value now works.
[EW19908] -
A function call, where one parameter is a pointer to a signed integral type that is cast to a pointer to the unsigned type of the same size (or vice versa), no longer causes an internal error if the function call is inlined.
[EW19933] -
Loops with an unsigned loop variable, going from 0 to 1, will no longer be optimized incorrectly.
[EW19973] -
Constant tables layout generation for Thumb2 code has been adjusted.
[EW19984] -
In some rare cases structure assignments, where the source was a indirection of a pre- or post-incremented pointer, could be optimized incorrectly. This has been corrected.
[EW20071] -
Debug information for variables in high registers (
r8-r14
) in Thumb2 code has been improved.
[EW20098]
[EW20100] -
Clustering now handles segment/section-located initialized variables.
[EW20149] -
In some rare cases an optimization that temporarily hoisted a memory cell (i.e. a global variable or a structure member) to a register did not transform the code correctly and one or more uses could still refer to the memory cell. This has been corrected.
[EW20150] -
Fall through from an arm function to a thumb function is no longer generated.
[EW20164] -
Invalid instructions no longer generate internal errors.
[EW20199] -
Tag_ABI_enum_size
now reflects the real size ofenum
used.
[EW20203]
V5.11 2007-12-11
New features- Support for Cortex-M1 and Cortex-M3.
-
If the code generator failed to place a small object of aggregate type in registers, it could fail also when it tried to place the object on the stack instead. This happened if the alignment of the object did not match the size of the aggregate members, resulting in the wrong offsets being used for all members except those placed on alignment boundaries.
[EW19478] -
A 32-bit mask operation with all except the highest bit together with a test on the highest bit of the same variable could generate incorrect code in Thumb mode.
[EW19480] -
The section ".textrw" can now be renamed.
[EW19672] -
The compiler can now handle segments/sections with names that are identical to names of assembler instructions, registers, etc.
[EW19674] -
Out-of-line definitions of member functions of a template class were not made properly tentative, resulting in erroneous 'duplicate definition' errors when linking. This has been corrected.
[EW19678] -
Declaring a class-specific two-operand operator delete in a class template no longer causes the compiler to crash.
[EW19707] -
Bad syntax in function declarations no longer generate internal errors.
[EW19718] -
Doubles are now rounded correctly.
[EW20026]
V5.10 2007-06-12
New features- Object files are now produced in the ELF/DWARF format.
- Support for AEABI, which means interperability with other ARM EABI compliant tools.
-
The compiler now produces an error when an initializer for a static variable
contains the address of a bitfield member.
[EW17962] -
A function-like macro, named as a predefined IAR attribute name, no longer
makes the compiler end erroneously.
[EW18386] -
In rare cases, only the high part of a 64-bit variable was loaded.
[EW18735] -
NOP instructions, inserted with the intrinsic function
__no_operation()
was scheduled causing them not to appear at the desired places in the code.
[EW18767] -
The header file
MtxWrapper.h
now works from C++.
[EW18769] -
Loops containing array accesses with index expressions of
char
type could earlier in some cases be optimized incorrectly.
[EW18815,EW18963] -
Inconsistencies between several declarations or between declaration and definition
of the same function now give proper diagnostics.
[EW18818] -
The header file
Dlib_Product.h
is now compilable with MISRA C.
[EW18843] -
Interweaved stores with zero and reads from the same structure could earlier be done in
incorrect order.
[EW18845] -
Wrong code was generated when passing an unaligned struct as parameter in big endian mode.
[EW18900] -
swprintf
andvswprintf
now correctly handle the ending\0
.
[EW18948] -
In some rare cases, common subexpressions involving a struct pointer (
p->x
) was incorrectly optimized if the expression was preceded by an equality test between an other member in the same structure and a constant (p->y == 0
).
[EW19015] -
Functions with
__irq
and__fiq
now save the vfp status register when compiling for vfp.
[EW19047] -
The compiler no longer generates an erroneous constant for a compound literal that is
used in a file-scoped initialization.
[EW19076] -
swprintf
now handles large strings correctly.
[EW19105] -
Large functions could give the following internal error:
Internal Error: [CoreUtil/General]: Jump distance to far for B
.
[EW19179] -
Clustering could cause zero initialized data to occupy ROM space,
instead of using zero initialization.
[EW19232] -
The
!
operator on a byte in achar
buffer (example:return !buf[0];
) could earlier cause the internal error:
Const_Folding - Internal error Unequal types for operator !=
Internal Error: [CoreUtil/General]: Const_Folding - Internal error
[EW19337]
V4.41A 2006-12-08
Program corrections-
The compiler generated misleading errors for unevaluated parts of constant
expressions in some circumstances, for example:
const unsigned int z1d = ( (0) ? ( ( 1 >= (1ul << -6) ) ? 1 : 2 ): 1 );
This expression contains a negative shift count, which would normally result in a diagnostic, but the problem is in the non-evaluated part of the containing conditional expression, so this diagnostic is suppressed. The negative shift count makes the comparison undeterminate, which resulted in a "constant value is not known" diagnostic. This subsequent diagnostics was not suppressed, which it also should have been.
[EW18140] -
In Thumb-mode a tail-call could incorrectly be optimized to jump even when the jump
distance was just out of reach.
[EW18151] -
A stack-backtrace information problem with
__irq
and__fiq
functions has been corrected.
[EW18152] -
Inverting a
long long
variable could earlier generate an internal error.
[EW18157] -
Instruction scheduling could earlier incorrectly lose some debug information for inlined functions.
[EW18180] -
A function containing a structure assignment inlined in a loop body could in some
rare cases cause an internal error.
[EW18182] -
The optimizer could incorrectly remove
CMP
instructions if the preceding arguments looked like constants.
[EW18231] -
When a constant table was placed immediately after a switch table,
a dangling (duplicate) label might be left which caused the backtrace
analysis to abort the compilation with the following error message
Internal error: [CoreUtil/General]: BtThreadAnalyzer: No direct arc from node to successor
[EW18259] -
If the compiler found several stores with zero to consecutive memory locations
the last store could be done with wrong size.
[EW18273] -
The compiler did not handle large functions properly in thumb mode.
[EW18276] -
The
<vector>
header no longer relies on the undefined symbol TRUE
[EW18284] -
Branch chaining optimization could incorrectly chain a
BNE
instruction via aBHI
instruction. [EW18312] -
Variables declared both
static
andvolatile
were incorrectly not treated as such at all times.
[EW18316] -
For a
struct
withshort
members, the members could incorrectly be written as a 32-bit entity when theshort
member was kept in register. This could also lead to adjacent members being overwritten.
[EW18320] -
In some rare cases the intrinsic
__no_operation()
function could give an internal error message.
[EW18396] -
Bitfield assignments should now work correctly, even when the function call on the right-hand
side of the assignment modifies other bitfields in the word.
[EW18460] -
In some rare cases, a series of assignments could be optimized incorrectly, for example assignments like:
x = ...; y = x; x = !z; ... use(y);
[EW18540] -
Using
#pragma optimize
to lower optimization level for a function no longer affect optimization of static accesses in other functions.
[EW18582] -
An optimization can lift a global variable to a register in a code region.
In some rare cases the register was not written back to the variable on all paths from the region.
[EW18814]
V4.40A 2006-06-03
Program corrections-
In some rare cases, the optimizer incorrectly transformed a
for
or awhile
loop to ado
loop if: the loop test compared the loop counter to a variable (V
) that was invariant in the loop, and the loop was preceded by an if-else-if-statement where the else-if-test testedV
against a constant value.
[EW17723] -
High optimization could, in some rare cases, incorrectly hoist a common
subexpression (1) across the initialization of another common subexpression (2)
where (2) was the value of a global pointer variable and (2) appeared as a
subexpression in (1).
[EW17754] -
Saturate idiom was recognized even at low or no optimization making the code
harder to debug.
[EW17802] -
An ARM-mode peephole optimization could optimize a MUL + ADD to MLA even thou
the ADD had a shifted operand.
[EW17833] -
Functions with inline assembler with labels could incorrectly be inlined.
[EW17862] -
Incorrect code could in some cases be generated in thumb mode for saturate
idiom.
[EW17868] -
Inlining of functions where a pointer parameter was declared volatile could in
some case result in incorrect code.
[EW17902] -
The result of the instruction scheduling could in some cases differ between
compilations with same input.
[EW17919] -
Functions that dereferenced a pointer after testing if it was NULL could be optimized
incorrectly.
[EW18038] -
Loops that added invariant expression to an indirection of an invariant pointer and the loop
index variable (p[i] += 4711) could in some cases be optimized incorrectly.
[EW18089] -
Unaligned store of zero could give internal error if neighbored with another zero store.
char charr[100]; *(int*)(&charr[1]) = 0; charr[5] = 0;
Note that this kind of code probably will not execute correctly, since most ARM architectures do not support unaligned accesses.
[EW18124]
- Support for the Cortex-M series has been added.
- Output from the compiler is now in unified assembler syntax.
V4.31A 2006-02-03
Program corrections-
Invariant assignments could in some cases incorrectly be hoisted out of
for
orwhile
loops, if the loop test contained an||
operator.
[EW16986] -
High optimization could in some cases generate incorrect code for nested loops
if the inner loop was not executed for every iteration of the outer loop.
[EW17010, EW17064] -
The compiler could in some rare cases loop if the outcome of the condition in a
conditional (
? :
) expression could be determined by assignments in the preceding basic blocks.
[EW17026] -
Nested irq functions did not return properly.
[EW17032, EW17033, EW17038] -
A
char
orshort
loop counter initialized with a function call could in some cases result in an internal error.
[EW17039, 17179] -
Assignments to an auto array could incorrectly be removed as dead code if the
only use of the array, besides assignments to it, was to assign the array
address to a global pointer.
[EW17041] -
Incorrect interpretation of the
Z
flag when analyzing aCMN
instruction could lead to incorrect optimizations.
[EW17065] -
Accessing a data member of a base class of a class object returned by value
from a function call no longer results in an internal error.
Example:fun().x
, wherex
is a data member of a base class of the type returned byfun()
.
[EW17085] -
Optimization of a function tail call into a branch instruction in a thumb
function that takes stack parameters generated wrong stack offset to the stack
parameters.
[EW17117] -
Delayed stack-cleaning in combination with stack access and a conditional (
? :
) expression could generate wrong stack offset.
[EW17127] -
Loops where the loop counter was a
short int
orchar
could earlier result in incorrect code if the loop increment was negative and high speed optimization was used (-s9
).
[EW17129, 17164] -
When constructing a vector of POD data (data with no constructors) with an
initial non-zero size, the elements are now correctly zero-initialized. For
example:
vector<int> v(3);
v
should in this example contain 3 integers, each initialized to zero. Previously the integers were incorrectly left uninitialized.
[EW17160] -
Code with both shifting and division by a constant value could in some rare
cases generate internal error.
[EW17162] -
Loops where the trip count was constant and the final statement was a
switch
expression could in some cases cause an internal error when high optimization was used.
[EW17181] -
Incorrect code could be generated for small loops with descending access
patterns. For example:
for (i = 0 ; i < n; ++i) a[100 - i] = ...;
orfor (i = 0 ; i < n; ++i) *(p-- + 17)= ...;
[EW17184] -
The MISRA C rule 113 states that members of a structure or union shall only be
accessed via their name. The compiler now diagnoses a violation of this rule
correctly when a pointer to an element of a member array is created. For
example:
struct { int a; int b[2]; } x; x.a; /* Was diagnosed */ x.b[0]; /* Was not diagnosed */
[EW17186] -
An
__swi
declared function pointer now correctly gives an error message.
[EW17329] -
A register transfer instruction were in some cases optimized away due to
incorrect optimizer analysis of sign extend operations.
[EW17330] -
Incorrect code was generated for assignments of instances of
vector<>
in two cases:
1. The assignment of a vector where the elements could use bitwise copy and where the destination vector was smaller than the source vector but had a capacity that was large enough.
2. The assignment of a vector where the elements needed copying or construction using member functions but did not need destruction, where the destination vector was larger than the source vector.
These assignments now work correctly.
[EW17413] -
R8_fiq
-R12_fiq
was unnecessarily saved when entering an fiq exception.
[EW17453] -
The internal error:
[Ect]: Optimize
has been corrected.
[EW17461] -
An error message is now given if the
--segment
option is used more than once with the same segment specifier.
[EW17463] -
On high optimization, array initializations and assignments to array members
could be incorrectly removed as dead code if the only explicit use of the array
was to assign its address to a member in a packed
struct
.
[EW17466] -
A problem in the instruction scheduling optimizer has been corrected. A
pop
instruction to restore callee saved registers could be hoisted over an instruction that defined one of theses registers.
[EW17495] -
When compiling for interwork, a redundant mode change entry will be inserted in
front of a generated function. This function may save information about code
size if the function is called from code with different mode (arm/thumb). In
some cases the compiler missed to generate this mode change entry. The
generated code is still correct but can give different code size between
compilations.
[EW17603]
-
The command-line option
--no_path_in_file_macros
has been added. It removes the path leaving only the filename for the symbols__FILE__
and__BASE_FILE__
.
V4.30A 2005-06-23
Program corrections-
The compilation time is now reasonable when the source code
contains hundreds of global variables and is compiled
with high optimization level.
[EW14199] -
Warning Pa084 ("pointless integer comparison with out of range value") will no
longer be issued erroneously in cases where a relational operator is used with
a template non-type parameter of integer type.
[EW16367] -
Some float NaN patterns were not correctly converted to double.
[EW16373] -
Using compound literals, a C99 feature, could result in an internal error in
the compiler.
[EW16412] -
Inline assembler code with illegal instructions like
MOV R0,@R1
could generate an internal error
[EW16414] -
An inline-assembler statement containing nothing but a newline character could
cause an internal error in the compiler. Example: asm("\n");
[EW16415] -
A label placed on the first line of a multi-line inline-assembler statement
could cause errors.
Example:asm("loop:\n" " bra loop");
[EW16417] -
Loops with multiple assignments to an auto variable could result in incorrect
code, when the loop also contained partial accesses (with a non-zero offset) to
the auto variable.
void ByteSwap128(short *addr) { int i; short tmp; char *dst, *src = (char *)&tmp; for (i = 0; i < 64; ++i) { tmp = *addr; dst = (char *)addr++; dst[0] = src[1]; /* points to (char *)&tmp + 1*/ dst[1] = src[0]; tmp = *addr; dst = (char *)addr++; dst[0] = src[1]; dst[1] = src[0]; } }
[EW16419] -
The compiler now generates the same alignment for the following two
definitions:
unsigned char a [6] = {0,0,0,0,0,0};
unsigned char b [] = {0,0,0,0,0,0};
[EW16430] -
Loops with a non-constant trip count (number of iterations in the loop) could
be uncorrectly unrolled.
[EW16439] -
Common subexpression elimination no longer hoists expressions that incorrectly
can cause an exception, unless the expression is guaranteed to be executed in
all successors.
[EW16443] -
Fixed a problem were iswprint erroneously returned true for the characters
carriage return and newline.
[EW16465] -
Branch-chaining optimization, which is performed at the highest size
optimization level, could incorrectly chain a
BCS
instruction via aBHI
instruction. This could cause a branch to go the wrong way at runtime depending on the status of the Z-flag.
[EW16481] -
An expression containing the new operator could generate a reference to the
wrong constructor when an optimization level of 6 or higher was used, at least
one of the parameters to the constructor was an object passed by copy
construction, and the constructor definition was not visible in the same
compilation unit as the expression containing the new operator.
Example:struct X { X(X const &); ... }; struct Y { Y(X); ... }; Y * mkY(int a) { return new Y(a); }
If the function mkY was not in the same file as the definition of Y::Y(X), a reference was created to Y::new Y(X *) instead of to Y::new Y(X).
[EW16482] -
Calculating remainder by a constant could give the wrong result at the highest
speed optimization level.
[EW16487] -
Overlapping stores with zero could caused an exception in the compiler at high
optimizations. The compiler analyzes stores with zero to memory and optimizes
them. If there were instructions that wrote to overlapping memory locations,
the compiler could terminate with the following internal error:
Internal error: [Ect]: Any exception Fatal error detected, aborting. Internal error: [PostOptimize]: Any exception Fatal error detected, aborting.
[EW16489,EW16491] -
Optimizer inlining failed to recognize the #pragma location directive, leading
to located code being placed in the wrong segment.
[EW16529] -
The compiler could generate incorrect code if:
- A function (f) assigned a variable (p) to point to an object (o) and returned the variable p,
- the function result was assigned to a variable (q) of the same type as p,
- the object o was modified before an access to o through q
- and the function call to f was inlined by the optimizer.
-
An optimization that tries to hold a global variable in a register during
several modifications of the global variable could in some cases cause
incorrect code.
[EW16547] -
In some cases, a loop with an upper bound that was a signed non-trivial
expression divided by a power of two could result in incorrect code.
[EW16550] -
Complex
?:
sequences could cause an internal error at the high optimization level.
[EW16552] -
When compiling EC++, constant variables initialized with simple floating point
expressions were put in RAM memory instead of ROM memory.
[EW16587] -
Corrected an internal error that could occur when an assignment to an auto
structure contained a reference to a member in itself or another auto
structure.
struct X x, y, *array; x = array[x.m];
[EW16606,EW16608,EW16627,EW17177] -
A Thumb
MOV
immediate to low register could be hoisted in between aCMP
-BCC
/BCS
sequence, which destroyed the effect of theCMP
instruction.
[EW16611] -
In some rare cases, values were not written to memory before a function call.
[EW16620] -
Code that implements a saturate operation (keep a value inside a range such as
-128 to 127) could produce incorrect code in both Thumb and Arm mode.
[EW16626,EW16670] -
At the high optimization level incorrect code could be generated if a loop had
an unsigned loop counter, the loop counter was decremented, and the loop
contained a test (besides the loop exit test) where the loop counter was
compared to zero.
[EW16646] -
An internal error in constant table generation for functions that end with a
fall through to the common exit sequence has been corrected.
[EW16657] -
Incorrect code could be produced when a "
Rn <shift> Rm
" operand is spilled to other registers and there is an overlap between one of the original registers and the new destination. The error occurred because the operand was not properly reconstructed to reflect the new registers that the values were moved to.
[EW16671] -
Optimizer inlining failed to recognize
__ramfunc
, leading to that code meant to be placed in RAM could end up in ROM.
[EW16698] -
If both statements in an if else statement are identical (after removal of dead
code) an optimization that merges the two statements could in some cases also
remove side effects (for example calls or volatile accesses) in the redundant
condition.
[EW16735] -
Incorrect code could be generated when the initial value for a signed loop
counter was computed with an & expression where both operands where
non-constant expressions.
[EW16757] -
Two
STRB
with zero to offset 256 and 257 could be compiled into a singleSTRH
which then had its offset truncated to 0.
[EW16885] -
Coprocessor instructions MCR and MRC are no longer moved around by the
instruction scheduler. They previously were allowed to be move past a volatile
side effect.
[EW16886] -
If a loop with a variable upper limit was preceded by a modification of the
upper limit and a test of the upper limit being larger than the lower limit of
the loop, the optimizer could incorrectly assume the loop body should always be
entered.
if (u > 0) { --u; for (i = 0; i < u; ++i) { ... } }
[EW16887] -
Including an I/O definition header and referencing more than one SFR from C++
code will no longer result in incorrect "more than one definition for
struct/union type" warnings when linking.
[EW16957] -
Unrolling of loop with non-constant trip count could cause internal error in
the optimizer.
[EW17006]
- Support for ARM11 and V6 has been added.
- The execution speed of the floating point library has been significantly improved.
- Code size and speed performance have been improved for both ARM and Thumb.
- It is now possible to declare variables in the initialization clause of a for statement, but only in extended language mode. This behavior is according to the C99 and the C++ standards.
-
You can now compile several source files in one compilation by specifying the
command line option --mfc. The advantage of multi-file compilation is that it
gives the interprocedural optimizations a larger set of functions to work on.
If you also specify the command line option --discard_unused_publics, the
optimization will be further improved because the compiler will assume that
there are no references to any symbol from the outside in the compilation, i.e.
the compilation unit is the whole application apart from the library.
Use the --mfc option with caution, because it is experimental in this version of the compiler. -
Some more C99 functionality has been added to the IAR DLIB Library:
- Ctype.h defines isblank as an added function.
- Inttypes.h has been added. Note that only the conversions are included, not the functions.
-
Math.h defines the following additions:
Macros - HUGE_VALF, HUGE_VALL, INFINITY, NAN, FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, MATH_ERRNO, MATH_ERREXCEPT, math_errhandling.
Typedefs - float_t, double_t.
Macro functions - fpclassify, signbit, isfinite, isinf, isnan, isnormal, isgreater, isless, islessequal, islessgreater, isunordered.
- Stdlib.h defines llabs, lldiv, strtoll, strtoull, atoll, strtof, and strtold as added functions.
- Wchar.h defines vfwscanf, vswscanf, vwscanf, wcstof, and wcstolb as added functions.
- Wctype.h defines iswblank as an added function.
V4.20A 2005-01-10
-
Program corrections
-
Using
#pragma vector
on an interrupt function did not update the exception vector table.
[EW14086] -
A function definition at a line number greater than 65535 could cause an
internal error, due to an unused line number field in an object file record
that overflowed.
[EW15542] -
Call to an
__irq
or__fiq
function could generate an internal error.
[EW15561] -
__ramfunc
functions shared relay functions with non__ramfunc
functions in the same module. If they were placed far from each other that could generate a link error.
[EW15562] -
The scheduler failed to recognize overlapping load and store operations if they
were of different size.
[EW15579, EW15656] -
A volatile load directly following a store to the exact same location could
reuse the stored value instead of loading it again.
[EW15582, EW15657, EW15663] -
A declaration of a block local variable with no initialization, immediately
followed by a label, resulted in incorrect code in some cases.
[EW15594] -
In some cases auto-variables of union type were optimized incorrectly.
Assignments to a member (m) were incorrectly removed if the union definition
contained a declaration of another member, of equal or larger size, below the
declaration of m.
[EW15595] -
The scheduler could generate an internal error for a large basic block without
any statement info.
[EW15596] -
If a function had multiple return statements and all returns were preceded by
an assignment to the same global variable (or an indirect assignment using the
same pointer), the return value could be overwritten by a temporary value.
[EW15600] -
Some caller-saved registers were not saved when calling library routines for
floating point subtraction and division.
[EW15601] -
Fall through to a large 'common exit sequence' with several constant references
could generate constant entries out of bounds.
[EW15613] -
AND
with a constant that was converted toBIC
on a variable smaller than 32 bits could leave garbage in the higher bits of the register.
[EW15621] -
In some cases auto-variables of structure type caused an internal error if the
structure had a member of union type.
[EW15622] -
A register parameter could in rare circumstances be allocated in the same
register (or overlapping register) as another local variable.
[EW15623] -
Hoisting of loop-invariant code could in some rare cases generate incorrect
code.
[EW15624] -
Code optimized to a conditional tail jump could generate an internal error.
[EW15625] -
A basic block could in some cases be flattened even if it had multiple
predecessors with different flags set.
[EW15627, EW15768] -
FLDS
,FLDD
,FSTS
andFSTD
can now have relocatable offset. This is needed when accessing constants from vfp code.
[EW15641] -
Constant entries could in some cases, especially large
long long
switches, be placed among the switch data. This could lead to random jumps anywhere in memory.
[EW15643,EW15660,EW15661,EW15665] -
Invariant definitions were in some cases hoisted even if it defined alive
non-invariant resources or used a non-invariant resource.
[EW15646] -
Offset check for constants placed in another segment part was too pessimistic.
This could lead to internal error.
[EW15653,EW15654] -
In some rare cases the compiler performed incorrect optimizations (for example
constant propagation or common subexpression elimination) of accesses through
pointers. The effects were noticeable when the same data object was accessed
through different pointers. The problem was unlikely to occur in non-trivial
functions.
[EW15655] -
long long
switch in thumb mode could generate unaligned accesses.
[EW15659] -
In some cases the compiler tried to flatten a basic block ending with a table
switch. This generated broken code.
[EW15664] -
In some cases union accesses were optimized incorrectly. The union accesses
could only have two sizes and one of the sizes must be the whole union.
Accesses of the two differing sizes must be interleaved so the contents of the
union was read with a different size than the value stored in the union.
[EW15681] -
The intrinsic
__no_operation()
could be optimized away in Arm mode.
[EW15690] -
When a volatile-declared variable was used in the index expression of a
volatile-declared array expression, the compiler issued an incorrect warning
about undefined order of volatile accesses.
[EW15710] -
The #pragma vector was broken in several ways.
1. The segment part was generated as noroot causing the linker to remove it.
2. Multiple vector numbers was not recognized.
3. The vector number was scaled wrongly.
[EW15781] -
When typedefs were involved in an integer comparison, the compiler sometimes
incorrectly issued the warning Pa084 (pointless integer comparison with out of
range value) for cases where such a warning was inappropriate.
[EW15793] -
Swi vector for declared only functions was sometimes treated as 0.
[EW15862] -
A thumb peephole pattern which propagates an
ADD
instruction beyond aLDR
/STR
instruction by modifying the addressing mode of theLDR
/STR
instruction did not take care of all situations properly with respect to flags being alive after the instruction.
[EW15898, EW16191] -
The compiler could generate wrong debug information for local variables causing
them to be shown as unavailable in the debugger watch window.
[EW15948] -
Complex expressions containing a signed division with a constant denominator
could in some cases cause an internal error.
[EW16000] -
Evaluation of expressions with the
%=
operator now follows the rules for integral promotion.
[EW16001] -
The internal header file
xlocale.h
did not work properly when the current locale was the C locale (which it typically is) and the symbol C was defined as a preprocessor macro.
[EW15602] -
The use of a variable (x) could incorrectly be eliminated from an expression,
if 1. the expression contained both a use and a defining use of x and 2. the
expression contained a use of another variable (b) that was the single use of
it 3. no defining use of x occured before b's defining use
void use(int); int broken(void) { int x; /* x uninitialized */ int a = 1; int b = 2; /* b's definition */ x = a; /* this defining use of x is overlooked */ use(x); x = b + x; /* use and def of x, use of b */ use(x); return x; }
[EW16002] -
The compiler now attempts to warn about undefined behavior in some situations
involving sequencing or multiple modifications with no intervening sequence
point. If this warning involved data accessed through the implicit
this
pointer of a C++ member function, an internal error resulted.
[EW16021] -
The scheduler could rearrange code including a constant load to VFP register
even when conflicts would appear.
[EW16051] -
An initialized
auto
array inside a loop no longer causes an internal error.
[EW16052] -
Relay function to
div
/mod
trashed R2 in thumb mode. Such relay functions is needed when the distance between the caller and the callee is more than 4 Mbytes.
[EW16061] -
A problem where using the preprocessing operator
define
could cause an internal error has been corrected.
[EW16076] -
Register allocation of VFP registers could differ between compilations of a
specific source code depending on Windows memory allocation. The code produced
was correct, but not necessarily identical.
[EW16083] -
Long functions can make use of spring board jumping which utilize existing
jumps to avoid generating a long branch, by forming branch chains. In one rare
case a conditional branch immediately preceeding the destination label could
incorrectly be incorporated in such sequence (its destination points elsewhere,
but it has fall-through flow to the target label).
[EW16097] -
Defining a C preprocessor macro with the same name as any directory component
of the library configuration file path would change that component giving the
wrong path.
[EW16220] -
long long
operations such asadd
,subtract
,negate
could be incorrectly made if the low part of the result overlapped with the upper part of one of the operands. This happened in some rare situations when the register pressure was high.
[EW16331] -
8-bytes stack alignment was not always preserved.
[EW16332] -
Complex pointer to data member access could generate internal error with bad
data alignment.
[EW16370] -
The compiler could terminate with
Internal Error: [CoreUtil/General]: Const_Folding
when doing a cast on pointer arithmetics.
[EW16898] -
The common subexpression elimination optimization could could give different (but correct)
output depending on compilation environment, producing slightly different (but correct)
code between compilations.
[EW17918]
-
A new object attribute,
__noreturn
has been added. The attribute can be used on functions to inform the compiler that the function will not return. The compiler can then generate more efficient code. Examples of functions that do not return areabort()
andexit()
. -
To determine the configuration file for DLIB from the command line, use the
compiler option
--dlib_config config_file
. The old variant, using-D_DLIB_CONFIG_FILE=config_file
, will still work but can interfere with other preprocessor defines. - Support for compound literals has been added to the C language.
-
New compiler command line option
--preinclude include_file
. -
The inline assembler operator
asm()
now supports multiple instructions and local labels. Example
asm("Loop: MOV R0,#10 \n" " ADD R3,R3,R2 \n" " SUB R0,r0,#1 \n" " BNE Loop");
Note that the instruction separator is'\n'
and that the definition and the reference of a local label do not necessarily need to be in oneasm()
.
V4.11A 2004-06-10
-
The following C99 features can now be used in the C language if language
extensions (-e) are enabled:
-
The
inline
keyword. It works as the C++ inline keyword (and the#pragma inline
declaration). - Mixing declarations and statements within the same scope.
- Having a declaration in the initialization expression of a for-loop.
-
The
-
The standard library
fopen()
function incorrectly worked and returned a valid file pointer, even when not linking the application with the debug information without I/O emulation modules, available by choosing Project Options and selecting the Linker category.
[EW13922] -
In rare cases at high optimization levels, the optimizer data flow analysis
could fail with an internal error.
[EW15026] -
The namespace scope of extern "C" functions was incorrectly included in their
linker visible names, which sometimes could lead to incorrect Undefined
External errors when linking.
[EW15088] -
Instruction scheduling could in some cases change the order of two volatile
read accesses.
[EW15119] -
In some cases an array element reference could be optimized incorrectly if the
address was computed in two separate expressions and both contained the loop
counter. For example.
int a[100][100]; int foo() { int i; for (i = 0; i < 10; ++i) { int *p = &a[i][0]; /* first use of i */ p[i * 2] = 4711; /* second use of i */ } }
[EW15123] -
If all paths to a switch statement with a single variable as a switch
expression contained assignments to the variable, it could in some rare cases
cause the compiler to loop when all the jumps to the switch were redirected to
their destination into the switch body.
[EW15131] -
Functions declared
__swi
and with calls to other functions could generate an internal error.
[EW15327] -
The
va_start1()
intrinsic function incorrectly gave a warning when the optionrequire_prototypes
was used.
[EW15328] -
Switch on character expression with all case values between 0x80 and 0xFF could
generate incorrect code.
[EW15349] -
Too agressive optimization could incorrectly casuse a needed
AND
instruction to be removed.
[EW15396] -
The treatment of the
#pragma segment
directive has been changed to allow multiple equivalent declarations of the same segment.
[EW15413] -
A switch statement with case values in a range greater than 255 could generate
an internal error.
[EW15462] -
The compiler printed diagnostic text contained the obsolete segment types
HUGEDATA
andHUGECONST
instead ofDATA
andCONST
.
[EW15464] -
Library call from located functions could incorrectly cause reference to
undefined symbol.
[EW15465] -
A function with a parameter of type pointer to class could sometimes get an
incorrect name in the object file, resulting in an 'undefined external' error
when linking. For this to happen, the class must have a user-defined or
non-bitwise compiler generated copy constructor, and there must be a definition
of another function in the same module returning the class by value. That
function must, apart from the pointer to class parameter, be declared with the
same parameter types as the first function.
[EW15466] -
An ARM function compiled for VFP with an integer parameter located in register
and later stored on the stack could generate an internal error.
[EW15469] -
No relay function was generated for calls to
__ramfunc
functions declared in the same module even though the distance was too far for theBL
instruction.
[EW15485] -
The shift count was not properly zero extended for
long long
shifts.
[EW15500] -
If a register was used in a loop only by a single instruction, that register
could incorrectly be considered as dead after the refering instruction.
[EW15612]
V4.10B 2004-03-09
-
Two new intrinsic functions are now available in the compiler,
__MCR()
and__MRC()
. They make it possible to access coprocessor registers from C and C++, and not just from assembler language.__MCR()
inserts a coprocessor write instruction,MCR
, and__MRC()
inserts a coprocessor read instruction,MRC
. For syntax details, please see the inarm.h header file. -
A new compiler command line option,
--separate_cluster_for_initialized_variables
, has been added to separate initialized and uninitialized variables, when using variable clustering. The use of this option can make the*_ID
segments smaller at the expense of code size. Variable clustering is disabled altogether by the--no_clustering
command line option. -
A new compiler keyword,
__nested
is available to allow nested interrupts. The keyword modifies the enter and exit code of an interrupt function to allow interrupts to be enabled and to be served inside the interrupt function without overwriting theSPSR
and return address inR14
. Nested interrupts are only supported for__irq
functions. For example:__irq __nested __arm void interrupt_handler(void);
-
Some ISO C99 features have been added. They are available when language
extensions are enabled.
-
Support for the bool data type, if the header file
stdbool.h
has been included. - _Pragma support. This operator works as the pragma directive and can be used in macro definitions.
-
Variadic macro support. You can now write printf-style macros.
-
Hexadecimal floating point constants support. This means the ability to exactly
specify a floating point constant. The functions strtod(), printf(), and
scanf() recognize the syntax.
-
The macro definition
__func__
. If used in a function, it is defined to the name of the function. - Designated initializers. Using these, you can initialize a specific element in a structure or a specific element in an array.
-
Inline functions. The pragma directive
inline[=forced]
has been added as well. -
long long
support in the library. For example the functions strtoll(), strtoull() have been added as well as support for them in printf() and scanf().
-
Support for the bool data type, if the header file
-
The
localtime
C++ runtime library function generates negative values for thetm_mday
element.
[EW12510] -
The compiler could generate an internal error when performing live-dead
analysis on a data pointer that was casted from a function pointer. The problem
was present on optimization levels medium (-z6/-s6) and high (-z9/-s9).
[EW14949] -
No relay is generated in the following code (The compiler does not know how far
apart these two functions actually are...)
#pragma location="CALLEE" __thumb void callee() { volatile int a = 0; } #pragma location="CALLER" __thumb void main() { volatile int a; callee(); a=1; }
[EW14973] -
In the following code the relay for the call from caller() to callee() will be
'knocked out' by the relay entry to callee.
#pragma location="CALLEE" __thumb __interwork void callee() { volatile int a = 0; }
[EW14975] -
In a member function of a template class or one of its nested classes, a delete
expression involving a pointer to one of these classes could cause an internal
error when compiling.
[EW14979] -
When compiling C++ code, the compiler could fail with an internal error when
the result of a struct/class/union assignment was used (for instance in a
chained assignment expression), the struct/class/union had no user-written
assignment operator, and the assignment could be performed as a bitwise
assignment.
[EW14981] -
The body of the following loop was incorrectly treated as invariant.
struct { int x; int array[10]; } s; void f(void); void g(void); void test() { int i; for(i = 0; i < 8; ++i) { if (s.array[i]) { f(); return; } } g(); }
[EW14985] -
When an inline member function was called from an __arm function, instead of
calling the member function the object's destructor was called.
[EW15102] -
When an inline member function is called from an __arm function, instead of
calling the member function the object's destructor was called.
[EW15103]
V4.10A 2004-02-21
-
Valid stack backtrace information is now available in the IAR C-SPY Debugger
inside the
__irq
and__fiq
interrupt functions.
[EW12251] -
Variables initialized to zero, either by explicitly setting them to zero in the
code or as default behavior when no value is given, were cleared to zero by cstartup.
A very small table entry was used to describe an entire block of memory to be
cleared. If such zero-initialized variables are clustered together with
variables that have explicit non-zero initializers, they would get explicit
zero bytes to be copied by cstartup. If the zero-initialized variable
was large (an array, for example), this could result in a waste of read-only
memory. There is a new option that can be used to correct the described
behavior:
--separate_cluster_for_initialized_variables
Separate initialized and uninitialized variables, when using variable clustering.
[EW12980] -
The
stdout
stream is now buffered. Unbuffered stdio could cause slow terminal I/O performance in the debugger.
[EW13609] -
Assignments of derived class objects to base class variables (also known as
"slicing" assignments) where the assignment could be performed by bitwise
copying caused an internal error when compiling.
[EW14094] -
Some syntax errors could cause a subsequent internal error when the
--require_prototypes
option was used.
[EW14107] -
When generating a constructor or destructor for an unnamed structure or class
(for example, because one of its members had a constructor or destructor) an
internal error occurred.
[EW14149] -
An internal error was generated for a switch case value which was out of range
for the switch type.
[EW14304] -
The compiler sometimes generated incorrect code when dividing with, and
comparing with -1 in a single statement.
[EW14344] -
In some cases loops with
long long
loop counters could be optimized incorrectly.
[EW14345] -
Incorrect code is no longer generated for
long long
decrements.
[EW14347] -
Fix of several problems regarding bitfields in
long long
base types.
[EW14357, EW14361, EW14362, EW14366, EW14378] -
An internal error with the message "Jump distance too far for B" could occur in
some rare situations.
[EW14358] -
Casting between
float
and thelong long
signed
andunsigned
types failed in Thumb mode when using the software floating-point runtime library. The library functions handling the casts used a return sequence that was not compatible with the v4 instruction set. Therefore, the Thumb state was not preserved by these casting operations.
[EW14365] -
Side effects of function calls was not correctly handled for global bit fields.
[EW14367] -
The intrinsic function
__QFlag()
, which is declared in inarm.h, is now correctly acknowledged as an intrinsic function by the compiler.
[EW14405] -
All functions (including, but not limited to, all relay functions) are now
KEEP_WITH_NEXT instead of REORDER. This prevents them from being reordered at
link time, if packed placement (-P) is used. This is only an issue for
applications larger than 4 Mbyte.
[EW14454] -
Float comparison could result in an internal error at the highest optimization
level when using the vector floating-point (VFP) unit.
[EW14669] -
Compares with 0.0 when generating code for VFP was sometimes done as if the
hardware supportes subnurmal-numbers.
[EW14670] -
Template functions and member functions of class templates that were not inline
(implicitly or explicitly) could cause an internal error in the compiler.
[EW14680] -
The intrinsic function
__CLZ()
gave an internal error when compiled at optimization levels above 3.
[EW14723] -
The extra 'new constructor'/'delete destructor' routines generated by the
compiler when optimizing for space should be marked as tentative if the class
involved is a template class, even if the corresponding constructor/destructor
is not tentative. The compiler failed to do this, which could result in
multiply defined symbol errors when linking.
[EW14746] -
In some cases an assignment to a member in a structure variable could be
erroneously eliminated, if the member was assigned a variable and that variable
was assigned in all basic blocks preceding the basic block containing the
structure variable declaration.
[EW14760] -
Optimization no longer treats
~(x - y)
as-(x - y)
.
[EW14788] -
Printf
format string characters above 0x7F were not handled correctly.
[EW14897] -
When trying to avoid unnecessary setting of the
vtable
pointer in the constructor for abstract classes, if the class has a member variable that is an array of objects requiring construction, the compiler could hit an assertion in the internal file lower_init.c.
[EW14909] -
When generating a constructor or destructor for an unnamed structure or class
(for example, because one of its members had a constructor or destructor) an
internal error occurred.
[EW14911] -
Converting numbers using
wcstoul()
with more than 9 decimal digits gave the wrong result.
[EW14921] -
The extra 'new constructor'/'delete destructor' routines generated by the
compiler when optimizing for space should be marked as tentative if the class
involved is a template class, even if the corresponding constructor/destructor
is not tentative. The compiler failed to do this, which could result in
multiply defined symbol errors when linking.
[EW14931] -
A structure that only containes small integral types plus another structure of
small integral types generated 32-bit LDR/STR instructions when operating on
non-aligned data objects.
[EW15593] -
In some situations the access to a variable could be hoisted above an
assignment to that variable.
[EW16828]
V3.40C 2003-12-12
-
ELF/DWARF debug information for variables located in VFP double registers could
not be handled by the linker. A linker internal error was generated.
[EW14206] -
In some cases expressions containing a negation could cause an internal error
if the expression below the negation was an associative and commutative
expression with several constants.
For example certain expressions with succeeding minus signs, as in-(108000000-(temp-108000000))
.
[EW14293, EW14532] -
Missing intrinsic function declarations of
__get_CPSR()
and__set_CPSR()
have been added to the inarm.h header file.
[EW14300] -
In some cases loops with
long long
loop counters were optimized incorrectly.
[EW14345] -
If a function that was compiled as
__monitor __thumb __interwork
did not destroy any registers that had to be restored, for example if the function body was empty, an internal error was generated.
[EW14445] -
Some standard I/O library functions was linked into the application even if not
used.
[EW14465] -
When common sub-expression elimination (CSE) was enabled in the compiler
optimizer, some constructs were previously optimized incorrectly. An example of
such a statement is:
k = i + j + k;
[EW14497]
V3.40B-P1 2003-10-06
-
Compiling with VFP enabled in ARM mode, and declaring a function with
__thumb
in the same translation unit, could cause an internal error at optimization levels above 3.
[EW14210, EW14211] -
The runtime library routine
??div8_a
has been corrected so that it now makes a full 32-bit sign-extension of the divisor and dividend, as opposed to a 16-bit one, prior to performing the actual division operation. The previous behavior was not a bug according to the C standard, but it could unnecessarily lead to an "undesired" result.
[EW14239] -
The result from signed 8- and 16-bit divide and modulo operations is now
(correctly) sign extended.
[EW14298] -
Optimizations based on register content tracking did not function correctly for
multidimensional arrays. This could result in incorrect optimization of an
access to an element in a multidimensional array, if two or more paths through
the function could reach the access and at least one of the paths contained an
assignment to the same element. Single dimensional arrays could also be
affected if they were clustered. This problem only occured on optimization
levels above 3.
[EW14342, EW14354] -
Structures small enough to fit within a register could in some cases be read
with incorrect alignment, that is with a single large read instruction instead
of several small ones. This resulted in an undefined behavior.
[EW14353] -
The expression
X-(Y*Z)
was incorrectly coded asFMSC[S|D]
instead ofFNMAC[S|D]
when using VFP. Since this type of expressions are present in the sourcecode forsin()
,cos()
, andcosh()
, applications using these library functions were affected.
[EW14359, EW14373, EW14389] -
VFP function pointers were previously not recognized as the default function
type.
[EW14360] -
Using VFP and casting a
float
to anunsigned int
orlong
could give the wrong rounding mode depending on the rounding mode set inFPSCR
. Previously, theFTOUIS
instruction was used, but the rounding mode ofFTOUIS
depends onFPSCR
and gives the wrong result unless round towards zero is set inFPSCR
. Now, theFTOUIZS
instruction is correctly used instead.
[EW14363] -
Using VFP and casting a
double
to asigned int
orlong
could give the wrong rounding mode depending on the rounding mode set inFPSCR
. Previously, theFTOSID
instruction was used, but the rounding mode ofFTOSID
depends onFPSCR
and gives the wrong result unless round towards zero is set inFPSCR
. Now, theFTOSIZD
instruction is correctly used instead.
[EW14364]
V3.40A 2003-07-03
-
Compiler assembly output in interwork mode could fail to assemble.
[EW13604] -
A loop containing a condition, where a loop counter was multiplied with a value
greater than 1 and compared to a constant, could, if certain additional
conditions were met, be optimized incorrectly due to rounding errors when
loop-peeling optimizations were performed. For example:
int i, res; for (i = 0; i < 3; i++) { if((i * 2) < 1) res = 0; else res = 1; printf("i=[%d]:res=[%d]\n", i, res); }
Loop-peeling optimizations are only attempted when there is a maximum of three basic blocks within the loop and the highest optimization level (-z9/-s9
) is used.
[EW13695] -
When using Thumb mode and a
long long
, or a value whose temporary internal representation waslong long
, was part of a struct and located at an offset of 124 (bytes) within the struct, the compiler sometimes tried to generate syntactically illegal code. As a result, an internal error was generated.
[EW13702] -
The global optimizer could in very special cases lose track of a temporary
result.
[EW13925] -
In some rare cases, the global optimizer could make incorrect assumptions of
the contents of a clustered variable,
b
, inside a loop. Incorrect code was generated in these cases. For this to occur, the loop must reside within an if-else statement, it cannot changeb
but must change another variable in the same cluster, andb
must be assigned in the other clause of the if-else statement. For example:int a; int b; void f(void) { if(a < b + 2) { while(a + b <= 0) a++; } else { b = b + 2; } }
[EW13936] -
In some cases, inner loops could be optimized incorrectly if the trip count
depended on the loop counter in a surrounding loop, the surrounding loop had a
trip count of 2, and the loop counter in the surrounding loop counted down.
[EW13937] -
In some cases, nested loops could be optimized incorrectly if the exit test in
the inner loop jumped directly to the test in the outer loop. For example:
x = ...; while (--x > 0) { y = ...; while (--y > 0) { ... } /* no code from outer loop here */ }
[EW13942] -
When
SFB
orSFE
directives were used on segments containing tentative segment parts (PUBWEAK
symbols), one such tentative segment part was used in the calculation ofSFB
/SFE
, and the chosen definition of the segment part was located in a different segment than the tentative one, XLINK could generate the wrong value for theSFB
/SFE
.
[EW13972] -
The compiler could produce different object code depending on the execution
environment, such as the host operating system used. However, the generated
code was correct in all cases.
[EW14003] -
Signed compare on
long long
was previously performed incorrectly. The generated code performed an all-signed compare, when it should have done a signed compare on the high 32-bit word and an unsigned compare on the lower part.
[EW14020] -
The sign-on message for the
--segment
command line option has been corrected. The sign-on message is displayed when invoking the compiler from the command line by typing "iccarm" only.
[EW14044] -
Const objects which are located at an absolute address, and either implicitly
initialized to zero or explicitly initialized to any value, were previously
incorrectly placed together with located no_init (const and non-const) objects
in the HUGE_AN segment. Now, they are correctly placed in the HUGE_AC segment.
[EW14050] -
In some cases volatile global variables could lose the volatile attribute if
they were clustered. Clustering was performed on
high
optimization level (-z9/-s9
) only. For example:int y; int z; int volatile x; void f(void) { x = y; x = z; }
[EW14051] -
All printf formatters, such as
%d
and%s
, gave an incorrect output when the_Printf_small
formatter was used.
[EW14068] -
The following example previously generated Thumb
ADD
andSUB
instructions in ARM mode, which resulted in an internal error.char x[8]; void foo(void) { *(int*)&x[1] = 1; }
[EW14070] -
An internal error could be generated when compiling Thumb code containing
certain forms of 32-bit integer multiplications.
[EW14093] -
A loop containing a condition, where a scaled loop counter was compared to a
constant, could be optimized incorrectly if the test was for (non-)equality and
the value was reached during the final iteration through the loop.
[EW14096] -
Signed long long division with negative numbers gave wrong sign on quotient and
remainder.
[EW14117] -
Long long arithmetic right shift failed if high word was all ones.
[EW14118] -
Alignment of complex objects like character arrays is now set to 4. The
previous alignment of one was not a bug according to ANSI, but could cause code
written for other ARM compilers to fail at runtime due to unaligned accesses.
As an example, this could happen when casting a character pointer to an int
pointer.
[EW14123] -
Passing a pointer to long long as argument to a function could cause an
internal error.
[EW14126] -
Standard input in C-SPY with library buffered I/O enabled did not work. In
addition, redirecting stdin from a file in C-SPY caused an application error.
If library buffered I/O was disabled, the standard input worked correctly.
[EW14174]
V3.30B 2003-03-18
-
When the compiler generated relay functions to Thumb assembler library
routines, for example
??divu32
,??div32
,??divu16
,??div16
,??divu8
, and??div8
, it accidentally destroyed the contents of non-scratch register R11. R11 is seldom used by Thumb code generation, but in ARM functions which call Thumb library code, this problem could surface if relay functions were needed. Now relay functions correctly use scratch register R12 instead.
[EW10737, EW13614] -
When performing crossjump or hoisting optimizations, which is done on
optimization levels
-z9/-s9
, the compiler incorrectly assumed that all inline assembler routines were identical. This could lead to an overly aggressive use of these optimization techniques, which resulted in incorrect code sequences to be generated.
[EW13638] -
The compiler produced incorrect type information when compiling a file which
contained a struct, one of whose fields was a pointer to another struct, and
where the first struct was used in a context where its size or any offsets into
it were not needed. The type information for the second struct was incorrect,
which could lead to numerous incorrect type conflict warnings when linking.
[EW13651]
V3.30A 2003-02-18
-
va_arg()
now works for structs that are not word-aligned.
[EW10145] -
Formatted I/O functions, like
printf
, can now handlelong long
.
[EW10898] -
The combined number of variables/functions per file is no longer limited to
64k.
[EW12299] -
Using the same segment name multiple times as an argument to the
__sfb()
or__sfe()
intrinsic functions resulted in an internal error:
Internal Error: [Front end]: compare_constants: bad address constant kind
[EW12783] -
In some cases, assignments to elements in arrays with an unspecified size could
be removed if the same element was used exactly once later in the same basic
block.
[EW12790] -
A remark that had been converted to a warning could not be suppressed using the
--diag_suppress
command line option.
[EW12847] -
An internal buffer overflow could occur if a very long file name was used in
combination with a very long function name. When this happened, the result
could either be no diagnostic message, or one of the following two internal
errors:
Internal error: [write_ABS_UBROF A01]: Illegal tag (P0: 0, P1: 0)
or
Internal error: [any]: Unexpected exception
[EW12851] -
A casted pointer expression could result in an internal error similar to:
Internal Error: [AsmLine - OgAsm]: Error[43]: Illegal effective address
ADD R1,#+0x2
[EW12883, EW12884] -
Peephole optimization of additions, where the first operand was known to be
smaller than the type of the addition and the other operand was a negative
constant, did not take the effects of propagated carry bits into account. If
only a part of the sum was used (for example by shifting or masking the sum)
and those bits came from the bits known to be cleared in the first operand, the
result was optimized incorrectly.
[EW12973] -
Incorrect code was generated for a pure 32-bit division when the divisor was a
constant with a value of 2^n, and optimization was turned on. The problem was
an incorrect mask constant.
[EW12975] -
If a multiplication of two
long long
numbers was made in Thumb mode inside a leaf function (a function that does not call any other functions), the link register was not properly preserved for function return, which resulted in an eternal loop.
[EW12979] -
If a switch statement contained only case constants that were impossible to
reach due to the size of the switch expression type, an internal error occurred
when no optimization was used.
[EW12983] -
Accessing an element of an array in a packed structure type could cause a
spurious warning:
Pa039: use of address of unaligned structure member
[EW12997] -
In some cases where several structure members were assigned loop invariant
values, the optimizer could mistakenly use the value from another member.
[EW13030] -
The compiler could get into an infinite loop for certain loop constructs at
optimization level
-z6
and above.
[EW13031, EW13048] -
An assignment from an array element to another in the same array could be
optimized away at optimization level 4 and above, if the only use of the array
after the assignment was to pass the array pointer itself to another function.
[EW13068] -
Negating variables of type
long long int
previously generated incorrect code.
[EW13077] -
At optimization level
-z4
or higher, the compiler could give an internal error with the message:illegal state
[EW13160] -
Incorrect code could be produced when the common subexpression and code motion
optimizations were turned on (optimization level 7 and above).
[EW13169] -
Multiplying a variable with itself could result in an unpredictable instruction
(operand combination) being generated in Thumb mode.
[EW13171, EW13362] -
In some cases, the sum of two expressions, where both expressions could be
expressed as k*x + m (k and m are constants and x is a loop variable), could be
calculated incorrectly.
[EW13184] -
The compiler could hang on certain code constructs.
[EW13185] -
There was a problem in auto-variable allocation that could cause two array or
struct variables to be allocated to the same space on the stack, even when they
were both alive at the same time.
[EW13186] -
The code generated for a constant shifted by a 2^n scaled value inside a loop
was incorrect, when compiled with High speed optimization.
[EW13222] -
Common subexpression elimination depended on memory allocation order and could
eliminate different expressions if the executing environment changed, for
example if different operating systems were used.
[EW13251] -
In some cases, optimization of repeated assignments could remove an assignment
to an auto variable, even though it was still used.
p = q; p->next = p; p->prev = p;
could be transformed to
p->prev = p->next = q;
[EW13299] -
When creating a temporary value from a common subexpression, the creation could
be lifted above assignments to clustered variables that were part of that
common subexpression. This caused the wrong clustered variable to be accessed.
[EW13332] -
Thumb functions declared
__irq
no longer generate an internal error. But note that__irq
functions cannot be compiled as__thumb
.
[EW13337] -
XLINK could erroneously report a type conflict for cases where some type
attributes (like
const
orvolatile
) were part of atypedef
type.
[EW13345] -
If a loop contains multiple occurrences of variables that are only incremented
in the loop, the increments of those variables can be hoisted out of the loop.
The order of the hoisted increments no longer depend on memory allocation
order.
[EW13352] -
When compiling a
new/delete
expression in C++ code at optimizations of Medium or High, and the code for the constructor/destructor was not visible, the compiler sometimes referred to the special 'new constructor'/'delete destructor' by an incorrect name, resulting in undefined external errors when linking.
[EW13359] -
A comma expression containing an assignment where a constant address was
assigned another constant,
*(unsigned char *)0x1234 = 17
, caused an internal error.
[EW13375] -
The assembler output generated from a string literal beginning with a tab
character could not be assembled.
[EW13552] -
If there were several calls with a different number of parameters via a relay
function to a vararg or K&R function, one of the parameters could be
destroyed.
[EW13564] -
Inline assembler with several functions in different modes (
__arm/__thumb
) in the same source file could cause an internal error.
[EW13581] -
In some cases, a common subexpression containing a clustered variable could be
hoisted across a definition of that variable, if it occured in the same basic
block as the common subexpression.
[EW13593] -
Incorrect code was sometimes generated when combining shift and zero extension
operations.
[EW13915] -
When doing char (8-bit) arithmetics causing overflow, the generated code could
make use of the overflowed value, that is, a larger value than 8 bits.
[EW14191] -
When compiling code containing a combination of left and right shifts, the
compiler performed an incorrect optimisation using a constant mask. This mask
was calculated for an unsigned int even when the actual type used was signed
int.
[EW14688] -
Compiling code which used a combination of shift left and shift right, the
compiler did an erroneous optimisation using a constant mask. This mask was
calculated for an unsigned int even when the actual type used was signed int.
[EW14688]
V3.21A 2002-09-27
-
#pragma segment = <name>
Declares a segment name that can be used in the segment operators __segment_begin and __segment_end. Example:
#pragma segment = "MYSEG" __huge
-
__segment_begin(<name>)
__segment_end(<name>)
The __segment_begin operator denotes the start address of the segment with the name <name>, which must be a string literal and must have been declared in a segment pragma at an earlier point in the compilation unit. The __segment_end operator denotes the address immediately after the last byte in the segment. The type of these operators is pointer to void. If a memory attribute is entered in the segment pragma declaring the segment, the type is pointer to <memory> void, otherwise the type is a default pointer to void. The operator given in the example has the type "void __huge *".
Example:
__segment_begin("MYSEG")
-
#pragma required
The #pragma required will introduce a requirement from a symbol to another symbol, i.e. if the first symbol is in the produced output when linking the other symbol should also be in that output. This is useful if, for instance, a function that handles certain data should only be used if there is any data to handle.
Syntax: #pragma required=symbol where symbol is any statically linked function or variable. The #pragma must be placed in front of a symbol definition.
An example:void func(void) { // handle segment S or longVariable here } #pragma required = func // longVariable requires f long longVariable @ "S"; // longVariable resides in segment S
- The option --diagnostics_tables file|directory produces all possible diagnostics to a file. The default extension is txt. Default filename, if only a directory is specified, is diagnostics_tables.txt. It should only be used as a separate option to the compiler. This option is usefull if you have used #pragma diag... but forgot to document why, etc.
- Libraries for big endian are now included.
-
Loop-invariant optimizations depended on OS memory allocation order.
[EW13215] -
Inlined code could in rare cases give the following error:
Internal Error: [GoSyncStuff::FindPrecedingSync]: cannot find unique sync node.
[12852] -
The compiler now generates the Thumb mnemonics LDRSB and LDRSH instead of the
older LDSB and LDSH.
[EW12310] -
Loop optimizations could generate incorrect array index.
[EW12325, EW12326, EW12409] -
Code that handles small unaligned structures could generate an internal error.
[EW12403] -
Code for casting to signed and unsigned long long could sometimes result in
incorrect values.
[EW12404] -
Code generated to access to nonaligned structures could be incorrect.
[EW12405, EW12406] -
A constanttable inserted after a function that had been cross-jumped could
result in an internal error.
[EW12407] -
An optimization bug could cause incorrect code to be generated.
[EW12408] -
Short elements in a union stored in a register could be incorrectly aligned.
[EW12410] -
A cast operation could sometimes incorrectly be optimized away.
[EW12512] -
The code generated by the compiler could change depending on the compiler
execution environment. The generated code was correct but the size could
differ. The sensitivity to change in execution environment could be moving to a
different Windows OS, changing the environment settings, length of file paths
and other changes that could change the memory allocation order within the
compiler process.
[EW11219, EW12580]
V3.20A 2002-06-18
- The runtime model has changed from version 3.11A. The current __rt_version is 4.
-
ARM instruction set version 5TE is now supported.
To use it add command line option --cpu {target core or architecture name}. - It is now possible to mix code compiled with small and large code models.
- The interworking code model is now supported through the new command line option --interwork.
- The calling convention is now ATPCS as default. Interwork must still be added if needed to a function with function-type attribute __interwork or globally with the command line option --interwork.
- Access to floating point flags has been re-engineered. Refer to the file MathFloatFlags.h for more information.
- Two functions from the ANSI C99 standard have been included: snprintf() and vsnprintf().
-
Evaluation of else-if could be performed incorrectly at high speed optimization
in Thumb mode.
[EW12287] -
The char pointer member of a structure object used as parameter was not passed
correctly to the called function. This occurred at high optimization levels.
[EW12248] -
The combination of Thumb mode and high speed optimization could lead to
incorrect code when testing bitfield values.
[EW12227] -
Structure return values from __pcs functions that are less than 32-bit and not
aligned to an even 4-byte address would be returned indirectly using an
implicit extra parameter.
[EW10358] -
Register mismatch in debug information between compiler and linker when output
was ELF/DWARF.
[EW10703] -
Library functions assert, strchr and strrchr could not be used with string
literals in C++.
[EW10899] -
The compiler could previously generate multiplication instruction with
undefined behavior: MUL R0,R0,R4.
[EW11114] -
The intrinsic functions __sfb/sfe could only be used once per segment, multiple
uses would result in link failure.
[EW11122] -
A small part of the runtime library was broken. It used the wrong register in a
BX instruction.
[EW12060] -
Certain __swi function definitions could result in an incorrect warning.
[EW11247] -
The compiler generated incorrect code for switch statements where the body code
and at least one case except the last did not end with a break or a goto.
[EW11336, EW11337, EW11360] -
The compiler could generate incorrect code for a bitfield value test at
high-speed optimization.
[EW11371] -
Nested loops using the same loop variable could be optimized incorrectly if the
increment or decrement of the loop variable preceded the inner loop.
[EW11372,EW11423] -
Read access to smaller union fields in register allocated unions could destroy
other union fields of different size.
[EW11373, EW11381] -
Some code optimization and analysis problems were corected. They either
resulted in "Internal error" or the compiler never terminated.
[EW11374, EW11375, EW11376] -
Corrected a problem where partial object assignments were interpreted as an
assignment of the whole object. This could cause incorrect elimination of
assignments.
[EW11377, EW11418, EW11424, EW11427] -
The compiler is now a little more restrictive when optimizing address
expressions. This avoids incorrect assumptions while compiling code that does
not conform to ANSI C.
[EW11378, EW11422] -
Variable initialization could in some cases be optimized away.
[EW11380] -
Sometimes loops that were unrolled to straight line code could be optimized
incorrectly.
[EW11416, EW11425] -
When for or while loops were fully unrolled, side effects in the test would not
be executed for the final iteration.
[EW11417, EW11426] -
Expressions like a > b + 1 were rewritten as a > = b, but that changed
the behavior when the expression b + 1 would have overflowed.
The ANSI C standard allows the transformation, since the behavior at overflow is unspecified. But the expressions are no longer transformed since it changed the expected behavior.
[EW11490, EW10978] -
Using integer division or modulo in __ramfunc could result in an internal
error.
[EW11999] -
Relay from located functions could result in:
Internal error [OgModuleLabels::Def::Define]: Label already defined.
[EW12011] -
A number of code-generation and optimization bugs have been corrected.
[EW11419, EW11420, EW11421,EW11862]
-
The file checkDefs.i included by cstartup.s79 was missing from the
distribution.
[EW11223] -
The code generated for __disable_interrupt() has been rewritten in a more
secure way.
[EW11143] -
Crossjump between two or more small functions could destroy LR is the distance
between them is too far.
[EW12808]
V3.11A 2001-12-04
- The floating point library now has exception flags. Refer to the file MathFloatFlags.h for more information.
- Long long is now supported, except in the formatted I/O functions.
- A new command line option, --omit_types, omits function/variable type info in object output.
-
An assignment between two elements from packed structures could generate a
misaligned access.
[EW10299] -
Structure parameters to __pcs functions larger then 64 bit or not aligned to an
even 4-byte address were always placed on the stack.
[EW10357] -
__pcs functions could in some cases get incorrect backtrace information.
[EW10359] -
Several corrections in long long support.
[EW10364] -
Loop optimization could hoist an expression before its definition.
[EW10421] -
String literals now have the type "array of const char" in C++.
[EW10542] -
Values casted to and compared in a type smaller than 32-bit could be destroyed.
[EW10569] -
When compiling a while loop following immediately after a case label in a
switch, the compiler could crash if high optimization was used (-s9 or -z9).
[EW10725] -
The intrinsic functions __sfb, __sfe and __sfs yield an error when the referred
segment is not otherwise used in the module.
[EW10757] -
Cross call optimization could generate a fatal error in some cases where
several similar functions had multiple exits.
[EW10807] -
Register allocation could in some rare cases with extreme register pressure
generate a "coloring failed" error.
[EW10868]
V3.10A 2001-10-02
- The runtime model has changed from version 2.10. The current __rt_version is 2.
- New floating point library with smaller code size and greatly improved speed.
- Debug information is improved, with better variable information and backtrace.
-
A switch statement of the form switch(a-b<=0) at higher optimization levels
than 3 caused the wrong case to be selected.
[ARMC0021] -
Inline expansion of memcpy() could produce the wrong result.
[ARMC0022] -
Assignment loop using loop index caused incorrect code at -z9.
[ARMC0027] -
Bitfields could not be larger than 255 bits.
[LB397] -
Global optimizer problems which resulted in internal error has been corrected
[EW10178 (LB399)] -
Global optimizer problems which resulted in incorrect code has been corrected.
[EW10082, EW10102, EW10180 (LB401), EW10181 (LB402), EW10182 (LB403)] -
Call via function pointer now sets the correct mode bit in return address.
[EW10313] -
A problem in the register allocation algorithm could cause "Internal error:
[CgDriver]: Coloring failed".
[EW10087] -
Too aggressive optimizations when shifting bitfields.
[EW10080] -
Call to a variadic __pcs function with K&R declaration with different
number of arguments could cause an internal error.
[EW10083] -
A faulty optimization rule could cause Thumb instructions to use illegal high
registers.
[EW10292] -
Header files for C++ not installed.
[EW10294] -
The gmtime() could cause corrupt tm structure values for arbitrary time values,
the tm_mday for example could turn negative. There was also a problem that the
mktime() function could corrupt tm structure values.
[EW10363]
V2.10D 2001-06-27
-
Loop optimizations have been reorganized and several problems have been
corrected.
[Lb 355,375,376,379,382,390,396] -
Corrected a problem in the ARM mode peephole optimizations. Could cause an
unintialized register to be used.
[ARMC0018] -
Corrected a problem that caused compiler to loop if ARM mode was used and the
code had a large modulo expression.
[ARMC0017] -
Part of the exit sequence could be optimized away (restoring high registers in
Thumb mode).
[ARMC0016] -
Fixed problem where a constant casted to a pointer caused incorrect code
randomly.
[ARMC0015] -
CStartup used to have a reference to SVC_STACK that was neither used in the
code nor declared in the standard linker command file lnkarm.xcl.
[ARMC0011] -
#pragma swi_number can now be fitted to either the function declaration or the
function definition.
[ARMC0009] -
Fixed code for passing structures as parameters. The code was either incorrect
or the stack was not aligned correctly.
[ARMC0007]
V2.10A 2001-02-21
- The compiler now supports Embedded C++.
- It is now possible to choose between big and little endian byte order.
- Support for the ARM9TDMI core has been added.
-
The following command line options have been added or changed:
-
--ec++
add support for ec++ syntax -
--cpu [arm7tdmi | arm9tdmi]
select processor -
--endian [big | little]
select memory format -
--no_scheduling
disables instruction scheduling
-
-
A program with struct accesses in different scopes but casted from the same
variable could be transformed incorrectly.
[Lb 388] - Too aggressive optimizations with partial updates of variables.
- A change of sign was sometimes introduced in unsigned character switches.
-
Incorrect code was generated in loops at high speed optimizations.
[Lb 381] -
An internal error was received when the > operator was used with unequal
types in loops at high optimizations.
[Lb 380] -
The recognition code for packed structures was incorrect.
[Lb 378] -
A problem occuring when accessing fields in packed structures has been
corrected.
[Lb 374] -
Accessing array members of struct return values could give an internal error.
[Lb 365] -
Correcting a problem occuring in Thumb mode on high optimization level when
adding a constant offest to an address (label).
[ARMC0004] -
The following code used to give an internal error:
int fn_dbl(double);
int fn_dbl(f) float f; { do_nothing(&f); return 97; }
[Lb 364]
V1.30C 2000-10-14
-
A problem in cstartup has been corrected, constants where put after each
segment even when fall-through was used.
[ARMC0003] -
A problem sometimes resulting in an internal error "coloring failed" in Thumb
mode has been corrected.
[ARMC0002]
V1.30A/B 2000-09-28
-
Support for handling interrupt functions has been added.
The following function type attribute keywords have been added:- __irq - declares an interrupt function.
- __fiq - declares a fast interrupt function.
- __swi - declares a software interrupt function.
-
The following #pragma directive has been added:
#pragma swi_number=<number>
For more information about interrupt functions, see Manual corrections in this document, tutor\interrupt_example.c, inc\arm_interrupt.h, and src\lib\swi_handler.s79. -
The following intrinsic functions have been added:
-
__intrinsic int __sfb(void *)
- returns address to beginning of segment -
__intrinsic int __sfe(void *)
- returns address to end of segment -
__intrinsic int __sfs(void *)
- returns size of segment
-
-
Code for spilling and unspilling high registers in Thumb mode has been
corrected.
[ARMC0001] - A problem that under some circumstances could result in a never-ending compiler internal loop is corrected.
- Volatile objects referred by a pointer, are now handled correctly.
V1.20A 2000-05-28
-
The following C library functions will under certain circumstances be handled
as intrinsic functions and will generate inline code instead of an ordinary
library call:
memcpy, memset, strcpy, strlen, strncpy, strcat, strcmp, strncmp
V1.10B 2000-01-14
- Minor corrections.
- Switch statements in ARM mode are now implemented more efficiently, using jump tables.
V1.10A 1999-12-30
- First release.