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

Reply via email to