------- Comment #4 from chris dot rimmer at antixlabs dot com 2008-01-17 09:52 ------- Sorry - my earlier comment was addressing the behaviour of GCC with respect to the DR, not the program in this bug report.
The situation in the DR is where the static type of the thrown object is 'Derived*', which the standard says should not be handled by a handler for 'Base*&'. GCC incorrectly catches the exception in this case. The situation in the original bug report is where the static type of the thrown object is 'Base*', so the handler should handle the exception, since 15.3 [except.handle]/3, first list item, says that a handler of type T& is a match for an exception of type E if E and T are the same type. (E and T are 'Base*' in this case). The GCC behaviour is a bug because 15.3 [except.handle]/19 says: "When the handler declares a reference to a non-constant object, any changes to the referenced object are changes to the temporary object initialised when the throw-expression was executed and will have effect should that object be rethrown." GCC binds the reference to a different object in each handler. We can see this by adding: std::cout << "&br = " << (void *) &br << '\n'; to each handler. When I ran this, the output was: &br = 0xbfb923e8 &br = 0xbfb923ec (gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)) -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23257