Tool/software: TI C/C++ Compiler
Hello,
We found very well hidden compiler's bug during testing CGT 8.3.4. Problem manifested on startup, when C++ constructors are called, so it was very hard to detect root cause and find temporary WA, but we managed to prepare local reproduction basing on ASM listings. I'm attaching sample code with class/struct hierarchy required to reproduce issue:
#define SIZE_OF_BIG_STRUCT 10200 #define NUM_OF_BIG_MEMBERS 4 typedef unsigned char u8; typedef unsigned int u32; typedef u8 TUsedSizeType_t; typedef enum { EContext1 = 0, EContext2, EContext3, EMaxContexts } EContextTypes_t; struct SimpleStructWithConstructor { SimpleStructWithConstructor(u32 arg = 9) { y = arg; } u32 y; }; template <typename SIZE_TYPE> struct CommonContextPart { SIZE_TYPE own; SIZE_TYPE nextFreeIndex; u8 group : 7; u8 inUse : 1; }; template <u32 ContextId, typename s_t> struct Context_t { }; template <typename size_type> struct Context_t <(u32)EContext1, size_type> : public CommonContextPart<size_type> { u32 bigArrayToSimulateBigContent[SIZE_OF_BIG_STRUCT]; SimpleStructWithConstructor m_simpleStructWithConstructor; }; typedef Context_t<(u32)EContext1, TUsedSizeType_t > BigStruct; struct SmallStruct { void init() { x = 3; } u32 x; }; struct TestClassCtx { TestClassCtx(); BigStruct m_bigMember[NUM_OF_BIG_MEMBERS]; SmallStruct m_smallMember; }; TestClassCtx::TestClassCtx() : m_bigMember() { m_smallMember.init(); } int main(void) { TestClassCtx testVar; }
In ASM file, please don't focus on "main" function, as it isn't problematic one (in original code we have pools, where placement new is called, so stack usage in "main" is not problem in our software). Instead, we are interested in compiler's generated auxiliary function $P$F0. It isn't affected with CGT7, but with CGT8 stack consumption is horrible huge. Our ASM experts translated affected code into C++ language as something like:
void constructor(int8_t *ptr) { int8_t tempSpace[40808]; memset(tempSpace, 0, sizeof(tempSpace)); memcpy(ptr, tempSpace, sizeof(tempSpace); }
We prepared some findings regarding sample code:
- This code generates $P$F0 function. Local frame size is small for CGT7, but extremely big for CGT8 (memset is visible in inline comment).
- Our temporary WA works - removing member initialization from initializer list (line 64) seems to “solve” problem.
- Affected structure is “template <typename size_type> Context_t <(u32)EContext1, size_type>” (lines 37-38). It contains a huge array to simulate big content.
- It seems, that issue occurs only, when struct has no user-defined constructor, but has at least one member with user-defined constructor. Issue disappears with following independent conditions:
- “SimpleStructWithConstructor” has no user-defined constructor (lines18-21 commented out);
- Member “m_simpleStructWithConstructor” is removed from “template <typename size_type> struct Context_t <(u32)EContext1, size_type>”;
- “template <typename size_type> struct Context_t <(u32)EContext1, size_type>” has only constructor’s declaration “Context_t();” – no definition is required to “solve” issue.
Fix for this bug is extremely important for us, because we are not able to detect such type of problem easily till crash occurrs. We would like to receive correction with RSA intrinsics at the latest.
Best Regards,
ZD