Jason, Consider this testcase reduced from g++.dg/tm/noexcept-1.C: ... struct TrueFalse { static constexpr bool v() { return true; } };
int global; template<typename T> int foo() { __transaction_atomic noexcept(T::v()) { global += 1; } return __transaction_atomic noexcept(T::v()) (global + 2); } int f1() { return foo<TrueFalse>(); } ... It fails with a SIGSEGV when run with -fno-exceptions: ... $ g++ noexcept-1.C -fno-exceptions -fgnu-tm -std=c++0x -S noexcept-1.C: In function ‘int foo() [with T = TrueFalse]’: noexcept-1.C:10:43: internal compiler error: Segmentation fault __transaction_atomic noexcept(T::v()) { global += 1; } ^ ... The noexcept(t::v()) operator evaluates to true, so the noexcept specifier on the transaction is set to true. Then cp/semantics.c:build_transaction_expr builds a MUST_NOT_THROW_EXPR to safe-guard the property at runtime: ... if (noex) { expr = build_must_not_throw_expr (expr, noex); SET_EXPR_LOCATION (expr, loc); TREE_SIDE_EFFECTS (expr) = 1; } ... During gimplification of the MUST_NOT_THROW_EXPR in cp/cp-gimplify.c:gimplify_must_not_throw_expr, we're trying to translate into a try/catch: ... gimplify_and_add (body, &try_); mnt = gimple_build_eh_must_not_throw (terminate_node); gimple_seq_add_stmt_without_update (&catch_, mnt); mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH); ... However, terminate_node is NULL at that point because of -fno-exceptions, so in gimple.c:gimple_build_eh_must_not_throw, this line causes a SIGSEGV because decl == terminate_node == NULL: ... gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); ... This patch fixes the SIGSEGV by not generating a MUST_NOT_THROW_EXPR with -fno-exceptions. Bootstrapped and reg-tested on x86_64. OK for trunk? Thanks, - Tom 2013-09-02 Tom de Vries <t...@codesourcery.com> PR c++/58282 * semantics.c (finish_transaction_stmt, build_transaction_expr): Handle flag_exceptions.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ee3503c..c8b328c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5189,7 +5189,7 @@ finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex) /* noexcept specifications are not allowed for function transactions. */ gcc_assert (!(noex && compound_stmt)); - if (noex) + if (noex && flag_exceptions) { tree body = build_must_not_throw_expr (TRANSACTION_EXPR_BODY (stmt), noex); @@ -5210,7 +5210,7 @@ tree build_transaction_expr (location_t loc, tree expr, int flags, tree noex) { tree ret; - if (noex) + if (noex && flag_exceptions) { expr = build_must_not_throw_expr (expr, noex); SET_EXPR_LOCATION (expr, loc);