On Tue, 9 Jul 2024 at 22:50, Jason Merrill <ja...@redhat.com> wrote:

> On 7/9/24 6:41 AM, Nina Dinka Ranns wrote:
> > On Mon, 8 Jul 2024 at 16:01, Jason Merrill <ja...@redhat.com
> > <mailto:ja...@redhat.com>> wrote:
> >
> >     On 7/8/24 7:47 AM, Nina Dinka Ranns wrote:
> >      > HI Jason,
> >      >
> >      > On Fri, 5 Jul 2024 at 17:31, Jason Merrill <ja...@redhat.com
> >     <mailto:ja...@redhat.com>> wrote:
> >      >>
> >      >> On 7/5/24 10:25 AM, Nina Dinka Ranns 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.
> >      >>
> >      >> Thanks for the patch!
> >      >>
> >      >>> Tested on x86_64-pc-linux-gnu
> >      >>> ---
> >      >>>
> >      >>>           PR c++/113968
> >      >>>
> >      >>> gcc/cp/ChangeLog:
> >      >>>
> >      >>>           * contracts.cc (grok_contract): Check for
> >     error_mark_node early
> >      >>>             exit
> >      >>
> >      >> These hunks are OK.
> >      >>
> >      >>>           * parser.cc (cp_parser_contract_attribute_spec):
> >     Check for
> >      >>>             error_mark_node early exit
> >      >>
> >      >> This seems redundant, since finish_contract_attribute already
> >     checks for
> >      >> error_mark_node and we're returning its result unchanged.
> >      >
> >      > good catch, removed.
> >      >
> >      >>
> >      >> Also, the convention is for wrapped lines in ChangeLog entries
> >     to line
> >      >> up with the *, and to finish sentences with a period.
> >      >
> >      > done.
> >      >
> >      > Tests re-run on x86_64-pc-linux-gnu , no change.
> >
> >     This looks good, but the patch doesn't apply due to word wrap.  To
> >     avoid
> >     that, I tend to use git send-email; sending the patch as an
> attachment
> >     is also OK.  Or see
> >
> >     https://www.kernel.org/doc/html/latest/process/email-clients.html
> >     <https://www.kernel.org/doc/html/latest/process/email-clients.html>
> >
> >     for tips on getting various email clients to leave patches alone.
> >
> >
> > ack, thank you for your patience.
> > This time, patch attached to the email.
>
> It looks like the attached patch reverted to older ChangeLog entries,
> without the periods, and with the dropped parser.cc change?
>
> git gcc-verify also complains
>
> > ERR: line should start with a tab: "        * contracts.cc
> (grok_contract): Check for error_mark_node early"
> > ERR: line should start with a tab: "          exit"
> > ERR: line should start with a tab: "        * parser.cc
> (cp_parser_contract_attribute_spec): Check for"
> > ERR: line should start with a tab: "          error_mark_node early exit"
> > ERR: line should start with a tab: "        *
> g++.dg/contracts/pr113968.C: New test."
> > ERR: PR 113968 in subject but not in changelog: "c++, contracts: Fix ICE
> in create_tmp_var [PR113968]"
>
> Jason
>
>
Apologies. I must have copy pasted something wrong. I've setup gcc-verify
and that passes.
Let's try again. Patch attached.

Thank you,
Nina
From f529ffd1c3abb2229ff715e5de123a0bfed9ff2a Mon Sep 17 00:00:00 2001
From: Nina Ranns <dinka.ra...@gmail.com>
Date: Thu, 4 Jul 2024 17:08:58 +0100
Subject: [PATCH] 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.ra...@gmail.com>
---
 gcc/cp/contracts.cc                       |  7 ++++++
 gcc/testsuite/g++.dg/contracts/pr113968.C | 29 +++++++++++++++++++++++
 2 files changed, 36 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/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