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

Reply via email to