diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index eb6cca75a85f..83cde15bb180 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -17561,7 +17561,24 @@ Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag = ModifyF //printf("SliceExp::checkModifiable %s\n", sliceExp.toChars()); auto e1 = sliceExp.e1; - if (e1.type.ty == Tsarray || (e1.op == EXP.index && e1.type.ty != Tarray) || e1.op == EXP.slice) + + if (e1.op == EXP.arrayLiteral || e1.op == EXP.structLiteral) + { + if (!(flag & ModifyFlags.noError)) + { + if (e1.type.ty != Terror) + { + error(exp.loc, "cannot modify the content of %s literal `%s`", + e1.op == EXP.arrayLiteral ? "array".ptr : "struct".ptr, + e1.toChars()); + } + } + return Modifiable.no; + } + + if (e1.type.ty == Tsarray || + (e1.op == EXP.index && e1.type.ty != Tarray) || + e1.op == EXP.slice) { return e1.checkModifiable(sc, flag); } @@ -17573,6 +17590,15 @@ Modifiable checkModifiable(Expression exp, Scope* sc, ModifyFlags flag = ModifyF case EXP.index: auto indexExp = cast(IndexExp)exp; auto e1 = indexExp.e1; + + if (e1.op == EXP.arrayLiteral || e1.op == EXP.structLiteral) + { + if (!(flag & ModifyFlags.noError)) + error(exp.loc, "cannot modify the content of %s literal `%s`", + e1.op == EXP.arrayLiteral ? "array".ptr : "struct".ptr, + e1.toChars()); + return Modifiable.no; + } if (e1.type.ty == Tsarray || e1.type.ty == Taarray || (e1.op == EXP.index && e1.type.ty != Tarray) || diff --git a/compiler/test/compilable/interpret4.d b/compiler/test/compilable/interpret4.d index 98ebcdff745a..ef0a9598fbef 100644 --- a/compiler/test/compilable/interpret4.d +++ b/compiler/test/compilable/interpret4.d @@ -43,6 +43,5 @@ int* find(int[] arr, int needle) enum int[int] aa = [0: 0]; enum int[] da = [0, 1, 2]; static assert(0 in aa); -static assert(&da[1]); static assert(find(da, 1)); static assert(!find(da, 3)); diff --git a/compiler/test/fail_compilation/array_literal_assign.d b/compiler/test/fail_compilation/array_literal_assign.d index f10b5d63c12c..16a8bdc75c56 100644 --- a/compiler/test/fail_compilation/array_literal_assign.d +++ b/compiler/test/fail_compilation/array_literal_assign.d @@ -1,10 +1,17 @@ /* TEST_OUTPUT: --- -fail_compilation/array_literal_assign.d(13): Error: discarded assignment to indexed array literal -fail_compilation/array_literal_assign.d(15): Error: discarded assignment to indexed array literal -fail_compilation/array_literal_assign.d(16): Error: discarded assignment to indexed array literal -fail_compilation/array_literal_assign.d(17): Error: discarded assignment to indexed array literal +fail_compilation/array_literal_assign.d(20): Error: cannot modify the content of array literal `[1, 2, 3]` +fail_compilation/array_literal_assign.d(20): Error: cannot modify the content of array literal `[1, 2, 3]` +fail_compilation/array_literal_assign.d(20): Error: discarded assignment to indexed array literal +fail_compilation/array_literal_assign.d(22): Error: cannot modify the content of array literal `[1, 2]` +fail_compilation/array_literal_assign.d(22): Error: discarded assignment to indexed array literal +fail_compilation/array_literal_assign.d(23): Error: cannot modify the content of array literal `[1, 2]` +fail_compilation/array_literal_assign.d(23): Error: discarded assignment to indexed array literal +fail_compilation/array_literal_assign.d(24): Error: cannot modify the content of array literal `[1, 2]` +fail_compilation/array_literal_assign.d(24): Error: discarded assignment to indexed array literal +fail_compilation/array_literal_assign.d(26): Error: cannot modify the content of array literal `[1, 2]` +fail_compilation/array_literal_assign.d(26): Error: cannot modify the content of array literal `[1, 2]` --- */ diff --git a/compiler/test/fail_compilation/fail22328.d b/compiler/test/fail_compilation/fail22328.d new file mode 100644 index 000000000000..fece144963dc --- /dev/null +++ b/compiler/test/fail_compilation/fail22328.d @@ -0,0 +1,22 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/fail22328.d(16): Error: cannot modify the content of array literal `[1, 2, 3]` +fail_compilation/fail22328.d(16): Error: cannot modify the content of array literal `[1, 2, 3]` +fail_compilation/fail22328.d(16): Error: discarded assignment to indexed array literal +fail_compilation/fail22328.d(17): Error: cannot modify the content of array literal `[10, 20]` +fail_compilation/fail22328.d(17): Error: cannot modify the content of array literal `[10, 20]` +fail_compilation/fail22328.d(17): Error: discarded assignment to indexed array literal +fail_compilation/fail22328.d(19): Error: cannot modify the content of array literal `[1, 2, 3]` +--- +*/ + +void main() { + enum ARR = [1, 2, 3]; + ARR[2] = 4; + [10, 20][0] = 30; + + ARR[0..2] = [4, 5]; + + auto p = &ARR[0]; +} diff --git a/compiler/test/fail_compilation/fail6795.d b/compiler/test/fail_compilation/fail6795.d index e566aff570a9..dc25f50e0cc5 100644 --- a/compiler/test/fail_compilation/fail6795.d +++ b/compiler/test/fail_compilation/fail6795.d @@ -2,12 +2,14 @@ /* TEST_OUTPUT: --- -fail_compilation/fail6795.d(19): Error: cannot modify expression `[0][0]` because it is not an lvalue -fail_compilation/fail6795.d(20): Error: cannot modify expression `[0:0][0]` because it is not an lvalue -fail_compilation/fail6795.d(22): Error: cannot modify expression `[0][0]` because it is not an lvalue -fail_compilation/fail6795.d(23): Error: cannot modify expression `[0:0][0]` because it is not an lvalue -fail_compilation/fail6795.d(25): Error: cannot take address of expression `[0][0]` because it is not an lvalue -fail_compilation/fail6795.d(30): Error: cannot modify expression `Some["zz"]` because it is not an lvalue +fail_compilation/fail6795.d(21): Error: cannot modify the content of array literal `[0]` +fail_compilation/fail6795.d(21): Error: cannot modify expression `[0][0]` because it is not an lvalue +fail_compilation/fail6795.d(22): Error: cannot modify expression `[0:0][0]` because it is not an lvalue +fail_compilation/fail6795.d(24): Error: cannot modify the content of array literal `[0]` +fail_compilation/fail6795.d(24): Error: cannot modify expression `[0][0]` because it is not an lvalue +fail_compilation/fail6795.d(25): Error: cannot modify expression `[0:0][0]` because it is not an lvalue +fail_compilation/fail6795.d(27): Error: cannot take address of expression `[0][0]` because it is not an lvalue +fail_compilation/fail6795.d(32): Error: cannot modify expression `Some["zz"]` because it is not an lvalue --- */ diff --git a/compiler/test/runnable/nogc.d b/compiler/test/runnable/nogc.d index c71866fc1995..523a7a99bcb4 100644 --- a/compiler/test/runnable/nogc.d +++ b/compiler/test/runnable/nogc.d @@ -79,16 +79,6 @@ void testIndexedArrayLiteral() @nogc assert(arr[i] == 400); } -void testArrayLiteralLvalue() -{ - // https://github.com/dlang/dmd/pull/16784 - // Test that this array literal is *not* put on the stack because - // it gets its address taken - static int* getPtr(int i) => &[1, 2, 3][i]; - int* x = getPtr(1); - int* y = getPtr(1); - assert(x != y); -} /***********************/ @@ -98,7 +88,6 @@ int main() test3032(); test12642(); test12936(); - testArrayLiteralLvalue(); printf("Success\n"); return 0; diff --git a/compiler/test/runnable/test6795.d b/compiler/test/runnable/test6795.d index 7e44fd4ad7a7..eef57a95a34d 100644 --- a/compiler/test/runnable/test6795.d +++ b/compiler/test/runnable/test6795.d @@ -1,13 +1,13 @@ // https://issues.dlang.org/show_bug.cgi?id=6795 void check6795() { - enum int[] array = [0]; + auto array = [0]; // PostExp assert(array[0]++ == 0); - assert(array[0]-- == 0); + assert(array[0]-- == 1); // PreExp assert(++array[0] == 1); - assert(--array[0] == -1); + assert(--array[0] == 0); // BinAssignExp assert((array[0] += 3) == 3); } @@ -15,7 +15,9 @@ void check6795() // https://issues.dlang.org/show_bug.cgi?id=21312 void check21312() { - auto p = &[123][0]; + int[1] tmp = [123]; + auto p = &tmp[0]; + assert(*p == 123); }