+2010-06-16 Jason Merrill <jason@redhat.com>
+
+ * c.opt: Add -Wnoexcept.
+
2010-06-16 Richard Guenther <rguenther@suse.de>
PR c/44555
C ObjC Var(warn_nested_externs) Warning
Warn about \"extern\" declarations not at file scope
+Wnoexcept
+C++ ObjC++ Var(warn_noexcept) Warning
+Warn when a noexcept expression evaluates to true even though the expression can't actually throw
+
Wnon-template-friend
C++ ObjC++ Var(warn_nontemplate_friend) Init(1) Warning
Warn when non-templatized friend functions are declared within a template
2010-06-16 Jason Merrill <jason@redhat.com>
+ * except.c (check_noexcept_r): Return the problematic function.
+ (finish_noexcept_expr): Give -Wnoexcept warning. Add complain parm.
+ * pt.c (tsubst_copy_and_build): Pass it.
+ * parser.c (cp_parser_unary_expression): Likewise.
+ * cp-tree.h: Adjust prototype.
+
* method.c (defaulted_late_check): Give the defaulted method
the same exception specification as the implicit declaration.
extern tree build_throw (tree);
extern int nothrow_libfn_p (const_tree);
extern void check_handlers (tree);
-extern tree finish_noexcept_expr (tree);
+extern tree finish_noexcept_expr (tree, tsubst_flags_t);
extern bool nothrow_spec_p (const_tree);
extern bool type_noexcept_p (const_tree);
extern bool type_throw_all_p (const_tree);
We could use TREE_NOTHROW (t) for !TREE_PUBLIC fns, though... */
tree fn = (code == AGGR_INIT_EXPR
? AGGR_INIT_EXPR_FN (t) : CALL_EXPR_FN (t));
+ tree type = TREE_TYPE (TREE_TYPE (fn));
+
+ STRIP_NOPS (fn);
if (TREE_CODE (fn) == ADDR_EXPR)
{
/* We do use TREE_NOTHROW for ABI internals like __dynamic_cast,
and for C library functions known not to throw. */
- tree fn2 = TREE_OPERAND (fn, 0);
- if (TREE_CODE (fn2) == FUNCTION_DECL
- && DECL_EXTERN_C_P (fn2)
- && (DECL_ARTIFICIAL (fn2)
- || nothrow_libfn_p (fn2)))
- return TREE_NOTHROW (fn2) ? NULL_TREE : t;
+ fn = TREE_OPERAND (fn, 0);
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_EXTERN_C_P (fn)
+ && (DECL_ARTIFICIAL (fn)
+ || nothrow_libfn_p (fn)))
+ return TREE_NOTHROW (fn) ? NULL_TREE : fn;
}
- fn = TREE_TYPE (TREE_TYPE (fn));
- if (!TYPE_NOTHROW_P (fn))
- return t;
+ if (!TYPE_NOTHROW_P (type))
+ return fn;
}
return NULL_TREE;
/* Evaluate noexcept ( EXPR ). */
tree
-finish_noexcept_expr (tree expr)
+finish_noexcept_expr (tree expr, tsubst_flags_t complain)
{
+ tree fn;
+
if (processing_template_decl)
return build_min (NOEXCEPT_EXPR, boolean_type_node, expr);
- if (cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0))
- return boolean_false_node;
+ fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0);
+ if (fn)
+ {
+ if ((complain & tf_warning) && TREE_CODE (fn) == FUNCTION_DECL
+ && TREE_NOTHROW (fn) && !DECL_ARTIFICIAL (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);
+ }
+ return boolean_false_node;
+ }
else
return boolean_true_node;
}
parser->type_definition_forbidden_message = saved_message;
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
- return finish_noexcept_expr (expr);
+ return finish_noexcept_expr (expr, tf_warning_or_error);
}
default:
/*integral_constant_expression_p=*/false);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
- return finish_noexcept_expr (op1);
+ return finish_noexcept_expr (op1, complain);
case MODOP_EXPR:
{
-fno-default-inline -fvisibility-inlines-hidden @gol
-fvisibility-ms-compat @gol
-Wabi -Wconversion-null -Wctor-dtor-privacy @gol
--Wnon-virtual-dtor -Wreorder @gol
+-Wnoexcept -Wnon-virtual-dtor -Wreorder @gol
-Weffc++ -Wstrict-null-sentinel @gol
-Wno-non-template-friend -Wold-style-cast @gol
-Woverloaded-virtual -Wno-pmf-conversions @gol
destructors in that class are private, and it has neither friends nor
public static member functions.
+@item -Wnoexcept @r{(C++ and Objective-C++ only)}
+@opindex Wnoexcept
+@opindex Wno-noexcept
+Warn when a noexcept-expression evaluates to false because of a call
+to a function that does not have a non-throwing exception
+specification (i.e. @samp{throw()} or @samp{noexcept}) but is known by
+the compiler to never throw an exception.
+
@item -Wnon-virtual-dtor @r{(C++ and Objective-C++ only)}
@opindex Wnon-virtual-dtor
@opindex Wno-non-virtual-dtor
2010-06-16 Jason Merrill <jason@redhat.com>
+ * g++.dg/cpp0x/noexcept03.C: Test -Wnoexcept.
+
* g++.dg/cpp0x/noexcept01.C: Test defaulted fns.
2010-06-16 Richard Guenther <rguenther@suse.de>
// Runtime test for noexcept-specification.
-// { dg-options "-std=c++0x" }
+// { dg-options "-std=c++0x -Wnoexcept" }
// { dg-do run }
#include <exception>
}
template <class T>
-void f(T) noexcept (noexcept (T()))
+void f(T) noexcept (noexcept (T())) // { dg-warning "false" }
{
p();
}
f(a);
}
-struct A { A() { } };
+struct A { A() { } }; // { dg-warning "does not throw" }
// throw(int) overrides noexcept(false) in either order.
void h() throw (int, std::bad_exception);