Hi Nina, thanks for the patch!
> On 5 Jul 2024, at 15:25, Nina Dinka Ranns <dinka.ra...@googlemail.com> wrote: > > Certain places in contract parsing currently do not check for errors. > This results in contracts > with embedded errors which eventually confuse gimplify. Checks for > errors added in > grok_contract() and cp_parser_contract_attribute_spec() to exit early > if an error is encountered. > > Tested on x86_64-pc-linux-gnu this LGTM, but I cannot approve it. Iain > --- > > PR c++/113968 > > gcc/cp/ChangeLog: > > * contracts.cc (grok_contract): Check for error_mark_node early > exit > * parser.cc (cp_parser_contract_attribute_spec): Check for > error_mark_node early exit > > gcc/testsuite/ChangeLog: > > * g++.dg/contracts/pr113968.C: New test. > > Signed-off-by: Nina Ranns <dinka.ra...@gmail.com> > > > --- > gcc/cp/contracts.cc | 7 ++++++ > gcc/cp/parser.cc | 3 +++ > gcc/testsuite/g++.dg/contracts/pr113968.C | 29 +++++++++++++++++++++++ > 3 files changed, 39 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/contracts/pr113968.C > > 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/cp/parser.cc b/gcc/cp/parser.cc > index 31ae9c2fb54..22c5e760aee 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -30835,6 +30835,9 @@ cp_parser_contract_attribute_spec (cp_parser > *parser, tree attribute) > return error_mark_node; > } > > + if (contract == error_mark_node) > + return error_mark_node; > + > return finish_contract_attribute (attribute, 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 () > +{ > +} > -- > 2.45.2