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>
* 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.

View File

@ -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);

View File

@ -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). */

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);
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;

View File

@ -1,5 +1,7 @@
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-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 (...) { }
}