Known Issues in the Compiler

The following bugs have currently been confirmed in the compiler.


  1. (Fixed in ARMCC 4.1 b576) Even when optimization is enabled, optimization of the command order is not enabled.
  2. (Fixed in ARMCC 5.01 b34) Even when using #pragma push/pop, the diagnostic message cannot be saved.
  3. (Fixed in ARMCC 4.1 b918) When the std::stable_sort function is executed, delete with NULL specified and new with 0 Bytes specified are called.
  4. (Fixed in ARMCC 4.1 b909) After updating ARMCC 4.1, you cannot have mixed operators in vector mode.
  5. (Fixed in ARMCC 4.1 b640) Invalid code is generated when writing array access via an inline function in a for statement with -Otime -O3 optimization.
  6. (Fixed in ARMCC 4.1 b911) When using a precompile header in ARMCC 4.1, internal faults sometimes occur.
  7. (RVCT 4.0) There is a bug in the loop optimization process enabled by the -O3 -Otime combination.
  8. (RVCT 4.0) Warning: C3007E appears when building.
  9. (RVCT 4.0) When the --gnu option is specified when using a STL algorithm, a warning is issued.
  10. (Fixed in ARMCC 4.1 b619) Increasing optimization results in erratic operations of the ? operator.
  11. (Fixed in ARMCC 4.1 b654) With the -Otime -O3 optimization, invalid values are written in the array with the for loop.
  12. (Fixed in ARMCC 4.1 b713) When calling a function that uses nn::math::Matrix, the arguments are sometimes corrupted.
  13. (Fixed in ARMCC 4.1 b791) The results of a shift calculation differ depending on the optimization level.
  14. (Fixed in ARMCC 4.1 b907) When the introsort_loop function is used, a large volume of recursive calls occurs.
  15. (Fixed in ARMCC 4.1 b791) When the optimization level is raised, writing to unintended addresses may occur.
  16. (Fixed in ARMCC 4.1 b713) for loops that use unsigned integer decrements sometimes enter infinite loops.
  17. (Fixed in ARMCC 4.1 b713) Signed value and unsigned value conversions cannot be performed at times.
  18. (RVCT 4.0) When compiling functions that use inline keywords with the -O3 and -Otime options, invalid values are sometimes used with the comparison expression.
  19. (Fixed in ARMCC 4.1 b640) With the -Otime and -O3 optimizations, the final portion of the array is passed and an invalid read operation occurs.
  20. (Fixed in CTR-SDK 5.0) "Warning 977 virtual function override intended?" is suppressed.
  21. (Fixed in ARMCC 4.1 b698) With -Otime -O3 optimization, invalid parameters are passed with a function call to inside the unnamed namespace.
  22. Warnings such as #634-D and #631-D are displayed.
  23. Internal errors occur with the template to generate zero-size arrays.
  24. (Fixed in ARMCC 4.1 b911) The compiler generates an internal fault when precompiled headers are used.
  25. (Fixed in ARMCC 4.1 b1247) With -Otime -O3 optimization, sometimes arrays are set with invalid values.
  26. (Fixed in ARMCC 4.1 b1247) With -O2 or higher optimization, sometimes calculations no longer perform correctly.
  27. (Fixed in ARMCC 4.1 b1247) With -Otime -O3 optimization, sometimes calculations are not performed in the correct order.
  28. (Fixed in ARMCC 4.1 b1307 and ARMCC 5.04 b27) With -Otime -O3 optimization, an invalid variable initialization is sometimes performed.
  29. (ARMCC 5.x) After updating to ARMCC 5.x, when specifying --gnu, the overload functions in the function templates are not resolved to be argument-dependent.
  30. (Fixed in ARMCC 4.1 b1307) After updating to ARMCC 4.1 b1247, pointers to static data are sometimes set to NULL when -O3 -Otime optimization is used.
  31. (ARMCC 5.x) After updating to ARMCC 5.x, the build fails when the path contains double-byte characters.
  32. (ARMCC 4.1 b1440) (Fixed in ARMCC 5.04 b49)With -O2 or higher optimization, an invalid offset is sometimes used to write to a structure member variable.
  33. (Fixed in ARMCC 5.04 b49) After updating to ARMCC 5.x, the compiler sometimes shuts down improperly if the source uses an unnamed namespace.
  34. (Fixed in ARMCC 4.1 b1440 and ARMCC 5.04 b82) With -Otime -O3 optimization, sometimes code with invalid loops is generated.
  35. Sometimes fails to compile when error is specified for --diag_warning.
  36. (ARMCC 4.1) (Fixed in ARMCC 5.04 b14) Sometimes object files are not generated when error is specified for --diag_suppress
  37. An internal fault occurs when functions that use alloca are made into inline functions with __forceinline.
  38. (ARMCC 4.1) (Fixed in ARMCC 5.04 b146) When optimizing with the -Otime -O3 options, sometimes the function that initializes variables is called twice.
  39. (ARMCC 4.1) When optimizing with the -Otime -O3 options, sometimes the function that initializes variables is called twice in the loop.
  40. When the size of the container that is assigned content by std::vector::operator= is reduced, an invalid size is passed to the deallocate member of the Allocator class.

1.

Symptom

Even when optimization is enabled, optimization of the command order is not enabled.

Cause

In some cases, the pre-scheduler optimization does not operate as expected.

Versions That Have This Problem

- ARMCC 4.1 b576 and earlier
- RVCT 4.0

Workaround

None.

State of Support

- Fixed in ARMCC 4.1 b576.
- No revision plans for RVCT 4.0.


2.

Symptom

Even when using #pragma push/pop, the diagnostic message cannot be saved.

Cause

This bug originated in the compiler.
The state where diag_suppress is specified cannot be saved with #pragma push/pop.

Versions That Have This Problem

- ARMCC 4.1
- RVCT 4.0

Workaround

None.

State of Support

- Fixed in ARMCC 5.01 b34.
- No revision plans for ARMCC 4.1 and RVCT 4.0.


3.

Symptom

When the std::stable_sort function is executed, delete with NULL specified and new with 0Bytes specified are called.

Cause

There is a bug in the Rogue Wave C++ library used with RVCT.

Versions That Have This Problem

- ARMCC 4.1
- RVCT 4.0

Workaround

None.

State of Support

- Fixed in ARMCC 4.1 b918.
- No revision plans for RVCT 4.0.


4.

Symptom

After updating ARMCC 4.1, you cannot have mixed operators in vector mode.
For example:

  vfpassert vector<3>
  fmuls    s16<3>, s8<3>, s0<>
  vfpassert scalar

Error:
error A1422: This combination of vector and scalar operands is not allowed
Also, if the fmuls line is changed as shown below, a different error occurs.
  fmuls    s16<3>, s8<3>, s0<1>

Error:
error A1416: Vector length does not match current vector length 3

Cause

There is a bug in armasm included in ARMCC 4.1.

Versions That Have This Problem

- ARMCC 4.1

Workaround

None.

State of Support

- Fixed in ARMCC 4.1 b909.


5.

Symptom

With a -Otime -O3 optimization, when you write an array access by using an inline function in a for statement, invalid code is generated.
In code such as the following, an unhandled exception occurs.

--
struct Vec 
{ 
 Vec() : x(0), y(0) {} 
 int x, y; 
}; 
  
class Array 
{ 
public: 
 Array(); 
 Vec* get() { return mArray; } 
private: 
 Vec mArray[ NUM ]; 
}; 
  
Array::Array() 
{ 
 for( int i = 0;  i < NUM;  ++i ) 
 { 
   mArray[i].x = i; 
   mArray[i].y = i; 
 } 
} 
  
void test() 
{ 
    Array*  a = new Array; 
    Vec*    v = a->get(); 

    for( int i = 0;  i <= NUM-1;  ++i ) 
    {
        a->get()[i].y = 0; // The unhandled exception happens here.
    }
}
--

Cause

We are investigating the cause, but this symptom does not occur after ARMCC 4.1 b640.

Versions That Have This Problem

- ARMCC 4.1 b640 and earlier versions
- RVCT 4.0

Workaround

Specify #pragma Ospace in the relevant function.

--
#pragma push
#pragma Ospace
void test() 
{
...
}
#pragma pop
--

State of Support

- This problem does not occur after ARMCC 4.1 b640.
- No revision plans for RVCT 4.0.


6.

Symptom

When using a precompile header in ARMCC 4.1, internal faults sometimes occur.

Cause

There is a bug in the front end portion of the compiler.

Versions That Have This Problem

- ARMCC 4.1

Workaround

Because there is no effective workaround, do the following so that the precompile header is not read.
Note: Add the following pragma to the start of the source code for the side reusing the PCH (--use_pch).

--
#pragma hdrstop
#include "test.h" // Precompiled header.
--

State of Support

- Fixed in ARMCC 4.1 b911.


7.

Symptom

There is a bug in RVCT 4.0 in the loop optimization process enabled by the -O3 -Otime combination.
The result of the following code is uncertain for a Release build.

--
#include<nw/gfx.h>
using namespace nw::math;

static MTX34 OptErrSub2()
{
  return MTX34::Identity();
}

inline MTX34 operator*(const MTX34 &lhs, const MTX34 &rhs)
{
  MTX34 res;
  MTX34Mult (&res, &lhs, &rhs);
  return res;
}
inline f32 OptErrSub1()
{
  MTX34 mf = OptErrSub2()*OptErrSub2();
  return mf.a[0];
}
f32 OptErrTest()
{
  f32 res;
  s32 ok = 1;
  do {
    res = OptErrSub1();
  } while( ok == 0 );
  return res;
}
--

Cause

With this code, in the OptErrTest function, operator* and the OptErrSub1 function are expanded inline.
At that time, the loop optimization process cannot correctly handle the variable mf attribute in the function, and a value is read from outside the loop.
For that reason, an invalid value is set in the res variable that uses the value returned from the OptErrSub1 function.

Versions That Have This Problem

- RVCT 4.0

Workaround

Because there are no plans to update RVCT 4.0, use the following.

--
#pragma push
#pragma Ospace
f32 OptErrTest()
{
・・・
}
#pragma pop
-- 

State of Support

No revision plans for RVCT 4.0.


8.

Symptom

"Warning: C3007E" is displayed at build time with RVCT 4.0.

Cause

This problem was a bug in RVCT 4.0.
If this error does not occur with ARMCC 4.1, there is no problem with the generated code.

Versions That Have This Problem

- RVCT 4.0

Workaround

- Add --diag_suppress=3007 to the command-line option.
- Insert the following in the relevant locations.

    #pragma push
    #pragma O0
    // Relevant function (function for which warning 3007 is issued).
    #pragma pop

State of Support

No revision plans for RVCT 4.0.


9.

Symptom

When the --gnu option is specified when using a STL algorithm, a warning is displayed.

Cause

RVCT 4.0 had a bug that displayed inappropriate warnings.

Versions That Have This Problem

- RVCT 4.0

Workaround

None.

State of Support

No revision plans for RVCT 4.0.


10.

Symptom

The ? operator functions erratically when the optimization level is increased.

Cause

This bug originated in the compiler.
During loop optimization, the compiler improperly handles the calculation conditional expression for the absolute value of the difference between two unsigned variables. This bug occurs for code such as the following.

--
unsigned foo(unsigned *curr, unsigned *last)
{
   unsigned tot = 0;
   for(int i = 0; i < 10; ++i) {
       unsigned diff = (curr[i] >= last[i]) ? (curr[i] - last[i]) :
(last[i] - curr[i]);
       tot += diff;
   }
   return tot;
} 
--

Versions That Have This Problem

- ARMCC 4.1 b619 and earlier versions
- RVCT 4.0

Workaround

Lower the optimization level for the relevant portion.

State of Support

- Fixed in ARMCC 4.1 b619.
- No revision plans for RVCT 4.0.


11.

Symptom

With the -Otime -O3 optimization, invalid values are written in the array with the for loop.

Cause

There is a bug in the loop optimization enabled with -Otime -O3.
For the following code, the first write operations are performed before the intended address.

--
static __declspec(noinline) void test(u32 seed) 
{ 
    u32 x = (seed | 1U) & 0xFFFFFFFFU; 
    u32 *s = &sState[1]; 
    int j; 

    for(*s++=x, j=N; --j; *s++ = (x*=69069U) & 0xFFFFFFFFU) 
    { 
        ;
    } 
} 
--

Versions That Have This Problem

- ARMCC 4.1 b654 and earlier
- RVCT 4.0

Workaround

You can avoid this bug by specifying #pragma Ospace.

--
#pragma push
#pragma Ospace
static __declspec(noinline) void test(u32 seed) 
{
...
}
#pragma pop
--

State of Support

- Fixed in ARMCC 4.1 b654.
- No revision plans for RVCT 4.0.


12.

Symptom

When calling a function that uses nn::math::Matrix, the arguments are sometimes corrupted.

Cause

This bug originated in the compiler.
With a call to a function using nn::math::Matrix34, as shown below, the argument passed with the const reference becomes corrupted.

--
#include<nn.h>

using nn::math::Matrix34;

Matrix34 func(const Matrix34& in)
{
Matrix34 out(0.0f, 0.0f, 0.0f, 0.0f,
      0.0f, 0.0f, 0.0f, 0.0f,
      0.0f, 0.0f, 0.0f, 0.0f);
  // The out address and in address are the same.
 in.Report(); // in is already corrupted.

 out.f._00 = in.f._00; // A correct result cannot be obtained.

return out;
}

void nnMain(void)
{
 Matrix34 a(1.0f, 2.0f, 3.0f, 4.0f,
      5.0f, 6.0f, 7.0f, 8.0f,
      9.0f, 1.0f, 2.0f, 3.0f);

 a = func(a);
 a.Report();

 return;
} 
--

Versions That Have This Problem

- ARMCC 4.1 b713 and earlier versions
- RVCT 4.0

Workaround

You can avoid this problem by storing the func return value in a temporary variable.

--
//a = func(a);
 MTX34 tmp = func(a);
 a=tmp; 
--

State of Support

- Fixed in ARMCC 4.1 b713.
- No revision plans for RVCT 4.0.


13.

Symptom

The results of a shift calculation differ according to the optimization level.

When the following code is executed, the result of a Debug build differs from that of a Release build.

#include <stdio.h>

#include <nn/os.h>
#include <nn/dbg.h>

extern "C" void nnMain()
{
    s16 buff[ 2 ] = { 0xffff, 0x00ff };
    u32 data = (u32)( buff[ 0 ] | buff[ 1 ] << 16 );

    NN_LOG( "%08x\n", data );
    
    while(1){}
}

Results
・ For Debug: ffffffff
・ For Release: 00ffffff

Cause

There is a bug in the rotation optimization that is enabled when -O2 or higher is specified, and the sign extension becomes invalid.

Versions That Have This Problem

- ARMCC 4.1 b791 and earlier versions.

Workaround

Change the optimization level in the function in the relevant code.

#pragma push
#if __OPTIMISE_LEVEL >= 2
#pragma O1
#endif
extern "C" void nnMain()
{
    s16 buff[ 2 ] = { 0xffff, 0x00ff };
    u32 data = (u32)( buff[ 0 ] | buff[ 1 ] << 16 );

    NN_LOG( "%08x\n", data );

    while(1){}
}
#pragma pop

State of Support

- Fixed in ARMCC 4.1 b791.


14.

Symptom

When the std::sort function is used, a large volume of recursive calls occurs.

Cause

There is a bug in the std::__introsort_loop function used in the std::sort function.
Depending on the data passed, a large volume of recursive calls occurs, and a stack overflow may be caused.

Versions That Have This Problem

- ARMCC 4.1
- RVCT 4.0

Workaround

You can avoid this problem by inserting the following code before the __introsort_loop function in the 956th line of include/algorithm.cc.

__max_depth /= 2;

State of Support

- Fixed in ARMCC 4.1 b907.
- No revision plans for RVCT 4.0.


15.

Symptom

When the optimization level is raised, writing to unintentional addresses occurs.

When the following code is built with an optimization level of 3, writing to an unintended address occurs.

void arm11_test(void)
{
    unsigned char    dst_obj[64 * 4];
    unsigned char    ref_obj[64 * 4];
    unsigned char    *dst;
    unsigned char    *ref;
    unsigned long    rx = 1;
    unsigned long    v0, v1, v2, v3, v4;
    signed long        ref_skip;
    signed long        i;

    dst    = dst_obj;
    ref    = ref_obj;
    ref_skip = rx;
    
    for (i = 0; i < 3; i++) {
        v0 = *(unsigned long *)(ref + 0);
        v1 = *(unsigned long *)(ref + 1);
        v2 = *(unsigned long *)(ref + 2);
        v3 = *(unsigned long *)(ref + 3);
        v4 = (unsigned long)*(  ref + 4);
        
        v0 = (unsigned long)(((v0) >> 1) | ((v1) << 1));
        v1 = (unsigned long)(((v1) >> 1) | ((v2) << 1));
        
        *(unsigned long *)(dst)    = v0;
        *(unsigned long *)(dst + 4) = v1;
        
        v2 = (unsigned long)(((v2) >> 1) | ((v3) << 1));
        v4 = (unsigned long)(((v3) >> 1) | ((v4) << 1));
        
       // The expectation is that data will be written to an address 64 bytes away from dst,
       // but instead data is stored at an address 72 bytes away.
        *(unsigned long *)(dst + 64)    = v2;         
        *(unsigned long *)(dst + 64 + 4) = v4;
        
        ref += ref_skip;
        dst += 8;
    }
}

Cause

There was a bug in the process for the compiler to optimize LDM/STM instructions.

Versions That Have This Problem

- ARMCC 4.1 b791 and earlier versions.

Workaround

Because this optimization is enabled with -O2 or higher, you can use the following method to avoid this problem.

#pragma push
#pragma O1
void arm11_test(void)
{
   // Omitted.
}
#pragma pop

State of Support

- Fixed in ARMCC 4.1 b791.


16.

Symptom

for loops that use unsigned integer decrements sometimes enter infinite loops.

When compiling with -O3 -Otime, for loops that use unsigned integer decrements may become infinite loops.

Cause

There was a bug in the compiler.
For -O3 -Otime optimization, the compiler can generate code that is an infinite loop. This problem occurs when the end condition of a for loop using an unsigned integer decrement is specified to reach a maximum value.

This problem occurs with code similar to the following.

----------------------------
for( unsigned int i = 100; i != (unsigned int)-1 ; --i )
{
 ...
}
----------------------------

Versions That Have This Problem

- ARMCC 4.1 b619 and earlier versions
- RVCT 4.0

Workaround

You can avoid this problem by replacing with an increment loop and changing the code so that no comparison to (unsigned)-1 is performed.

State of Support

- Fixed in ARMCC 4.1 b713.
- No revision plans for RVCT 4.0.


17.

Symptom

Signed value and unsigned value conversions cannot be performed at times.

When RVCT 4.0/ARMCC 4.1 is used and code similar to the following is compiled,
the compiler cannot correctly convert signed values and unsigned values.

u16 uVal = 0x999c;
s16 sVal = *(s16*)&uVal;
int intVal = (int)sVal;

Note: Even though the value for intVal is supposed to be 0xFFFF999c (-26,212), 0x999c (39,324) is entered.

Cause

This bug originated in the compiler.

Versions That Have This Problem

- ARMCC 4.1 b713 and earlier versions
- RVCT 4.0

Workaround

Try using a method to explicitly have sign extensions by either setting s16 sVal = (s16)uVal, or by using a signed integer as a temporary variable, as shown below.

u16 uVal = 0x999c;
s32 tmp = *(s16*)&uVal;
s16 sVal = (s16)tmp;
int intVal = (int)sVal;

State of Support

- Fixed in ARMCC 4.1 b713.
- No revision plans for RVCT 4.0.


18.

Symptom

When compiling functions that use inline keywords with the -O3 and -Otime options, invalid values are sometimes used with the comparison expression.

Cause

There was a bug in the compiler common subexpression elimination optimization.

Versions That Have This Problem

- RVCT 4.0

Workaround

There are no plans to revise RVCT 4.0, so add the following #pragma to the function on the side that calls the inline function to avoid the problem.

#pragma push
#pragma Ono_cse
float hogehoge(unsigned int var1)
{
・・・
}
#pragma pop 

State of Support

- No revision plans for RVCT 4.0.


19.

Symptom

With the -Otime and -O3 optimization, the final portion of the array is passed and an invalid read operation occurs.

Cause

With Otime and -O3 optimization, the compiler applies loop rotation modification for the purpose of prefetching data to repeat the following.
The result is that an invalid read operation sometimes occurs when the final portion of the array is passed.

This bug occurs for code such as the following.

int test(int* input, int length)
{
  int r = 0;
  for (int i = 0; i < length; i++)
  {
      r += *input++;
  }
  return r;
}
When the end of a memory loop is used in the array region, an access violation sometimes occurred.

Versions That Have This Problem

- ARMCC 4.1 b640 and earlier versions
- RVCT 4.0

Workaround

You can avoid this problem by specifying #pragma Ospace.

#pragma push
#pragma Ospace
int test(int* input, int length)
{
...
}
#pragma pop

State of Support

- Fixed in ARMCC 4.1 b640.
- No revision plans for RVCT 4.0.


20.

Symptom

"Warning 997 virtual function override intended?" is suppressed.

When you include <nn/fs.h>, the warning message "Warning 997 virtual function override intended?" is suppressed.

Cause

This warning is suppressed in <nn/fs.h>. When you include <nn/fs.h>, warning 997 is suppressed because of the influence of Even when using #pragma push/pop, the diagnostic message cannot be saved.
.

Versions That Have This Problem

- ARMCC 4.1
- RVCT 4.0

Workaround

#include <nn/fs.h>
After the preceding code, if the following code is written,
#pragma diag_warning 997
the warning can be displayed. 

State of Support

- This bug was fixed in CTR-SDK 5.0.


21.

Symptom

With -Otime -O3 optimization, invalid parameters are passed with a function call to inside the unnamed namespace.

Cause

There was a bug in the compiler.
During optimization, inline expansion of functions in the unnamed namespace is not performed appropriately.
With the following code, the incorrect code is generated with the function in the unnamed namespace.

namespace
{
  volatile int& s_Reg = *reinterpret_cast(0x00100000);

  void Test0(int x)
  {
      s_Reg = x;
  }
}

void Test1()
{
  Test0(0x1234);

  int tmp;
  __asm { mrs     tmp, cpsr }
}

void Test2()
{
  Test0(0x5678);
}

Versions That Have This Problem

- ARMCC 4.1 b640 and earlier versions
- RVCT 4.0

Workaround

Because there are no plans to revise RVCT4.0, you can avoid this bug by specifying #pragma Ospace.

namespace
{
  volatile int& s_Reg = *reinterpret_cast(0x00100000);

#pragma push
#pragma Ospace
  void Test0(int x)
  {
      s_Reg = x;
  }
#pragma pop

State of Support

- Fixed in ARMCC 4.1 b698.
- No revision plans for RVCT 4.0.


22.

Symptom

Warnings such as #634-D and #631-D are displayed.

Cause

The main reason this warning is issued is that the randomization of the address space layout (ASLR) on the host size is enabled, and this may be the problem.

Although it is unclear whether ASLR is enabled with Windows XP, other security software, rather than Windows itself, may be performing an equivalent process.

Versions That Have This Problem

- ARMCC 4.1/5.x
- RVCT 4.0

Workaround

Disable security software during builds.

State of Support

- No plans for revision in the near future.


23.

Symptom

Internal errors occur with the template to generate zero-size arrays.

If you instantiate a template with code like the following, Internal fault: [0x462f69:410683] occurs at compile time.

template
class TEST{
// COMPILE_ASSERT(DIM != 0);
public:
    TYPE _aData[DIM];
    TEST(){}
};

extern "C" void nnMain(){
   
   TEST test;
   
   while(1){}
}

Cause

There is a bug in the front end of the compiler.

Versions That Have This Problem

- ARMCC 4.1/5.x
- RVCT 4.0

Workaround

None.

State of Support

- No fixes are planned for ARMCC 4.1/5.x or RVCT 4.0.


24.

Symptom

The compiler generates an internal fault when precompiled headers are used.

Cause

This bug originated in the compiler.

Versions That Have This Problem

- ARMCC 4.1

Workaround

Use #pragma hdrstop and do not use precompiled headers in source code that causes this issue.

State of Support

- Fixed in ARMCC 4.1 b911.


25.

Symptom

With -Otime -O3 optimization, sometimes arrays are set invalidly.

Cause

This bug involves invalid handling of type information when optimization is enabled with -O3 -Otime.

This bug occurs for code such as the following.

struct Element 
{ 
   float x, y, z, u0, v0, u1, v1; 
}; 

#define DIVISOR 5

void SetData(Element* elements, f32 v0) 
{ 
    Element* e = elements; 
    for (int t = 0; t < DIVISOR + 1; t++) { 
        f32 v = v0 * t; 
        for (int s = 0; s < DIVISOR + 1; s++) { 
            e++->v0 = v; 
        } 
    } 
} 

Versions That Have This Problem

- ARMCC 4.1 b1133 and earlier versions.

Workaround

Use one of the following workarounds.

1) Specify #pragma O2.

#pragma push 
#pragma O2 
void SetData(Element* elements, float v0) 
{ 
// Omitted. 
} 
#pragma pop 

2) Perform an explicit type conversion. (Cast type float.)

    float v = v0 * (float)t; 

State of Support

- Fixed in ARMCC 4.1 b1247.


26.

Symptom

With -O2 or higher optimization, sometimes calculations no longer perform correctly.

Cause

This bug is related to common subexpression elimination optimization.

This bug occurs for code such as the following.

struct  Test { 
   unsigned short  _n; 
}; 

inline static void add(Test* __restrict p)
{ 
   ++p->_n; 
} 

inline static void run(Test* __restrict p) 
{ 
   add( p ); 
   ++p->_n; 
   p->_n += p->_n;
} 

Test    gTest;
extern "C" void nnMain(void)
{ 
   run( &gTest ); 
   nn::dbg::detail::Printf( "\nResult: N = %04x\n", gTest._n ); 
   for( ;; );
} 

Versions That Have This Problem

- ARMCC 4.1 b1133 and earlier versions.

Workaround

As a workaround to this bug, use the -O0 or -O1 option, or specify the private compiler option -Ono_cse_restrict.

State of Support

- Fixed in ARMCC 4.1 b1247.


27.

Symptom

With -Otime -O3 optimization, sometimes calculations are not performed in the correct order.

Cause

There is a bug in the optimization enabled with the -O3 -Otime combination.

This bug occurs for code such as the following.

#pragma no_inline 
class DMY{}; 
void* testSub(DMY, const char* a, size_t* size) 
{ 
   *size = 160; 
   return (void*)a; 
} 
void test() 
{ 
   size_t size; 
   void* p = testSub(DMY(), "hoge", &size); 
   int n = size/8; 
   printf("n: %d\n", n); 
   if (p==NULL) return; 
   printf("p: %s\n", p); 
} 

Versions That Have This Problem

- ARMCC 4.1 b1133 and earlier versions.

Workaround

Use one of the following workarounds.

1) Change the optimization level for the function, and use a combination other than -O3 -Otime.

#pragma push 
#pragma Ospace 
void test() 
{ 
// Omitted. 
} 
#pragma pop

2) Add the private compiler option -Ono_vast and disable only the optimization that is the cause of the bug.

State of Support

- Fixed in ARMCC 4.1 b1247.


28.

Symptom

With -O3 -Otime optimization, invalid variables are sometimes initialized.

Cause

This bug occurs in the loop optimization that is enabled with -Otime -O3.

This bug occurs for code such as the following.

u32 foo()
{
    // Omitted.
    case CASE_ooo:
        for (j = 0, i = 0; j < 2; j++)
        {
            // Omitted.
            for (k = 8; k--; i++)
            {
                p->m_bar[i] = hoge;
                // Omitted.
	    }
        }
    // Omitted.
}
The index was not being created correctly for the operation that stores values in p->m_bar[i], which led to invalid results.

Versions That Have This Problem

- ARMCC 4.1 b1247 and earlier versions.
- ARMCC 5.03 b102 and earlier versions.

Workaround

Use one of the following workarounds.

1) Change the optimization level for the function, and use a combination other than -O3 -Otime.

#pragma push 
#pragma O2
u32 foo()
{ 
// Omitted. 
} 
#pragma pop

2) Handle variable initialization outside the loop.

case CASE_ooo:
    i = 0;
    for (j = 0; j < 2; j++)
    {

State of Support

- Fixed in ARMCC 4.1 b1307.
- Fixed in ARMCC 5.04 b27.


29.

Symptom

After updating to ARMCC 5.x, when specifying --gnu, the overload functions in the function templates are not resolved to be argument-dependent.

Cause

This problem is caused by the GCC bug emulation of the GNU compatibility mode in the front end used in ARMCC 5.x.

This bug occurs for code such as the following.

template
T foo(const U* u) { return foo(const_cast(u)); }

template
T foo(U* u) { return static_cast(u); }

class X {};
class Y : public X {};

const Y* bar(const Y* y, const X* x)
{
    return foo(x);
}
The bar(const Y*, const X*) function calls the foo(const U* u) template. This call strips the const operator from the u argument (because the const_cast operator is used), and calls the foo function. In the C++ standards, the compiler considers the foo function name to be visible. Accordingly, it starts checking the argument dependencies of other overload functions and searches the foo(U * U) function template.

Because GCC does not perform argument-dependendent lookups, it uses foo(const U* u) rather than foo(U *u). This bug originated in GCC and was fixed in 4.4.4, but the ARMCC 5.x GNU compatibility mode emulates the incorrect GCC functionality.

Versions That Have This Problem

- ARMCC 5.x

Workaround

None.

State of Support

To be determined.


30.

Symptom

After updating to ARMCC 4.1 b1247, pointers to static data are sometimes set to NULL when -O3 -Otime optimization is used.

Cause

This bug occurs in optimization that is enabled with -O3 -Otime.

This bug occurs for code such as the following.

class Hoge : HogeBase
{
public :
    static const char* cHoge_A[];
    static const char* cHoge_B[];
private :
    void foo(bool b);
};
const char* Hoge::cHoge_A[]	=
{
    (Omitted)
};
const char* Hoge::cHoge_B[]	=
{
    (Omitted)
};
void Hoge::foo(bool b)
{
    Index       i = GetIndex();
    const char*	pName = b ? cHoge_A[i] : cHoge_B[i];
    (Omitted)
}
An uninitialized value was loaded into pName and NULL was set.

Versions That Have This Problem

- ARMCC 4.1 b1247

Workaround

Use one of the following workarounds.

1) Change the optimization level for the function, and use a combination other than -O3 -Otime.

#pragma push 
#pragma O2
void Hoge::foo(bool b)
{
    (Omitted)
}
#pragma pop

2) Separate ternary operator and variable declarations.

Before:
    const char*	pName = b ? cHoge_A[i] : cHoge_B[i];

After:
    const char* pName;
    pName = b ? cHoge_A[i] : cHoge_B[i];

State of Support

- Fixed in ARMCC 4.1 b1307.


31.

Symptom

After updating to ARMCC 5.x, the build fails when the path contains double-byte characters.

Cause

This bug is related to the compiler front end changed with ARMCC 5.0 or later.

Versions That Have This Problem

- ARMCC 5.x

Workaround

Avoid this problem by not using double-byte characters in the paths used with the build.

State of Support

- To be determined.


32.

Symptom

With -O2 or higher optimization, an invalid offset is sometimes used to write to a structure member variable.

Cause

This bug occurs in optimization that is enabled with -O2 or higher.

This bug occurs for code such as the following.

template< class Hoge1, class Hoge2, int n, typename Hoge3 >
class Hoge
{
public:
	Hoge1* hoge1;
	Hoge2  hoge2a;
	Hoge2  hoge2b;
	Hoge3  hoge3[ n ];
public:
	Hoge() :
		hoge1( 0 ),
		hoge2a( ( Hoge2 )0 ),
		hoge2b( ( Hoge2 )0 )
	{
		::memset( hoge3, 0, sizeof( hoge3 ) );
	}
	void Foo( Hoge1* h1, const Hoge3* h3, size_t len )
	{
		hoge1 = h1;
		::memcpy( hoge3, h3, sizeof( Hoge3 ) * n );
	}
};
Code using the wrong offset during assignment to hoge1 was generated.

This bug is a problem with the optimization process in the final stages of the compilation and the details for the conditions of occurrence cannot be identified, but the following is known.

1) This bug occurs only for a non-volatile store with -02 or higher (either -Ospace or -Otime).
2) This erroneous optimization occurs only with basic blocks containing at least two immediate offset store processes of size 4 or 8 bytes.
3) One requirement for the compiler to reach the block containing the bug is that the source register with the store command is the same as the base register.
One possibility for this occurrence may be when storing a pointer to internal structure of the structure itself.

Versions That Have This Problem

- ARMCC 4.1 b1307 and earlier
- ARMCC 5.04 b27 and earlier

Workaround

Use one of the following workarounds.

1) Change the optimization level of the appropriate function to -O1 or lower.

#pragma push 
#pragma O1
void Bar::Bar()
{
	(Omitted)
	hoge.Foo(this, p, n)
	(Omitted)
}
#pragma pop

2) Do not perform in-line expansion of the function that has this problem.

Before:
	void Foo( Hoge1* h1, const Hoge3* h3, size_t len )

After:
	void Foo( Hoge1* h1, const Hoge3* h3, size_t len )  __attribute__((noinline)); 

State of Support

- Fixed in ARMCC 4.1 b1440.
- Fixed in ARMCC 5.04 b49.


33.

Symptom

After updating to ARMCC 5.x, the compiler sometimes shuts down improperly if the source uses an unnamed namespace.

Cause

This bug is in the ARMCC 5.x compiler front end.

This bug occurs for code such as the following.

1) Combine the unnamed namespace and dynamic_cast.

class Base  {
public:
	virtual ~Base() { }
};

bool is_derived(Base *i_base);

namespace {
class Derived : public Base { };
}

class AClass {
public:
	static bool down_cast_test(Base *i_base) {
		Derived *d = dynamic_cast(i_base);
		return (d != NULL);
	}
};

bool is_derived(Base *i_base){
	return AClass::down_cast_test(i_base);
}

2) Combine the unnamed namespace and the delete class.

namespace
{
    class Foo
    {
    public:
        Foo():_member(0)
        {
        }

        virtual ~Foo()
        {
        }
    protected:
        int    _member;
    };
}


namespace code
{
    class Bar
    {
        Foo*    _member;

        Bar()
        {
            _member = new Foo();
        }
        virtual ~Bar()
        {
            delete  _member;
        }
    };

}

Versions That Have This Problem

- ARMCC 5.04 b27 and earlier

Workaround

Use a named namespace for unnamed namespaces that have this problem.

State of Support

- Fixed in ARMCC 5.04 b49.


34.

Symptom

With -O3 -Otime optimization, sometimes code with invalid loops is generated.

Cause

This bug occurs in optimization that is enabled with -O3 -Otime.

This bug occurs for code such as the following.

void foo( int first, int last )
{
   int sum = 0;
   int i, j;
   for( i = first, j = last; i <= last; j = i++ )
   {
       sum += j;
   }
   NN_LOG( "sum = %d, i = %d, j = %d\n", sum, i, j );
}
In this code, the value for the j variable is computed incorrectly, and the sum variable also takes on an invalid value.

Versions That Have This Problem

- ARMCC 4.1 b1307 and earlier
- ARMCC 5.04 b49 and earlier

Workaround

Specify an optimization level other than -O3 -Otime for the functions.

#pragma push
#pragma O2
void foo( int first, int last )
{
// Omitted.
}
#pragma pop

State of Support

- Fixed in ARMCC 4.1 b1440.
- Fixed in ARMCC 5.04 b82.


35.

Symptom

Sometimes fails to compile when error is specified for --diag_warning.

Cause

Due to a bug, specifying --diag_warning=error to demote all errors that can be demoted to warnings results in errors that are not supposed to be demoted being demoted to warnings anyway. This sometimes causes internal faults or crashes when compiling.

Versions That Have This Problem

- ARMCC 4.1 and 5.x

Workaround

Work around this issue by directly specifying the message number of the error you want to demote, rather than specifying error for --diag_warning.

State of Support

- No revision plans for ARMCC 4.1. - Support for ARMCC 5.x remains undecided.


36.

Symptom

Sometimes object files are not generated when error is specified for --diag_suppress.

Cause

When --diag_suppress=error is specified to hide all errors, sometimes the compiling step ends without generating object files.

Versions That Have This Problem

- ARMCC 4.1
- ARMCC 5.04 b82 and earlier

Workaround

Work around this issue by directly specifying the message number of the error you want to hide, rather than specifying error for --diag_suppress.

State of Support

- No revision plans for ARMCC 4.1. - Fixed in ARMCC 5.04 b146.


37.

Symptom

An internal fault occurs when functions that use alloca are made into inline functions with __forceinline.

Cause

Functions that use alloca cannot be made into inline functions using the inline keyword or through automatic inlining, but there was a bug where specifying __forceinline to inline these functions would sometimes cause an internal fault.

Versions That Have This Problem

- ARMCC 4.1 and 5.x

Workaround

Work around this issue by not specifying __forceinline for functions that use alloc.

State of Support

- No revision plans for ARMCC 4.1. - Support for ARMCC 5.x remains undecided.


38.

Symptom

When optimizing with the -Otime -O3 option, sometimes the function that initializes variables is called twice.

Cause

This bug occurs in optimization that is enabled with the -O3 -Otime option.

This bug occurs for code such as the following.

struct Type1 { Type1(); };
struct Type2 { Type2(); };

struct Builder {
    Type1 method1();
    Type2 method2(Type1);
};

void broken(Builder *builder)
{
    Type1 t1 = builder->method1();  // Called twice.
    const Type2 &t2 = builder->method2(t1);
}
In this code, method1 is called twice because the following generating factors are satisfied.

1: The result (t1) of some method (method1) is passed as the parameter of a different method (method2)
2: The result of this other method (method2) is assigned to a const reference (const Type2 &t2).

Versions That Have This Problem

- ARMCC4.1 b1247 and earlier
- ARMCC5.04 b82 and earlier

Workaround

Use one of the following workarounds.

1) Change the optimization level for the function, and use a combination other than -Otime -O3.

#pragma push 
#pragma Ospace
void broken(Builder *builder)
{
    Type1 t1 = builder->method1();
    const Type2 &t2 = builder->method2(t1);
}
#pragma pop

2) Assign the result of method2 to a regular variable rather than a const.

    Type2 t2 = builder->method2(t1);

State of Support

- A fix is being considered for an additional release of ARMCC4.1.
- Fixed in ARMCC 5.04 b146.


39.

Symptom

When optimizing with the -Otime -O3 option, sometimes the function that initializes variables is called twice in the loop.

Cause

This bug occurs in optimization that is enabled with the -O3 -Otime option.

This bug occurs for code such as the following.

struct X { X(); };
struct Y { Y(); };

X makeX();
bool proc(X, Y);

void broken() {
    Y y;
    while (1) {
        X x = makeX();      // Called twice.
        bool result = proc(x, y);
    }
}
Also, it does not matter how proc is defined, or how x and y are supplied to proc. For example, the problem occurs even with the following code.
struct X { X(); };
struct Y { Y(); };

X makeX();
bool proc(void *, void*);

void *convX(X);
void *convY(Y);

void broken() {
    Y y;
    while (1) {
        X x = makeX();      // Called twice.
        bool result = proc(convX(x), convY(y));
    }
}
In this code, makeX is called twice because the following generating factors are satisfied.

1: Variable x and the scope of result are both inside the loop.
2: Variable x is used to calculate result via a number of functions (proc).
3: The functions (proc) take for their argument a different variable y with a scope outside of the loop.

Versions That Have This Problem

- ARMCC4.1 b1247 and earlier versions

Workaround

Use one of the following workarounds.

1) Change the optimization level for the function, and use a combination other than -Otime -O3.

#pragma push 
#pragma Ospace
void broken() {
{
    (Omitted)
}
#pragma pop

2) Move the declarations for variable x or result outside of the loop (or move both declarations outside of the loop).

void not_broken() {
    Y y;
    bool result;
    while (1) {
        X x = makeX();
        result = proc(x, y);
    }
}

State of Support

- Fixed in ARMCC 4.1 b1454.


40.

Symptom

When the size of the container that is assigned content by std::vector::operator= is reduced, an invalid size is passed to the deallocate member of the Allocator class.

Cause

This is a bug in the C++ library of ARMCC.

The symptom occurs when dest_vector = source_vector is run for std::vector::operator= and all of the following conditions are true.

1: source_vector.size() <= dest_vector.capacity()
2: dest_vector.size() >= source_vector.size()
3: dest_vector.capacity() != source_vector.size()

In this case, the dest_vector.capacity function matches the source_vector.size function, regardless of the assigned size, and an invalid size is passed to the deallocate member of the Allocator class used with vector.

Versions That Have This Problem

- ARMCC 4.1 and 5.x

Workaround

As a workaround, make the revisions show below to the following part of the C++ library include\vector.cc

 vector<_TypeT,_Allocator>::operator= (const vector<_TypeT,_Allocator>& __x) 

Before the revisions:
    else if (size() >= __x.size()) {
        iterator __it = copy (__x.begin (), __x.end (), begin ());
        _C_destroy (__it, end ());
        _C_end_of_storage = _C_finish = _C_start + __x.size();
    }
After the revisions:
    else if (size() >= __x.size()) {
        iterator __it = copy (__x.begin (), __x.end (), begin ());
        _C_destroy (__it, end ());
        _C_finish = _C_start + __x.size();
    }

State of Support

- No revision plans for ARMCC 4.1. - Support for ARMCC 5.x remains undecided.



CONFIDENTIAL