From 9feb3d6aca21781464d2759fcef34bd471d85628 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 15 May 2010 22:27:02 -0400 Subject: c.opt: Add -fnothrow-opt. gcc: * c.opt: Add -fnothrow-opt. gcc/cp: * cp-tree.h (TYPE_NOEXCEPT_P): New macro. * except.c (begin_eh_spec_block): Use MUST_NOT_THROW_EXPR if TYPE_NOEXCEPT_P. (finish_eh_spec_block): Adjust. From-SVN: r159450 --- gcc/ChangeLog | 4 ++++ gcc/c.opt | 4 ++++ gcc/cp/ChangeLog | 7 +++++++ gcc/cp/cp-tree.h | 6 ++++++ gcc/cp/except.c | 19 +++++++++++++++--- gcc/doc/invoke.texi | 9 +++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/eh/forced3.C | 2 +- gcc/testsuite/g++.dg/eh/spec10.C | 31 ++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/eh/spec11.C | 11 +++++++++++ gcc/testsuite/g++.old-deja/g++.mike/eh34.C | 1 - 11 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/eh/spec10.C create mode 100644 gcc/testsuite/g++.dg/eh/spec11.C (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e294679..9380883 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2010-05-15 Jason Merrill + + * c.opt: Add -fnothrow-opt. + 2010-05-15 Jan Hubicka * ipa-prop.c (ipa_prop_read_section): Add sanity check that node is analyzed. diff --git a/gcc/c.opt b/gcc/c.opt index c79165a..01d6428 100644 --- a/gcc/c.opt +++ b/gcc/c.opt @@ -689,6 +689,10 @@ C++ ObjC++ fnonnull-objects C++ ObjC++ +fnothrow-opt +C++ ObjC++ Optimization Var(flag_nothrow_opt) +Treat a throw() exception specification as noexcept to improve code size + ; Generate special '- .cxx_construct' and '- .cxx_destruct' methods ; to initialize any non-POD ivars in Objective-C++ classes. fobjc-call-cxx-cdtors diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fda48be..84b8ae5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2010-05-15 Jason Merrill + + * cp-tree.h (TYPE_NOEXCEPT_P): New macro. + * except.c (begin_eh_spec_block): Use MUST_NOT_THROW_EXPR if + TYPE_NOEXCEPT_P. + (finish_eh_spec_block): Adjust. + 2010-05-15 Jakub Jelinek PR c++/44148 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3b8e9d0..361a6f2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1741,6 +1741,12 @@ struct GTY(()) lang_type { (TYPE_RAISES_EXCEPTIONS (NODE) \ && TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE) +/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the + case for things declared noexcept(true) and, with -fnothrow-opt, for + throw() functions. */ +#define TYPE_NOEXCEPT_P(NODE) \ + (flag_nothrow_opt && TYPE_NOTHROW_P(NODE)) + /* The binding level associated with the namespace. */ #define NAMESPACE_LEVEL(NODE) \ (LANG_DECL_NS_CHECK (NODE)->level) diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 48ace53..c0867ef 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -513,9 +513,18 @@ expand_end_catch_block (void) tree begin_eh_spec_block (void) { - tree r = build_stmt (input_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE); + tree r; + /* A noexcept specification (or throw() with -fnothrow-opt) is a + MUST_NOT_THROW_EXPR. */ + if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl))) + { + r = build_stmt (input_location, MUST_NOT_THROW_EXPR, NULL_TREE); + TREE_SIDE_EFFECTS (r) = 1; + } + else + r = build_stmt (input_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE); add_stmt (r); - EH_SPEC_STMTS (r) = push_stmt_list (); + TREE_OPERAND (r, 0) = push_stmt_list (); return r; } @@ -524,7 +533,11 @@ finish_eh_spec_block (tree raw_raises, tree eh_spec_block) { tree raises; - EH_SPEC_STMTS (eh_spec_block) = pop_stmt_list (EH_SPEC_STMTS (eh_spec_block)); + TREE_OPERAND (eh_spec_block, 0) + = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0)); + + if (TREE_CODE (eh_spec_block) == MUST_NOT_THROW_EXPR) + return; /* Strip cv quals, etc, from the specification types. */ for (raises = NULL_TREE; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 98f97cc..81c2d03 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1929,6 +1929,15 @@ Disable built-in declarations of functions that are not mandated by ANSI/ISO C@. These include @code{ffs}, @code{alloca}, @code{_exit}, @code{index}, @code{bzero}, @code{conjf}, and other related functions. +@item -fnothrow-opt +@opindex fnothrow-opt +Treat a @code{throw()} exception specification as though it were a +@code{noexcept} specification to reduce or eliminate the text size +overhead relative to a function with no exception specification. The +semantic effect is that an exception thrown out of a function with +such an exception specification will result in a call to +@code{terminate} rather than @code{unexpected}. + @item -fno-operator-names @opindex fno-operator-names Do not treat the operator name keywords @code{and}, @code{bitand}, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ded582b..8b25528 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-05-15 Jason Merrill + + * g++.dg/eh/spec10.C: New. + * g++.dg/eh/spec11.C: New. + * g++.old-deja/g++.mike/eh34.C: Remove dg-options. + 2010-05-15 Janus Weil PR fortran/44154 diff --git a/gcc/testsuite/g++.dg/eh/forced3.C b/gcc/testsuite/g++.dg/eh/forced3.C index 96319d4..b8f47df 100644 --- a/gcc/testsuite/g++.dg/eh/forced3.C +++ b/gcc/testsuite/g++.dg/eh/forced3.C @@ -2,7 +2,7 @@ // { dg-do run { xfail "ia64-hp-hpux11.*" } } // Test that forced unwinding calls std::unexpected going -// throw a nothrow function. +// through a nothrow function. #include #include diff --git a/gcc/testsuite/g++.dg/eh/spec10.C b/gcc/testsuite/g++.dg/eh/spec10.C new file mode 100644 index 0000000..a62d24e --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/spec10.C @@ -0,0 +1,31 @@ +// Make sure that we call terminate when a throw() spec is violated even +// with -fnothrow-opt. The function pointers are there to make sure that +// the compiler doesn't get clever about optimizing the calls based on +// knowledge about the called functions. + +// { dg-options "-fnothrow-opt" } +// { dg-do run } + +#include +#include + +void my_terminate () +{ + std::exit (0); +} + +void g() { throw 1; } +void (*p1)() = g; +void f() throw() { p1(); } +void (*p2)() = f; +void h() { p2(); } + +int main() +{ + std::set_terminate (my_terminate); + + try { h(); } + catch (int) { } + + return 1; +} diff --git a/gcc/testsuite/g++.dg/eh/spec11.C b/gcc/testsuite/g++.dg/eh/spec11.C new file mode 100644 index 0000000..562e366 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/spec11.C @@ -0,0 +1,11 @@ +// Make sure that we force an LSDA for a throw() spec with -fnothrow-opt so +// that the personality routine will call terminate. + +// { dg-final { scan-assembler-not "_ZSt9terminatev" } } +// { dg-final { scan-assembler-not "EHB" } } +// { dg-final { scan-assembler "LSDA" } } + +// { dg-options "-fnothrow-opt" } + +void g(); +void f() throw() { g(); } diff --git a/gcc/testsuite/g++.old-deja/g++.mike/eh34.C b/gcc/testsuite/g++.old-deja/g++.mike/eh34.C index 68fa673..056f6b8 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/eh34.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/eh34.C @@ -1,5 +1,4 @@ // { dg-do run { xfail sparc64-*-elf arm-*-pe } } -// { dg-options "-fexceptions" } #include #include -- cgit v1.1