Boost logo

Boost :

Subject: Re: [boost] [exception] warnings on top of trunk
From: Bryce Lelbach (blelbach_at_[hidden])
Date: 2011-05-23 11:44:28


GCC documentation:

noreturn
    A few standard library functions, such as abort and exit, cannot return.
    GCC knows this automatically. Some programs define their own functions that
    never return. You can declare them noreturn to tell the compiler this fact.
    
    [snip]

    The noreturn keyword does not affect the exceptional path when that applies:
    a noreturn-marked function may still return to the caller by throwing an
    exception or calling longjmp.

p.ptr_->rethrow() is not marked as noreturn, and it throws an exception, which
makes it nonsensical IMHO. It does actually exit.

Example:

#include <stdlib.h>

#include <exception>
#include <stdlib.h>

__attribute__((noreturn)) void foo1 (void);
void foo2 (void);

__attribute__((noreturn)) void foo1 (void) { foo2(); }
void foo2 (void) { }

__attribute__((noreturn)) void bar1 (void);
void bar2 (void);

__attribute__((noreturn)) void bar1 (void) { bar2(); exit(0); }
void bar2 (void) { }

__attribute__((noreturn)) void buzz1 (void);
__attribute__((noreturn)) void buzz2 (void);

__attribute__((noreturn)) void buzz1 (void) { buzz2(); }
__attribute__((noreturn)) void buzz2 (void) { }

__attribute__((noreturn)) void yack1 (void);
__attribute__((noreturn)) void yack2 (void);

__attribute__((noreturn)) void yack1 (void) { yack2(); }
__attribute__((noreturn)) void yack2 (void) { throw std::exception(); }

int main (void) {
  foo1();
  bar1();
  buzz1();
  yack1();
}

Emits:

[10:22:04]:wash_at_[hidden]:/home/wash/sandbox$ g++ -Wall -Wextra -DNDEBUG -O3 attribute_no_return.cpp -o attribute_no_return
attribute_no_return.cpp: In function ‘void buzz2()’:
attribute_no_return.cpp:20: warning: ‘noreturn’ function does return
attribute_no_return.cpp: In function ‘void foo1()’:
attribute_no_return.cpp:7: warning: ‘noreturn’ function does return

On GCC 4.4.4, RHEL 6.0, x86-64.

This warning is in fact valid.

> > BOOST_ATTRIBUTE_NORETURN
> > inline
> > void
> > rethrow_exception( exception_ptr const & p )
> > {
> > BOOST_ASSERT(p);
> > p.ptr_->rethrow();
> > }

p.ptr is a shared_ptr to an exception_detail::clone_base. rethrow() is a pure
virtual function. Therefore, there is no gurantee that rethrow() won't exit,
and if it does, then rethrow_exception will exit, which could be catastrophic.
Not to mention the possibilities if exceptions are disabled (not sure if
rethrow_exception is even available in that case).

rethrow_exception should call abort() after rethrow() to ensure that it doesn't
return, or attribute noreturn should be removed. It is just an optimization...

-- 
Bryce Lelbach aka wash
boost-spirit.com
px.cct.lsu.edu
github.com/lll-project



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk