This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/MSP-EXP430FR5994: MSP430 TI v17.9.0 compiler doesn't allow malloc of size larger than 32758 bytes in large data model due to compiler generating incorrect constant comparison

Part Number: MSP-EXP430FR5994
Other Parts Discussed in Thread: MSP430FR5994

Tool/software: TI C/C++ Compiler

Was using a MSP430FR5994 to check the limits on the heap size supported by the TI MSP430 compiler, with the project configured to use the 208 Kbyte FRAM2 region for the heap and the data model set to large.

One test involved determining the maximum size allocation malloc() would return when the heap was empty.

With the TI v17.9.0 compiler the maximum size allocation was 32758 bytes which was lower than expected and only part of the heap. Whereas with the TI v18.1.0 compiler the maximum size allocation was 212988 bytes.

On investigation both compiler versions have the same check_alloc_size() call at the start of malloc() in the RTS memory.c source file:

/*****************************************************************************/
/*                                                                           */
/*  CHECK_ALLOC_SIZE - Verify that an allocation of the requested size is    */
/*                     possible without an overflow during the process.      */
/*                                                                           */
/*****************************************************************************/
inline static int check_alloc_size(size_t size)
{
    /*-----------------------------------------------------------------------*/
    /* Make sure the value of size is small enough that we will not overflow */
    /* the memsz_t type in the malloc/realloc calculations.  SDSCM00049633.  */
    /*-----------------------------------------------------------------------*/
    if (size > (MEMSZ_MAX - OVERHEAD - MINSIZE - 1))
        return 0;
    return 1;
}
    
void *malloc(size_t size)
{
    memsz_t allocsize;
    PACKET *current, *next, *prev;
    
    if (check_alloc_size(size) == 0) return 0;
    
    allocsize = (memsz_t)size;

The TI v17.9.0 compiler generates the following for check_alloc_size():

        malloc():
004000:   144A                PUSHM.A #5,R10
209         if (size > (MEMSZ_MAX - OVERHEAD - MINSIZE - 1))
004002:   930D                TST.W   R13
004004:   2029                JNE     ($C$L18)
004006:   903C 7FF7           CMP.W   #0x7ff7,R12
00400a:   2C26                JHS     ($C$L18)
265         allocsize = (memsz_t)size;

Whereas the TI v18.1..0 compiler generates the following for check_alloc_size():

        malloc():
004000:   144A                PUSHM.A #5,R10
209         if (size > (MEMSZ_MAX - OVERHEAD - MINSIZE - 1))
004002:   903D 7FFF           CMP.W   #0x7fff,R13
004006:   2804                JLO     ($C$L11)
004008:   2029                JNE     ($C$L19)
00400a:   903C FFF7           CMP.W   #0xfff7,R12
00400e:   2C26                JHS     ($C$L19)
265         allocsize = (memsz_t)size;
        $C$L11:

The TI v17.9.0 compiler appears to have generated incorrect code for check_alloc_size(), in that it is checking for a maximum size of 0x7FF6 rather than 0x7FFFFFF6. Is this a problem with how the TI v17.9.0 compiler handles comparisons against constants in the large data model?

While the problem was found in the malloc() implementation in the RTS not sure under which other conditions incorrect comparisons could occur.

The example project is attached MSP430FR5994_max_heap_size.zip

  • Thank you for concisely pointing out the problem.  The root cause is in the header file stdint.h.  MEMSZ_MAX is defined as PTRDIFF_MAX, which comes from stdint.h.  In version 17.9.0.STS, under large data model, PTRDIFF_MAX is incorrectly set to INT16_MAX.  In version 18.1.x.LTS, under large data model, PTRDIFF_MAX is correctly set to INT32_MAX.  

    The fix is to upgrade to the latest 18.1.x.LTS release, which is presently 18.1.1.LTS.  With rare exceptions, bugs found in any STS release are not fixed in that release, but in the following release.

    Because I don't understand how this happened, I filed CODEGEN-4514 in the SDOWP system to have this investigated.  I want to be sure the fix is intentional, and not the side effect of some unrelated change.  You are welcome to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George

  • George Mock said:
    In version 17.9.0.STS, under large data model, PTRDIFF_MAX is incorrectly set to INT16_MAX.

    Thank you for the information. I didn't spot that.

    From a quick look I think the same problem also exists in ti-cgt-msp430_16.9.6.LTS/include/stdint.h (based upon looking at the output from --gen_preprocessor_listing).

  • I added 16.9.6.LTS to the list of versions affected by the bug.  This means the bug will be fixed in a future 16.9.x.LTS release.

    Thanks and regards,

    -George