Commit 2c5df20f by Jason Merrill Committed by Jason Merrill

except.c (pending_noexcept, [...]): New.

	* except.c (pending_noexcept, pending_noexcept_checks): New.
	(perform_deferred_noexcept_checks): New.
	(maybe_noexcept_warning): Split from...
	(finish_noexcept_expr): ...here.  Adjust.
	* decl2.c (cp_write_global_declarations): Call
	perform_deferred_noexcept_checks.
	* cp-tree.h: And declare it.

From-SVN: r163379
parent fcaa4ca4
2010-08-19 Jason Merrill <jason@redhat.com>
* except.c (pending_noexcept, pending_noexcept_checks): New.
(perform_deferred_noexcept_checks): New.
(maybe_noexcept_warning): Split from...
(finish_noexcept_expr): ...here. Adjust.
* decl2.c (cp_write_global_declarations): Call
perform_deferred_noexcept_checks.
* cp-tree.h: And declare it.
2010-08-18 Nathan Froyd <froydnj@codesourcery.com> 2010-08-18 Nathan Froyd <froydnj@codesourcery.com>
PR c++/45049 PR c++/45049
......
...@@ -4883,6 +4883,7 @@ extern tree build_throw (tree); ...@@ -4883,6 +4883,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 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);
extern bool type_throw_all_p (const_tree); extern bool type_throw_all_p (const_tree);
......
...@@ -3934,6 +3934,8 @@ cp_write_global_declarations (void) ...@@ -3934,6 +3934,8 @@ cp_write_global_declarations (void)
VEC_length (tree, pending_statics)); VEC_length (tree, pending_statics));
} }
perform_deferred_noexcept_checks ();
/* Generate hidden aliases for Java. */ /* Generate hidden aliases for Java. */
if (candidates) if (candidates)
{ {
......
...@@ -1069,6 +1069,51 @@ check_noexcept_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, ...@@ -1069,6 +1069,51 @@ check_noexcept_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
return NULL_TREE; return NULL_TREE;
} }
/* If a function that causes a noexcept-expression to be false isn't
defined yet, remember it and check it for TREE_NOTHROW again at EOF. */
typedef struct GTY(()) pending_noexcept {
tree fn;
location_t loc;
} pending_noexcept;
DEF_VEC_O(pending_noexcept);
DEF_VEC_ALLOC_O(pending_noexcept,gc);
static GTY(()) VEC(pending_noexcept,gc) *pending_noexcept_checks;
/* FN is a FUNCTION_DECL that caused a noexcept-expr to be false. Warn if
it can't throw. */
static void
maybe_noexcept_warning (tree fn)
{
if (TREE_NOTHROW (fn))
{
warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> "
"because of a call to %qD", fn);
warning (OPT_Wnoexcept, "but %q+D does not throw; perhaps "
"it should be declared %<noexcept%>", fn);
}
}
/* Check any functions that weren't defined earlier when they caused a
noexcept expression to evaluate to false. */
void
perform_deferred_noexcept_checks (void)
{
int i;
pending_noexcept *p;
location_t saved_loc = input_location;
for (i = 0;
VEC_iterate (pending_noexcept, pending_noexcept_checks, i, p);
++i)
{
input_location = p->loc;
maybe_noexcept_warning (p->fn);
}
input_location = saved_loc;
}
/* Evaluate noexcept ( EXPR ). */ /* Evaluate noexcept ( EXPR ). */
tree tree
...@@ -1082,13 +1127,20 @@ finish_noexcept_expr (tree expr, tsubst_flags_t complain) ...@@ -1082,13 +1127,20 @@ finish_noexcept_expr (tree expr, tsubst_flags_t complain)
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)
{ {
if ((complain & tf_warning) && TREE_CODE (fn) == FUNCTION_DECL if ((complain & tf_warning) && warn_noexcept
&& TREE_NOTHROW (fn) && !DECL_ARTIFICIAL (fn)) && TREE_CODE (fn) == FUNCTION_DECL)
{ {
warning (OPT_Wnoexcept, "noexcept-expression evaluates to %<false%> " if (!DECL_INITIAL (fn))
"because of a call to %qD", fn); {
warning (OPT_Wnoexcept, "but %q+D does not throw; perhaps " /* Not defined yet; check again at EOF. */
"it should be declared %<noexcept%>", fn); pending_noexcept *p
= VEC_safe_push (pending_noexcept, gc,
pending_noexcept_checks, NULL);
p->fn = fn;
p->loc = input_location;
}
else
maybe_noexcept_warning (fn);
} }
return boolean_false_node; return boolean_false_node;
} }
......
2010-08-19 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/noexcept09.C: New.
2010-08-19 Daniel Kraft <d@domob.eu> 2010-08-19 Daniel Kraft <d@domob.eu>
PR fortran/29785 PR fortran/29785
......
// Test that -Wnoexcept works with templates
// { dg-options "-std=c++0x -Wnoexcept" }
template <class T>
T f (T t) { return t; } // { dg-warning "does not throw" }
#define SA(X) static_assert(X, #X)
SA (!noexcept(f(1))); // { dg-warning "noexcept" }
int main()
{
f(1); // Use f(int) so it gets instantiated
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment