On 7/1/21 12:27 PM, Andrew Sutton wrote:
I think this version addresses most of your concerns.
Thanks, looking good. I'll fuss with it a bit and commit it soon.
Do you agree that this testcase should compile?
>From 85400e1896a188892b1ebeb0c8e86ff3cd28cfa6 Mon Sep 17 00:00:00 2001
From: Jason Merrill <ja...@redhat.com>
Date: Wed, 30 Jun 2021 16:57:44 -0400
Subject: [PATCH] assume-cx
To: gcc-patches@gcc.gnu.org
---
gcc/cp/constexpr.c | 26 +++++++++++++++----
.../g++.dg/contracts/contracts-constexpr3.C | 10 +++++++
2 files changed, 31 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/contracts/contracts-constexpr3.C
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 435bf530d68..66b3ccce713 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -7022,12 +7022,26 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
break;
tree c = CONTRACT_CONDITION (t);
- if (semantic == CCS_ASSUME && !cp_tree_defined_p (c))
- break;
+ if (semantic == CCS_ASSUME)
+ {
+ /* For an assume contract, try evaluating it without instantiating
+ anything. If non-constant, assume it's satisfied. */
- /* Evaluate the generated check. */
- r = cxx_eval_constant_expression (ctx, c, false, non_constant_p,
- overflow_p);
+ if (!cp_tree_defined_p (c))
+ break;
+
+ bool dummy_nc = false, dummy_ov = false;
+ constexpr_ctx new_ctx = *ctx;
+ new_ctx.quiet = true;
+ r = cxx_eval_constant_expression (&new_ctx, c, false,
+ &dummy_nc, &dummy_ov);
+ if (dummy_nc)
+ break;
+ }
+ else
+ /* Evaluate the generated check. */
+ r = cxx_eval_constant_expression (ctx, c, false, non_constant_p,
+ overflow_p);
if (r == boolean_false_node)
{
if (!ctx->quiet)
@@ -8948,6 +8962,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case ASSERTION_STMT:
case PRECONDITION_STMT:
case POSTCONDITION_STMT:
+ if (!checked_contract_p (get_contract_semantic (t)))
+ return true;
if (!RECUR (CONTRACT_CONDITION (t), rval))
return false;
return true;
diff --git a/gcc/testsuite/g++.dg/contracts/contracts-constexpr3.C b/gcc/testsuite/g++.dg/contracts/contracts-constexpr3.C
new file mode 100644
index 00000000000..8826220ef91
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/contracts-constexpr3.C
@@ -0,0 +1,10 @@
+// An assumed contract shouldn't break constant evaluation.
+
+// { dg-do compile { target c++20 } }
+// { dg-additional-options -fcontracts }
+
+bool b;
+
+constexpr int f() [[ pre assume: b ]] { return 42; }
+
+static_assert (f() > 0);
--
2.27.0