diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc index 634e3cf4fa9..a7d0fdacf6e 100644 --- a/gcc/cp/contracts.cc +++ b/gcc/cp/contracts.cc @@ -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; diff --git a/gcc/testsuite/g++.dg/contracts/pr113968.C b/gcc/testsuite/g++.dg/contracts/pr113968.C new file mode 100644 index 00000000000..fbaad1c930d --- /dev/null +++ b/gcc/testsuite/g++.dg/contracts/pr113968.C @@ -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 () +{ +}