https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94075

            Bug ID: 94075
           Summary: When using linker-generated list, bad optimization
                    performed in -O2
           Product: gcc
           Version: 5.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fabrice.girardot at flowbird dot group
  Target Milestone: ---

Created attachment 47992
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47992&action=edit
Test case + Makefile to reproduice bug

GCC does a wrong optimization in -O2 when using linker-generated lists, when
such a list is empty.

Linker-generated lists are convenient to automatically group items at link
time.
A 0-sized item array is located at start of list (section ".foo_1").
A 0-sized item array is located at end of list (section ".foo_3").
All other items with section ".foo_2" will automatically be located between the
top and bottom tags.

When there is *NO* item with section ".foo_2", the list is empty, the start and
end addresses are the same.
When compiling with "-O2", gcc assumes start and end addresses can't be equal,
and always enter the for() loop in the attached example.

If attached example is compiled with "-O0" (please edit Makefile), then
generated code is correct.

This bug was found on arm-none-eabi-gcc version 6.2.1 with a real linker script
for STM32 micro-controller, and the result is an embedded hard fault.
For convenient testing under Linux, the Makefile in the attached zip file
automatically generates a linker script to add a section for linker-generated
lists.

==================================
Correct output result (example compiled with -O0):
----------------------------------
$ make clean && make
rm -rf output
gcc -dumpversion
5.4.0
gcc -c -std=c99 -O0 -DOPTIMIZE="\"-O0\"" -o output/main.o src/main.c
ld --verbose \
    | sed -n '/===/,$p' \
    | sed '/===/d' \
    | sed -e '/.rodata[ ]*:/a   .foobar : { KEEP(*(SORT(.foo_*))); } ' \
    > output/test.ld
gcc -Wl,-Map=output/test.map -T output/test.ld -o output/test output/main.o
$ output/test
I am compiled with '-O0' !
start = 0x4006a0
end   = 0x4006a0
==================================
Wrong optimization (example compiled with -O2)
----------------------------------
$ make clean && make
rm -rf output
gcc -dumpversion
5.4.0
gcc -c -std=c99 -O2 -DOPTIMIZE="\"-O2\"" -o output/main.o src/main.c
ld --verbose \
    | sed -n '/===/,$p' \
    | sed '/===/d' \
    | sed -e '/.rodata[ ]*:/a   .foobar : { KEEP(*(SORT(.foo_*))); } ' \
    > output/test.ld
gcc -Wl,-Map=output/test.map -T output/test.ld -o output/test output/main.o
$ output/test
I am compiled with '-O2' !
start = 0x400680
end   = 0x400680
[0] p = 0x400680 ; *p = 0
[1] p = 0x400684 ; *p = 52
[2] p = 0x400688 ; *p = 5
[3] p = 0x40068c ; *p = -736
[4] p = 0x400690 ; *p = 128
[5] p = 0x400694 ; *p = -672
[6] p = 0x400698 ; *p = 168
[7] p = 0x40069c ; *p = -480
[8] p = 0x4006a0 ; *p = 80
[9] p = 0x4006a4 ; *p = -224
Aborting...
==================================

Reply via email to