diff options
-rw-r--r-- | gcc/d/d-codegen.cc | 16 | ||||
-rw-r--r-- | gcc/d/d-convert.cc | 15 | ||||
-rw-r--r-- | gcc/d/dmd/MERGE | 2 | ||||
-rw-r--r-- | gcc/d/dmd/dcast.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gdc.dg/pr101490.d | 21 | ||||
-rw-r--r-- | gcc/testsuite/gdc.test/fail_compilation/fail22144.d | 14 |
6 files changed, 57 insertions, 26 deletions
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index ce7c17b..f35de90 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -1639,21 +1639,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 3073eda..237c084 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 do not 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 do not 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/MERGE b/gcc/d/dmd/MERGE index 08bd50d..2568993 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -f8c1ca928360dd8c9f2fbb5771e2a5e398878ca0 +27e388b4c4d292cac25811496aaf79341c05c940 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/dcast.c b/gcc/d/dmd/dcast.c index 4dd648b..d84ab7f 100644 --- a/gcc/d/dmd/dcast.c +++ b/gcc/d/dmd/dcast.c @@ -1496,13 +1496,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 0000000..6929d40 --- /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 0000000..e0fd5b1 --- /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 +} |