public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r9-9650] d: fix ICE at convert_expr(tree_node*, Type*, Type*) (PR101490)
@ 2021-07-28 11:57 Iain Buclaw
  0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2021-07-28 11:57 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5a67fcd15dc42969dc97a9ebb292cd53f9bc0a16

commit r9-9650-g5a67fcd15dc42969dc97a9ebb292cd53f9bc0a16
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Mon Jul 26 15:11:42 2021 +0200

    d: fix ICE at convert_expr(tree_node*, Type*, Type*) (PR101490)
    
    Both the front-end and code generator had a modulo by zero bug when testing if
    a conversion from a static array to dynamic array was valid.
    
            PR d/101490
    
    gcc/d/ChangeLog:
    
            * d-codegen.cc (build_array_index): Handle void arrays same as byte.
            * d-convert.cc (convert_expr): Handle converting to zero-sized arrays.
            * dmd/dcast.c (castTo): Handle casting to zero-sized arrays.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/pr101490.d: New test.
            * gdc.test/fail_compilation/fail22144.d: New test.
    
    (cherry picked from commit c936c39f86c74b3bfc6831f694b3165296c99dc0)

Diff:
---
 gcc/d/d-codegen.cc                                  | 16 ++--------------
 gcc/d/d-convert.cc                                  | 15 ++++++++++-----
 gcc/d/dmd/dcast.c                                   | 15 +++++++++------
 gcc/testsuite/gdc.dg/pr101490.d                     | 21 +++++++++++++++++++++
 gcc/testsuite/gdc.test/fail_compilation/fail22144.d | 14 ++++++++++++++
 5 files changed, 56 insertions(+), 25 deletions(-)

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 5368b5892db..fb83770d64a 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -1606,21 +1606,9 @@ build_array_index (tree ptr, tree index)
   /* Array element size.  */
   tree size_exp = size_in_bytes (target_type);
 
-  if (integer_zerop (size_exp))
+  if (integer_zerop (size_exp) || integer_onep (size_exp))
     {
-      /* Test for array of void.  */
-      if (TYPE_MODE (target_type) == TYPE_MODE (void_type_node))
-	index = fold_convert (type, index);
-      else
-	{
-	  /* Should catch this earlier.  */
-	  error ("invalid use of incomplete type %qD", TYPE_NAME (target_type));
-	  ptr_type = error_mark_node;
-	}
-    }
-  else if (integer_onep (size_exp))
-    {
-      /* Array of bytes -- No need to multiply.  */
+      /* Array of void or bytes -- No need to multiply.  */
       index = fold_convert (type, index);
     }
   else
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 761ab3c5435..9c2f6b45a44 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -473,13 +473,18 @@ convert_expr (tree exp, Type *etype, Type *totype)
 
 	  tree ptrtype = build_ctype (tbtype->nextOf ()->pointerTo ());
 
-	  if ((dim * esize) % tsize != 0)
+	  if (esize != tsize)
 	    {
-	      error ("cannot cast %qs to %qs since sizes don't line up",
-		     etype->toChars (), totype->toChars ());
-	      return error_mark_node;
+	      /* Array element sizes do not match, so we must adjust the
+		 dimensions.  */
+	      if (tsize == 0 || (dim * esize) % tsize != 0)
+		{
+		  error ("cannot cast %qs to %qs since sizes don't line up",
+			 etype->toChars (), totype->toChars ());
+		  return error_mark_node;
+		}
+	      dim = (dim * esize) / tsize;
 	    }
-	  dim = (dim * esize) / tsize;
 
 	  /* Assumes casting to dynamic array of same type or void.  */
 	  return d_array_value (build_ctype (totype), size_int (dim),
diff --git a/gcc/d/dmd/dcast.c b/gcc/d/dmd/dcast.c
index a3df701c341..905aed72625 100644
--- a/gcc/d/dmd/dcast.c
+++ b/gcc/d/dmd/dcast.c
@@ -1494,13 +1494,16 @@ Expression *castTo(Expression *e, Scope *sc, Type *t)
                     // cast(U[])sa; // ==> cast(U[])sa[];
                     d_uns64 fsize = t1b->nextOf()->size();
                     d_uns64 tsize = tob->nextOf()->size();
-                    if ((((TypeSArray *)t1b)->dim->toInteger() * fsize) % tsize != 0)
+                    if (fsize != tsize)
                     {
-                        // copied from sarray_toDarray() in e2ir.c
-                        e->error("cannot cast expression %s of type %s to %s since sizes don't line up",
-                            e->toChars(), e->type->toChars(), t->toChars());
-                        result = new ErrorExp();
-                        return;
+                        dinteger_t dim = ((TypeSArray *)t1b)->dim->toInteger();
+                        if (tsize == 0 || (dim * fsize) % tsize != 0)
+                        {
+                            e->error("cannot cast expression `%s` of type `%s` to `%s` since sizes don't line up",
+                                     e->toChars(), e->type->toChars(), t->toChars());
+                            result = new ErrorExp();
+                            return;
+                        }
                     }
                     goto Lok;
                 }
diff --git a/gcc/testsuite/gdc.dg/pr101490.d b/gcc/testsuite/gdc.dg/pr101490.d
new file mode 100644
index 00000000000..6929d406863
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr101490.d
@@ -0,0 +1,21 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101490
+// { dg-do compile }
+
+struct S101490
+{
+    int[0] arr;
+}
+
+void main()
+{
+    S101490* t;
+    auto a = cast(typeof(t.arr)[0])t.arr;
+    write(a);
+}
+
+void write(S)(S args)
+{
+    foreach (arg; args)
+    {
+    }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22144.d b/gcc/testsuite/gdc.test/fail_compilation/fail22144.d
new file mode 100644
index 00000000000..e0fd5b19225
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22144.d
@@ -0,0 +1,14 @@
+// https://issues.dlang.org/show_bug.cgi?id=22144
+/* TEST_OUTPUT
+---
+fail_compilation/fail22144.d(12): Error: cannot cast expression `zarray1` of type `int[0]` to `int[0][]` since sizes don't line up
+---
+*/
+void main()
+{
+  int[0] zarray1;
+  int[0][0] zarray2;
+
+  auto zslice1 = cast(int[0][])zarray1; // ICE -> Error
+  auto zslice2 = cast(int[0][])zarray2; // ICE -> OK
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-28 11:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-28 11:57 [gcc r9-9650] d: fix ICE at convert_expr(tree_node*, Type*, Type*) (PR101490) Iain Buclaw

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).