Commit 1006c9d4 by Jakub Jelinek Committed by Jakub Jelinek

constexpr.c (cxx_eval_constant_expression): If not skipping upon entry to body...

	* constexpr.c (cxx_eval_constant_expression) <case CLEANUP_STMT>: If
	not skipping upon entry to body, run cleanup with the same *jump_target
	as it started to run the cleanup even if the body returns, breaks or
	continues.
	(potential_constant_expression_1): Allow CLEANUP_STMT.

	* g++.dg/ext/constexpr-attr-cleanup1.C: New test.

From-SVN: r276494
parent 276a52d5
2019-10-03 Jakub Jelinek <jakub@redhat.com>
* constexpr.c (cxx_eval_constant_expression) <case CLEANUP_STMT>: If
not skipping upon entry to body, run cleanup with the same *jump_target
as it started to run the cleanup even if the body returns, breaks or
continues.
(potential_constant_expression_1): Allow CLEANUP_STMT.
* constexpr.c (cxx_eval_store_expression): Formatting fix. Handle
const_object_being_modified with array type.
......
......@@ -4899,14 +4899,21 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
break;
case CLEANUP_STMT:
r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
{
tree initial_jump_target = jump_target ? *jump_target : NULL_TREE;
r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
non_constant_p, overflow_p,
jump_target);
if (!CLEANUP_EH_ONLY (t) && !*non_constant_p)
/* Also evaluate the cleanup. If we weren't skipping at the
start of the CLEANUP_BODY, change jump_target temporarily
to &initial_jump_target, so that even a return or break or
continue in the body doesn't skip the cleanup. */
cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), true,
non_constant_p, overflow_p,
jump_target);
if (!CLEANUP_EH_ONLY (t) && !*non_constant_p)
/* Also evaluate the cleanup. */
cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), true,
non_constant_p, overflow_p,
jump_target);
jump_target ? &initial_jump_target
: NULL);
}
break;
/* These differ from cxx_eval_unary_expression in that this doesn't
......@@ -6975,6 +6982,12 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
return true;
case CLEANUP_STMT:
if (!RECUR (CLEANUP_BODY (t), any))
return false;
if (!CLEANUP_EH_ONLY (t) && !RECUR (CLEANUP_EXPR (t), any))
return false;
return true;
case EMPTY_CLASS_EXPR:
case PREDICT_EXPR:
return false;
......
2019-10-03 Jakub Jelinek <jakub@redhat.com>
* g++.dg/ext/constexpr-attr-cleanup1.C: New test.
2019-10-02 Martin Sebor <msebor@redhat.com>
PR tree-optimization/80936
......
// { dg-do compile { target c++2a } }
constexpr void
cleanup (int *x)
{
if (x)
asm (""); // { dg-error "inline assembly is not a constant expression" }
} // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 }
constexpr void
cleanup2 (int *x)
{
}
constexpr bool
foo ()
{
int a __attribute__((cleanup (cleanup))) = 1;
return true;
}
constexpr bool
bar ()
{
int a __attribute__((cleanup (cleanup2))) = 1;
return true;
}
constexpr auto x = foo (); // { dg-message "in 'constexpr' expansion of" }
constexpr auto y = bar ();
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