Hi,
I recently came across some bug in my program that I could narrow down
to the snipped below (also attached with a Makefile).
extern unsigned int _vector_table;
int main(void)
{
unsigned int *vector_base = &_vector_table;
if (vector_base == 0) {
return 1;
} else {
return 2;
}
}
The code generated for this function is (I tested a couple of different
compilers and architectures (4.7, 4.9 and 5.2)):
0000000000000000 <main>:
0: b8 02 00 00 00 mov $0x2,%eax
5: c3 retq
If my understanding is correct, this is a legal optimization under the
assumption that no object may reside at address 0, resulting in the
optimized out if branch.
Though, my understanding is that the switch
'-fno-delete-null-pointer-checks' would remove that assumption allowing
such code to be compiled "correctly" (I'm on an embedded system and code
at 0 is actually important).
Could somebody tell me what the correct way for implementing something
like that would be? Or whether this is actually a gcc issue?
Thanks,
Sören
extern unsigned int _vector_table;
int main(void)
{
unsigned int *vector_base = &_vector_table;
if (vector_base == 0) {
return 1;
} else {
return 2;
}
}
CC ?= gcc
OBJDUMP = objdump
CFLAGS = -Wall -fno-delete-null-pointer-checks -O2
-fno-delete-null-pointer-checks
SRC = main.c
all: $(SRC:.c=.dump) $(SRC:.c=.s) $(SRC:.c=.o)
%.dump: %.o
$(OBJDUMP) -DS $< > $@
%.s: %.c
$(CC) $(CFLAGS) -S $< -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -rf *.o *.s *.dump