Hi again,
Hi,
this is a rejects-valid with constexpr & noexcept, noticed by Daniel
(and myself time ago). I find it pretty annoying. Anyway, the issue
is, we reject:
constexpr bool ok() noexcept
{
typedef int type;
return true;
}
constexpr auto x = ok();
because of the noexcept. What happens is that massage_constexpr_body
looks inside MUST_NOT_THROW_EXPR but then doesn't notice that body is
still a BIND_EXPR.
Thus the obvious idea is processing the latter as we would do if the
noexcept were not there and that indeed fixes the issue without
regressions, but I'm not sure if we shouldn't recurse / iterate more
generically (or do indeed something else entirely)
uhm, if all there is to this issue is just the possibility of a
BIND_EXPR embedded inside a MUST_NOT_THROW_EXPR we could just trivially
reorder the conditionals of course (the current order seems just
accidental). Or, assuming nothing deeper is going on, we can iterate.
Both patchlets below pass testing.
Thanks,
Paolo.
////////////////////
Index: semantics.c
===================================================================
--- semantics.c (revision 182571)
+++ semantics.c (working copy)
@@ -5998,12 +5998,12 @@ massage_constexpr_body (tree fun, tree body)
(DECL_CONTEXT (fun), body);
else
{
- if (TREE_CODE (body) == BIND_EXPR)
- body = BIND_EXPR_BODY (body);
if (TREE_CODE (body) == EH_SPEC_BLOCK)
body = EH_SPEC_STMTS (body);
if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
body = TREE_OPERAND (body, 0);
+ if (TREE_CODE (body) == BIND_EXPR)
+ body = BIND_EXPR_BODY (body);
body = constexpr_fn_retval (body);
}
return body;
Index: semantics.c
===================================================================
--- semantics.c (revision 182571)
+++ semantics.c (working copy)
@@ -5998,12 +5998,17 @@ massage_constexpr_body (tree fun, tree body)
(DECL_CONTEXT (fun), body);
else
{
- if (TREE_CODE (body) == BIND_EXPR)
- body = BIND_EXPR_BODY (body);
- if (TREE_CODE (body) == EH_SPEC_BLOCK)
- body = EH_SPEC_STMTS (body);
- if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
- body = TREE_OPERAND (body, 0);
+ while (true)
+ {
+ if (TREE_CODE (body) == BIND_EXPR)
+ body = BIND_EXPR_BODY (body);
+ else if (TREE_CODE (body) == EH_SPEC_BLOCK)
+ body = EH_SPEC_STMTS (body);
+ else if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
+ body = TREE_OPERAND (body, 0);
+ else
+ break;
+ }
body = constexpr_fn_retval (body);
}
return body;