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

Reply via email to