Like GCC (in C mode) G++ accepts attribute noreturn on function pointer declarations, but unlike in C mode then ignores the attribute when the pointer is used to call a function. G++ should be consistent with GCC. In addition, the effects of the attribute on function pointers are not documented in the Common Variable Attributes section of the manual. The attribute should be mentioned there as well and its effects on function pointers should be documented. $ (set -x && cat u.C && for lang in c c++; do gcc -S -Wall -Wunused -Wpedantic -x$lang u.C; done) + cat u.C void (*pf)() __attribute__ ((noreturn)); void (*pg)(); int foo () { pf (); // no warning in C (good), but warning in C++ (bug) } int bar () { pg (); // warning in both C and C++ (good) } + for lang in c c++ + /build/gcc-git/gcc/xgcc -B /build/gcc-git/gcc -S -Wall -Wunused -Wpedantic -xc u.C u.C: In function ‘bar’: u.C:13:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ + for lang in c c++ + /build/gcc-git/gcc/xgcc -B /build/gcc-git/gcc -S -Wall -Wunused -Wpedantic -xc++ u.C u.C: In function ‘int foo()’: u.C:8:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^ u.C: In function ‘int bar()’: u.C:13:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^
Another inconsistency is that when the noreturn attributes decorates a function parameter that is a pointer to a function, C considers it to be a part of the function's type while C++ does not. That means that some otherwise valid code that's accepted in C++ is rejected in C. $ (set -x && cat z.c && for lang in c c++; do gcc -S -Wall -Wunused -Wpedantic -x$lang z.c; done) + cat z.c int f_ptr_noreturn (void (*fp)(void) __attribute__((noreturn))); int f_ptr_noreturn (void (*fp)(void)) { fp (); } + for lang in c c++ + /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -S -Wall -Wunused -Wpedantic -xc z.c z.c:3:5: error: conflicting types for ‘f_ptr_noreturn’ int f_ptr_noreturn (void (*fp)(void)) ^~~~~~~~~~~~~~ z.c:1:5: note: previous declaration of ‘f_ptr_noreturn’ was here int f_ptr_noreturn (void (*fp)(void) __attribute__((noreturn))); ^~~~~~~~~~~~~~ z.c: In function ‘f_ptr_noreturn’: z.c:6:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ + for lang in c c++ + /ssd/build/gcc-git/gcc/xgcc -B /ssd/build/gcc-git/gcc -S -Wall -Wunused -Wpedantic -xc++ z.c z.c: In function ‘int f_ptr_noreturn(void (*)())’: z.c:6:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^
See also bug 88397 for a similar problem with attribute malloc (but one that affects both C and C++ the same way). Let me also confirm this bug since this is at least the second time I've run into it.