]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++, contracts: fix testsuite basic.contract.eval.p8 failed
authoryxj-github-437 <2457369732@qq.com>
Thu, 30 Apr 2026 15:52:18 +0000 (23:52 +0800)
committerJason Merrill <jason@redhat.com>
Mon, 4 May 2026 19:29:43 +0000 (15:29 -0400)
I noticed that the following code passed.

1 | consteval void foo( auto x ) pre( false ) { return x; }
2 |
3 | static_assert (foo( 1 ) == 1, "");
4 |
5 | int main() {
6 |   foo( 1 );
7 | }

However, the code has contract violations.
In constexpr_call, a result with contract violations should
not be cached.

gcc/cp/ChangeLog:
* constexpr.cc (cxx_eval_constant_expression): Do not cache
result with contract violation.
gcc/testsuite/ChangeLog:
* g++.dg/contracts/cpp26/basic.contract.eval.p8-3.C: New test.

gcc/cp/constexpr.cc
gcc/testsuite/g++.dg/contracts/cpp26/basic.contract.eval.p8-3.C [new file with mode: 0644]

index e9388a6ba7f20b1146af3ecc0461dd71c4318797..280843660c90f6877b9d0236c835cc822d85870c 100644 (file)
@@ -4639,6 +4639,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
          /* Only cache a permitted result of a constant expression.  */
          if (cacheable && !reduced_constant_expression_p (result))
            cacheable = false;
+
+         /* Only cache a result without contract violations.  */
+         if (cacheable && ctx->global->contract_statement)
+           cacheable = false;
        }
       else
        /* Couldn't get a function copy to evaluate.  */
diff --git a/gcc/testsuite/g++.dg/contracts/cpp26/basic.contract.eval.p8-3.C b/gcc/testsuite/g++.dg/contracts/cpp26/basic.contract.eval.p8-3.C
new file mode 100644 (file)
index 0000000..e121d8b
--- /dev/null
@@ -0,0 +1,15 @@
+// basic.contract.eval/p8
+// If a contract violation occurs in a context that is manifestly
+// constant-evaluated ([expr.const]), and the evaluation semantic is a
+// terminating semantic, the program is ill-formed.
+// { dg-do compile { target c++23 } }
+// { dg-additional-options "-fcontracts" }
+
+consteval auto foo( auto x ) pre( false ) { return x; }
+// { dg-error {contract predicate is false in constant expression} "" { target *-*-* } .-1 }
+
+static_assert(foo( 42 ) == 42, "");
+
+int main() {
+  foo( 42 ); // { dg-error {call to consteval function 'foo<int>\(42\)' is not a constant expression} }
+}