Tool/software: TI C/C++ Compiler
If I have the following code
extern unsigned char __heap[512];
#define mid ((void *)__heap + 256)
#define end ((void *)__heap + 512)
void func(void)
{
void *ptr = end;
do {
*(unsigned char *)ptr = 1;
ptr -= 32;
} while (ptr > mid);
}
I get suppressible warnings about void pointer arithmetic but the produced code is incorrect under all optimisation levels.
Under opt_level=0 I get the following:
;** 9 ----------------------- ptr = &__heap+512;
.dwpsn file "ptrloop.c",line 9,column 15,is_stmt,isa 0
MOV.W #__heap+512,r15 ; [] |9|
;* --------------------------------------------------------------------------*
;* BEGIN LOOP $C$L1
;*
;* Loop source line : 10
;* Loop closing brace source line : 13
;* Known Minimum Trip Count : 1
;* Known Maximum Trip Count : 4294967295
;* Known Max Trip Count Factor : 1
;* --------------------------------------------------------------------------*
$C$L1:
;** -----------------------g2:
;** 11 ----------------------- *(unsigned char *)ptr = 1u;
.dwpsn file "ptrloop.c",line 11,column 9,is_stmt,isa 0
MOV.B #1,0(r15) ; [] |11|
;** 13 ----------------------- if ( (ptr -= 32) > &__heap ) goto g2;
.dwpsn file "ptrloop.c",line 13,column 14,is_stmt,isa 0
SUB.W #32,r15 ; [] |13|
CMP.W #__heap+1,r15 ; [] |13|
JHS $C$L1 ; [] |13|
; [] |13|
;** ----------------------- return;
where you can see that the comparison is against `__heap+1` rather than `__heap+257`.
Under opt_level=4 I get the following:
MOV.W #__heap+512,r15 ; [] |9|
;** ----------------------- #pragma MUST_ITERATE(16, 16, 16)
;** ----------------------- #pragma LOOP_FLAGS(0u)
;** ----------------------- L$1 = 16;
MOV.W #16,r14 ; []
;* --------------------------------------------------------------------------*
;* BEGIN LOOP $C$L1
;*
;* Loop source line : 10
;* Loop closing brace source line : 13
;* Known Minimum Trip Count : 16
;* Known Maximum Trip Count : 16
;* Known Max Trip Count Factor : 16
;* --------------------------------------------------------------------------*
$C$L1:
;** -----------------------g2:
;** 11 ----------------------- *(unsigned char *)ptr = 1u;
.dwpsn file "ptrloop.c",line 11,column 9,is_stmt,isa 0
MOV.B #1,0(r15) ; [] |11|
;** 13 ----------------------- ptr -= 32;
.dwpsn file "ptrloop.c",line 13,column 14,is_stmt,isa 0
SUB.W #32,r15 ; [] |13|
;** 13 ----------------------- if ( L$1 = L$1-1 ) goto g2;
SUB.W #1,r14 ; [] |13|
JNE $C$L1 ; [] |13|
; [] |13|
;** ----------------------- return;
Where you can see that the loop runs 16 times where it should only run 8.
From what I can tell I don't have a problem if the result of void pointer arithmetic is stored, only in comparisons. This should be fixed, or else the void pointer arithmetic warning should be changed to an error.