During contract parsing, in grok_contract(), we proceed even if the
condition contains errors. This results in contracts with embedded errors
which eventually confuse gimplify. Checks for errors have been added in
grok_contract() to exit early if an error is encountered.
PR c++/113968
gcc/cp/ChangeLog:
* contracts.cc (grok_contract): Check for error_mark_node early
exit.
gcc/testsuite/ChangeLog:
* g++.dg/contracts/pr113968.C: New test.
Signed-off-by: Nina Ranns <dinka.ranns@gmail.com>
grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
location_t loc)
{
+ if (condition == error_mark_node)
+ return error_mark_node;
+
tree_code code;
if (is_attribute_p ("assert", attribute))
code = ASSERTION_STMT;
/* The condition is converted to bool. */
condition = finish_contract_condition (condition);
+
+ if (condition == error_mark_node)
+ return error_mark_node;
+
CONTRACT_CONDITION (contract) = condition;
return contract;
--- /dev/null
+// check that an invalid contract condition doesn't cause an ICE
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts " }
+
+struct A
+{
+ A (A&);
+};
+struct S
+{
+ void f(A a)
+ [[ pre : a]] // { dg-error "could not convert" }
+ [[ pre : a.b]]// { dg-error "has no member" }
+ {
+
+ }
+};
+void f(A a)
+ [[ pre : a]] // { dg-error "could not convert" }
+ [[ pre : a.b]]// { dg-error "has no member" }
+ {
+ [[ assert : a ]]; // { dg-error "could not convert" }
+ [[ assert : a.b ]];// { dg-error "has no member" }
+ }
+
+int
+main ()
+{
+}