public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C PATCH] PR c/109618: ICE-after-error from error_mark_node.
@ 2024-04-29 23:06 Roger Sayle
  2024-04-30  7:37 ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: Roger Sayle @ 2024-04-29 23:06 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1597 bytes --]


This patch solves another ICE-after-error problem in the C family
front-ends.  Upon a conflicting type redeclaration, the ambiguous
type is poisoned with an error_mark_node to indicate to the middle-end
that the type is suspect, but care has to be taken by the front-end to
avoid passing these malformed trees into the middle-end during error
recovery. In this case, a var_decl with a poisoned type appears within
a sizeof() expression (wrapped in NOP_EXPR) which causes problems.

This revision of the patch tests seen_error() to avoid tree traversal
(STRIP_NOPs) in the most common case that an error hasn't occurred.
Both this version (and an earlier revision that didn't test seen_error)
have survived bootstrap and regression testing on x86_64-pc-linux-gnu.
As a consolation, this code also contains a minor performance improvement,
by avoiding trying to create (and folding away) a CEIL_DIV_EXPR in the
common case that "char" is a single-byte.  The current code relies on
the middle-end's tree folding to recognize that CEIL_DIV_EXPR of
integer_one_node is a no-op, that can be optimized away.

Ok for mainline?


2024-04-30  Roger Sayle  <roger@nextmovesoftware.com>

gcc/c-family/ChangeLog
        PR c/109618
        * c-common.cc (c_sizeof_or_alignof_type): If seen_error() check
        whether value is (a VAR_DECL) of type error_mark_node, or a
        NOP_EXPR thereof.  Avoid folding CEIL_DIV_EXPR for the common
        case where char_type is a single byte.

gcc/testsuite/ChangeLog
        PR c/109618
        * gcc.dg/pr109618.c: New test case.


Thanks in advance,
Roger
--


[-- Attachment #2: patcher2.txt --]
[-- Type: text/plain, Size: 1758 bytes --]

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 6fa8243..be8ff09 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -3993,10 +3993,31 @@ c_sizeof_or_alignof_type (location_t loc,
   else
     {
       if (is_sizeof)
-	/* Convert in case a char is more than one unit.  */
-	value = size_binop_loc (loc, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
-				size_int (TYPE_PRECISION (char_type_node)
-					  / BITS_PER_UNIT));
+	{
+	  value = TYPE_SIZE_UNIT (type);
+
+	  /* PR 109618: Check for erroneous types, stripping NOPs.  */
+	  if (seen_error ())
+	    {
+	      tree tmp = value;
+	      while (CONVERT_EXPR_P (tmp)
+		     || TREE_CODE (tmp) == NON_LVALUE_EXPR)
+		{
+		  if (TREE_TYPE (tmp) == error_mark_node)
+		    return error_mark_node;
+		  tmp = TREE_OPERAND (tmp, 0);
+		}
+	      if (tmp == error_mark_node
+		  || TREE_TYPE (tmp) == error_mark_node)
+		return error_mark_node;
+	    }
+
+	  /* Convert in case a char is more than one unit.  */
+	  if (TYPE_PRECISION (char_type_node) != BITS_PER_UNIT)
+	    value = size_binop_loc (loc, CEIL_DIV_EXPR, value,
+				    size_int (TYPE_PRECISION (char_type_node)
+					      / BITS_PER_UNIT));
+	}
       else if (min_alignof)
 	value = size_int (min_align_of_type (type));
       else
diff --git a/gcc/testsuite/gcc.dg/pr109618.c b/gcc/testsuite/gcc.dg/pr109618.c
new file mode 100644
index 0000000..f240907
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr109618.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+int foo()
+{
+  const unsigned int var_1 = 2;
+  
+  char var_5[var_1];
+  
+  int var_1[10];  /* { dg-error "conflicting type" } */
+  
+  return sizeof(var_5);
+}
+

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-05-02  9:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-29 23:06 [C PATCH] PR c/109618: ICE-after-error from error_mark_node Roger Sayle
2024-04-30  7:37 ` Richard Biener
2024-04-30  8:23   ` Roger Sayle
2024-04-30  9:17     ` Richard Biener
2024-04-30 15:14       ` Roger Sayle
2024-05-02  9:57         ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).