A small testcase:

#include <stdlib.h>
extern unsigned int whatever(unsigned char *);

__attribute__((noreturn)) int main(void)
{
  whatever(NULL);
  for(;;);
}

If you compile this code without -mthumb, gcc asm output is as such:

       .file   "pqp.c"
        .text
        .align  2
        .global main
        .type   main, %function
main:
        @ Volatile: function does not return.
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        mov     r0, #0
        bl      whatever
.L2:
        b       .L2
        .size   main, .-main
        .ident  "GCC: (GNU) 4.3.2"


... Or, in other words, it correctly avoids to preserve the link register.

With -mthumb, it pushes lr to the stack, which is the same behaviour as
removing the noreturn attribute.

The thing becomes relevant when main is a complex function that does not
return: it pushes not only lr, but several otherwise clobbered registers to the
stack which it won't pull back in, thus wasting stack space forever. As you can
imagined, in embedded targets every byte counts. when compiling to arm mode
(not thumb), it avoids preserving these since it has nowhere to return them to.


-- 
           Summary: attribute `noreturn' isn't effective when -mthumb param
                    is active
           Product: gcc
           Version: 4.3.2
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: alexandre dot nunes at gmail dot com
GCC target triplet: arm-unknown-elf


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38203

Reply via email to