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