From 6eaade31bbb647403677bc9c47ce8ee1dd67b514 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 24 Sep 2011 22:26:21 -0400 Subject: [PATCH] except.c (expr_noexcept_p): Split out from finish_noexcept_expr. * except.c (expr_noexcept_p): Split out from finish_noexcept_expr. * cp-tree.h: Declare it. * method.c (walk_field_subobs): Use it. From-SVN: r179158 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/cp-tree.h | 1 + gcc/cp/except.c | 21 +++++++++++++++++---- gcc/cp/method.c | 6 ++++++ gcc/testsuite/ChangeLog | 2 ++ gcc/testsuite/g++.dg/cpp0x/nsdmi-eh1.C | 18 ++++++++++++++++++ 6 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-eh1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fc5436a..8c25746 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2011-09-24 Jason Merrill + * except.c (expr_noexcept_p): Split out from finish_noexcept_expr. + * cp-tree.h: Declare it. + * method.c (walk_field_subobs): Use it. + * init.c (perform_member_init): Instantiate NSDMI here. * pt.c (tsubst_decl) [FIELD_DECL]: Not here. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2f93bba..0f7deb6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5047,6 +5047,7 @@ extern tree build_throw (tree); extern int nothrow_libfn_p (const_tree); extern void check_handlers (tree); extern tree finish_noexcept_expr (tree, tsubst_flags_t); +extern bool expr_noexcept_p (tree, tsubst_flags_t); extern void perform_deferred_noexcept_checks (void); extern bool nothrow_spec_p (const_tree); extern bool type_noexcept_p (const_tree); diff --git a/gcc/cp/except.c b/gcc/cp/except.c index bfc520d..ceec858 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -1125,14 +1125,27 @@ perform_deferred_noexcept_checks (void) tree finish_noexcept_expr (tree expr, tsubst_flags_t complain) { - tree fn; - if (expr == error_mark_node) return error_mark_node; if (processing_template_decl) return build_min (NOEXCEPT_EXPR, boolean_type_node, expr); + return (expr_noexcept_p (expr, complain) + ? boolean_true_node : boolean_false_node); +} + +/* Returns whether EXPR is noexcept, possibly warning if allowed by + COMPLAIN. */ + +bool +expr_noexcept_p (tree expr, tsubst_flags_t complain) +{ + tree fn; + + if (expr == error_mark_node) + return false; + fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0); if (fn) { @@ -1151,10 +1164,10 @@ finish_noexcept_expr (tree expr, tsubst_flags_t complain) else maybe_noexcept_warning (fn); } - return boolean_false_node; + return false; } else - return boolean_true_node; + return true; } /* Return true iff SPEC is throw() or noexcept(true). */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 734c23b..1316dfb 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1042,6 +1042,12 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, inform (0, "initializer for %q+#D is invalid", field); if (trivial_p) *trivial_p = false; + /* Core 1351: If the field has an NSDMI that could throw, the + default constructor is noexcept(false). FIXME this is + broken by deferred parsing and 1360 saying we can't + lazily declare a non-trivial default constructor. */ + if (spec_p && !expr_noexcept_p (DECL_INITIAL (field), complain)) + *spec_p = noexcept_false_spec; /* Don't do the normal processing. */ continue; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a8b10cd..5b73414 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-09-24 Jason Merrill + * g++.dg/cpp0x/nsdmi-eh1.C: New. + * g++.dg/cpp0x/nsdmi-defer3.C: New. * g++.dg/cpp0x/nsdmi-defer1.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-eh1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-eh1.C new file mode 100644 index 0000000..09c92d2f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-eh1.C @@ -0,0 +1,18 @@ +// Core issue 1351 +// { dg-do run { xfail *-*-* } } +// { dg-options -std=c++0x } + +bool fail; +struct A +{ + int i = fail ? throw "noooooooo" : 42; +}; + +int main() +{ + A a1; + if (a1.i != 42) return 1; + fail = true; + try { A a2; } + catch (...) { } +} -- 2.7.4