Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 34 additions & 13 deletions compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,8 @@ bool isLvalue(Expression _this)
return false;
auto t1b = _this.e1.type.toBasetype();
if (t1b.isTypeAArray() || t1b.isTypeSArray() ||
(_this.e1.isIndexExp() && t1b != t1b.isTypeDArray()))
(_this.e1.isIndexExp() && t1b != t1b.isTypeDArray()) ||
_this.e1.op == EXP.arrayLiteral)
{
return _this.e1.isLvalue();
}
Expand Down Expand Up @@ -2072,9 +2073,7 @@ Expression checkNoreturnVarAccess(Expression exp)
{
auto msg = new StringExp(exp.loc, "Accessed expression of type `noreturn`");
msg.type = Type.tstring;
auto ae = new AssertExp(exp.loc, IntegerExp.literal!0, msg);
ae.loweredFrom = exp;
result = ae;
result = new AssertExp(exp.loc, IntegerExp.literal!0, msg);
result.type = exp.type;
}

Expand Down Expand Up @@ -4189,10 +4188,6 @@ private bool functionParameters(Loc loc, Scope* sc,
arg = arg.resolveLoc(loc, sc);
(*arguments)[i] = arg;
}
else if (!(p.storageClass & (STC.ref_ | STC.out_)))
{
(*arguments)[i] = checkNoreturnVarAccess(arg);
}

if (tf.parameterList.varargs == VarArg.typesafe && i + 1 == nparams) // https://dlang.org/spec/function.html#variadic
{
Expand Down Expand Up @@ -8257,7 +8252,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}

void errorHelper(const(char)* failMessage, Loc argloc) scope
void errorHelper(const(char)* failMessage, Loc loc) scope
{
OutBuffer buf;
buf.writeByte('(');
Expand All @@ -8270,7 +8265,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
.error(exp.loc, "%s `%s` is not callable using argument types `%s`",
p, exp.e1.toErrMsg(), buf.peekChars());
if (failMessage)
errorSupplemental((argloc !is Loc.initial) ? argloc : exp.loc, "%s", failMessage);
errorSupplemental(exp.loc, "%s", failMessage);
}

if (callMatch(exp.f, tf, null, exp.argumentList, 0, &errorHelper, sc) == MATCH.nomatch)
Expand Down Expand Up @@ -8333,7 +8328,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.f = exp.f.toAliasFunc();
TypeFunction tf = cast(TypeFunction)exp.f.type;

void errorHelper2(const(char)* failMessage, Loc argloc) scope
void errorHelper2(const(char)* failMessage, Loc loc) scope
{
OutBuffer buf;
buf.writeByte('(');
Expand All @@ -8351,7 +8346,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
.error(exp.loc, "%s `%s` is not callable using argument types `%s`",
exp.f.kind(), exp.f.toErrMsg(), buf.peekChars());
if (failMessage)
errorSupplemental((argloc !is Loc.initial) ? argloc : exp.loc, "%s", failMessage);
errorSupplemental(exp.loc, "%s", failMessage);
.errorSupplemental(exp.f.loc, "`%s%s` declared here", exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList));
exp.f = null;
}
Expand Down Expand Up @@ -17558,7 +17553,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);
}
Expand All @@ -17570,6 +17582,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) ||
Expand Down
1 change: 0 additions & 1 deletion compiler/test/compilable/interpret4.d
Original file line number Diff line number Diff line change
Expand Up @@ -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));
6 changes: 3 additions & 3 deletions compiler/test/fail_compilation/diag21167.d
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*
TEST_OUTPUT:
---
fail_compilation\diag21167.d(15): Error: function `f` is not callable using argument types `(int, string, int)`
fail_compilation\diag21167.d(17): cannot pass argument `"foo"` of type `string` to parameter `int __param_1`
fail_compilation\diag21167.d(11): `diag21167.f(int __param_0, int __param_1, int __param_2)` declared here
fail_compilation/diag21167.d(15): Error: function `f` is not callable using argument types `(int, string, int)`
fail_compilation/diag21167.d(15): cannot pass argument `"foo"` of type `string` to parameter `int __param_1`
fail_compilation/diag21167.d(11): `diag21167.f(int __param_0, int __param_1, int __param_2)` declared here
---
*/
// https://github.com/dlang/dmd/issues/21167
Expand Down
23 changes: 23 additions & 0 deletions compiler/test/fail_compilation/fail22328.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail22328.d(17): Error: cannot modify the content of array literal `[1, 2, 3]`
fail_compilation/fail22328.d(17): Error: cannot modify the content of array literal `[1, 2, 3]`
fail_compilation/fail22328.d(17): Error: cannot modify expression `[1, 2, 3][2]` because it is not an lvalue
fail_compilation/fail22328.d(18): Error: cannot modify the content of array literal `[10, 20]`
fail_compilation/fail22328.d(18): Error: cannot modify the content of array literal `[10, 20]`
fail_compilation/fail22328.d(18): Error: cannot modify expression `[10, 20][0]` because it is not an lvalue
fail_compilation/fail22328.d(20): Error: cannot modify the content of array literal `[1, 2, 3]`
fail_compilation/fail22328.d(22): Error: cannot take address of expression `[1, 2, 3][0]` because it is not an lvalue
---
*/

void main() {
enum ARR = [1, 2, 3];
ARR[2] = 4;
[10, 20][0] = 30;

ARR[0..2] = [4, 5];

auto p = &ARR[0];
}
14 changes: 8 additions & 6 deletions compiler/test/fail_compilation/fail6795.d
Original file line number Diff line number Diff line change
Expand Up @@ -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
---
*/

Expand Down
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/retscope3.d
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fail_compilation/retscope3.d(4003): Error: escaping a reference to parameter `u`
fail_compilation/retscope3.d(4016): Error: storing reference to outer local variable `i` into allocated memory causes it to escape
fail_compilation/retscope3.d(4025): Deprecation: slice of static array temporary returned by `makeSA()` assigned to longer lived variable `a`
fail_compilation/retscope3.d(4025): Error: escaping reference to stack allocated value returned by `makeSA()` into allocated memory
fail_compilation/retscope3.d(4032): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function
fail_compilation/retscope3.d(4032): Error: cannot take address of expression `[& i][0]` because it is not an lvalue
---
*/

Expand Down
2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/test21634.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fail_compilation/test21634.d(22): Error: function literal `(int x) { }` is not c
^
fail_compilation/test21634.d(22): cannot pass argument `"%s"` of type `string` to parameter `int x`
(int x) {} ("%s");
^
^
fail_compilation/test21634.d(24): Error: declaration `test21634.main.foo` is already defined
int foo;
^
Expand Down
11 changes: 0 additions & 11 deletions compiler/test/runnable/nogc.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/***********************/

Expand All @@ -98,7 +88,6 @@ int main()
test3032();
test12642();
test12936();
testArrayLiteralLvalue();

printf("Success\n");
return 0;
Expand Down
10 changes: 6 additions & 4 deletions compiler/test/runnable/test6795.d
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
// 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);
}

// 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);
}

Expand Down
Loading