I was debugging a function and by inserting the debug statement crashed the system. Some investigation revealed that gcc 4.3.2 arm-eabi (compiled from sources) with -O2 under some circumstances assumes that if a pointer is dereferenced, it can not be NULL therefore explicite tests against NULL can be later eliminated. Here is a short function that demonstrates the erroneous behaviour:
extern void Debug( unsigned int x ); typedef struct s_head { struct s_head *next; unsigned int value; } A_STRUCT; void InsertByValue( A_STRUCT **queue, A_STRUCT *ptr ) { A_STRUCT *tst; for ( tst = *queue ; ; queue = &tst->next, tst = *queue ) { // Debug( tst->value ); if ( ! tst ) { ptr->next = (void *) 0; break; } if ( tst->value < ptr->value ) { ptr->next = tst; break; } } *queue = ptr; } Compiling this function with arm-eabi-gcc -O2 -S foo.c generates perfect code. However, if the Debug( tst->value ); is not commented out, then the generated code looks like this: InsertByValue: @ Function supports interworking. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 stmfd sp!, {r4, r5, r6, lr} mov r6, r0 ldr r4, [r0, #0] mov r5, r1 b .L3 .L2: mov r6, r4 ldr r4, [r4, #0] .L3: ldr r0, [r4, #4] bl Debug ldr r2, [r4, #4] ldr r3, [r5, #4] cmp r2, r3 bcs .L2 str r4, [r5, #0] str r5, [r6, #0] ldmfd sp!, {r4, r5, r6, lr} bx lr As you can see, when 'tst' is fetched to R4, it is not checked against being 0 anywhere and the whole if ( ! tst ) { ... } bit is completely eliminated from the code. Indeed, the actual compiled code crashes because the loop does not stop when the end of the list is reached. I know that you are not supposed to dereference a NULL pointer, however, on the microcontroller I have it is perfectly legal: what you get is an element of the exception vector table that resides at 0x0. I don't think that the compiler has a right to remove my test, just because it assumes that if I derferenced a pointer then it surely was not NULL. At least it should give me a warning (which it does not, not even with -W -Wall -Wextra). Zoltan