This another one of these ICE after error issues with the
gimplifier and a fallout from r12-3278-g823685221de986af.
The problem here is that STRIP_USELESS_TYPE_CONVERSION will
leave around a NON_LVALUE_EXPR which is an error mark node.
Since the gimplifier assumes non-lvalue expressions has been
removed, there was an ICE.

This fixes the issue by checking if there is a NON_LVALUE_EXPR
and that has an error operand, we handle it as the same as if
it was an error operand.

gcc/ChangeLog:

        PR c/110682
        * gimplify.cc (gimplify_expr): Add check if there is
        a non-lvalue with an error operand.

gcc/testsuite/ChangeLog:

        PR c/110682
        * gcc.dg/redecl-27.c: New test.

Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
---
 gcc/gimplify.cc                  |  6 +++++-
 gcc/testsuite/gcc.dg/redecl-27.c | 14 ++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/redecl-27.c

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index d64bbf3ffbd..001b4af68b9 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -17686,7 +17686,11 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
       save_expr = *expr_p;
 
       /* Die, die, die, my darling.  */
-      if (error_operand_p (save_expr))
+      if (error_operand_p (save_expr)
+         /* The above strip useless type conversion might not strip out
+            a conversion from an error so handle that case here.  */
+         || (TREE_CODE (save_expr) == NON_LVALUE_EXPR
+             && error_operand_p (TREE_OPERAND (save_expr, 0))))
        {
          ret = GS_ERROR;
          break;
diff --git a/gcc/testsuite/gcc.dg/redecl-27.c b/gcc/testsuite/gcc.dg/redecl-27.c
new file mode 100644
index 00000000000..93f577e64ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/redecl-27.c
@@ -0,0 +1,14 @@
+/* We used to ICE while gimplifying the body of f
+   due to a NON_LVALUE_EXPR still being there.
+   PR c/110682*/
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct a {
+  const signed char b;
+};
+
+void f(volatile struct a *c) { /* { dg-note "" } */
+  c - 0 % c->b;
+  struct a c = {1}; /* { dg-error "redeclared as different kind of symbol" } */
+}
-- 
2.43.0

Reply via email to