c++: Fix noexcept with unevaluated operand [PR101087]
It sounds plausible that this assert int f(); static_assert(noexcept(sizeof(f()))); should pass: sizeof produces a std::size_t and its operand is not evaluated, so it can't throw. noexcept should only evaluate to false for potentially evaluated operands. Therefore I think that check_noexcept_r shouldn't walk into operands of sizeof/decltype/ alignof/typeof. PR c++/101087 gcc/cp/ChangeLog: * cp-tree.h (unevaluated_p): New. * except.c (check_noexcept_r): Use it. Don't walk into unevaluated operands. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept70.C: New test.
This commit is contained in:
parent
b14ac7b29c
commit
dee00bf689
@ -8465,6 +8465,19 @@ is_constrained_auto (const_tree t)
|
||||
return is_auto (t) && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t);
|
||||
}
|
||||
|
||||
/* True if CODE, a tree code, denotes a tree whose operand is not evaluated
|
||||
as per [expr.context], i.e., an operand to sizeof, typeof, decltype, or
|
||||
alignof. */
|
||||
|
||||
inline bool
|
||||
unevaluated_p (tree_code code)
|
||||
{
|
||||
return (code == DECLTYPE_TYPE
|
||||
|| code == ALIGNOF_EXPR
|
||||
|| code == SIZEOF_EXPR
|
||||
|| code == NOEXCEPT_EXPR);
|
||||
}
|
||||
|
||||
/* RAII class to push/pop the access scope for T. */
|
||||
|
||||
struct push_access_scope_guard
|
||||
|
@ -1033,12 +1033,15 @@ check_handlers (tree handlers)
|
||||
expression whose type is a polymorphic class type (10.3). */
|
||||
|
||||
static tree
|
||||
check_noexcept_r (tree *tp, int * /*walk_subtrees*/, void * /*data*/)
|
||||
check_noexcept_r (tree *tp, int *walk_subtrees, void *)
|
||||
{
|
||||
tree t = *tp;
|
||||
enum tree_code code = TREE_CODE (t);
|
||||
if ((code == CALL_EXPR && CALL_EXPR_FN (t))
|
||||
|| code == AGGR_INIT_EXPR)
|
||||
|
||||
if (unevaluated_p (code))
|
||||
*walk_subtrees = false;
|
||||
else if ((code == CALL_EXPR && CALL_EXPR_FN (t))
|
||||
|| code == AGGR_INIT_EXPR)
|
||||
{
|
||||
/* We can only use the exception specification of the called function
|
||||
for determining the value of a noexcept expression; we can't use
|
||||
|
5
gcc/testsuite/g++.dg/cpp0x/noexcept70.C
Normal file
5
gcc/testsuite/g++.dg/cpp0x/noexcept70.C
Normal file
@ -0,0 +1,5 @@
|
||||
// PR c++/101087
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
int f();
|
||||
static_assert(noexcept(sizeof(f())), "");
|
Loading…
Reference in New Issue
Block a user