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.