c++, contracts: Fix ICE in create_tmp_var [PR113968]

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>
This commit is contained in:
Nina Ranns 2024-07-04 17:08:58 +01:00 committed by Jason Merrill
parent 8326956159
commit c829042849
2 changed files with 36 additions and 0 deletions

View file

@ -750,6 +750,9 @@ tree
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;
@ -785,6 +788,10 @@ grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
/* 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;

View file

@ -0,0 +1,29 @@
// 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 ()
{
}