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
This commit is contained in:
Jason Merrill 2011-09-24 22:26:21 -04:00 committed by Jason Merrill
parent 6fd4488141
commit 6eaade31bb
6 changed files with 48 additions and 4 deletions

View File

@ -1,5 +1,9 @@
2011-09-24 Jason Merrill <jason@redhat.com> 2011-09-24 Jason Merrill <jason@redhat.com>
* 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. * init.c (perform_member_init): Instantiate NSDMI here.
* pt.c (tsubst_decl) [FIELD_DECL]: Not here. * pt.c (tsubst_decl) [FIELD_DECL]: Not here.

View File

@ -5047,6 +5047,7 @@ extern tree build_throw (tree);
extern int nothrow_libfn_p (const_tree); extern int nothrow_libfn_p (const_tree);
extern void check_handlers (tree); extern void check_handlers (tree);
extern tree finish_noexcept_expr (tree, tsubst_flags_t); 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 void perform_deferred_noexcept_checks (void);
extern bool nothrow_spec_p (const_tree); extern bool nothrow_spec_p (const_tree);
extern bool type_noexcept_p (const_tree); extern bool type_noexcept_p (const_tree);

View File

@ -1125,14 +1125,27 @@ perform_deferred_noexcept_checks (void)
tree tree
finish_noexcept_expr (tree expr, tsubst_flags_t complain) finish_noexcept_expr (tree expr, tsubst_flags_t complain)
{ {
tree fn;
if (expr == error_mark_node) if (expr == error_mark_node)
return error_mark_node; return error_mark_node;
if (processing_template_decl) if (processing_template_decl)
return build_min (NOEXCEPT_EXPR, boolean_type_node, expr); 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); fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0);
if (fn) if (fn)
{ {
@ -1151,10 +1164,10 @@ finish_noexcept_expr (tree expr, tsubst_flags_t complain)
else else
maybe_noexcept_warning (fn); maybe_noexcept_warning (fn);
} }
return boolean_false_node; return false;
} }
else else
return boolean_true_node; return true;
} }
/* Return true iff SPEC is throw() or noexcept(true). */ /* Return true iff SPEC is throw() or noexcept(true). */

View File

@ -1042,6 +1042,12 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
inform (0, "initializer for %q+#D is invalid", field); inform (0, "initializer for %q+#D is invalid", field);
if (trivial_p) if (trivial_p)
*trivial_p = false; *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. */ /* Don't do the normal processing. */
continue; continue;

View File

@ -1,5 +1,7 @@
2011-09-24 Jason Merrill <jason@redhat.com> 2011-09-24 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/nsdmi-eh1.C: New.
* g++.dg/cpp0x/nsdmi-defer3.C: New. * g++.dg/cpp0x/nsdmi-defer3.C: New.
* g++.dg/cpp0x/nsdmi-defer1.C: New. * g++.dg/cpp0x/nsdmi-defer1.C: New.

View File

@ -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 (...) { }
}