Skip to content

Commit ba1009c

Browse files
committed
Merge pull request #702 from 9rnsr/fix7444
Issue 7444 - Require [] for array copies too
2 parents 3644943 + 8519a3a commit ba1009c

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

src/expression.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10714,6 +10714,20 @@ Expression *AssignExp::semantic(Scope *sc)
1071410714
e2 = new SliceExp(e2->loc, e2, NULL, NULL);
1071510715
e2 = e2->semantic(sc);
1071610716
}
10717+
else if (global.params.warnings && !global.gag && op == TOKassign &&
10718+
e2->op != TOKarrayliteral && e2->op != TOKstring)
10719+
{ // Disallow sa = da (Converted to sa[] = da[])
10720+
// Disallow sa = e (Converted to sa[] = e)
10721+
const char* e1str = e1->toChars();
10722+
const char* e2str = e2->toChars();
10723+
if (e2->op == TOKslice || t2->implicitConvTo(t1->nextOf()))
10724+
warning("explicit element-wise assignment (%s)[] = %s is better than %s = %s",
10725+
e1str, e2str, e1str, e2str);
10726+
else
10727+
warning("explicit element-wise assignment (%s)[] = (%s)[] is better than %s = %s",
10728+
e1str, e2str, e1str, e2str);
10729+
return new ErrorExp();
10730+
}
1071710731

1071810732
// Convert e1 to e1[]
1071910733
Expression *e = new SliceExp(e1->loc, e1, NULL, NULL);
@@ -10809,13 +10823,44 @@ Expression *AssignExp::semantic(Scope *sc)
1080910823
{
1081010824
checkPostblit(e2->loc, t2->nextOf());
1081110825
}
10826+
if (global.params.warnings && !global.gag && op == TOKassign &&
10827+
e2->op != TOKslice && e2->op != TOKassign &&
10828+
e2->op != TOKarrayliteral && e2->op != TOKstring &&
10829+
!(e2->op == TOKadd || e2->op == TOKmin ||
10830+
e2->op == TOKmul || e2->op == TOKdiv ||
10831+
e2->op == TOKmod || e2->op == TOKxor ||
10832+
e2->op == TOKand || e2->op == TOKor ||
10833+
#if DMDV2
10834+
e2->op == TOKpow ||
10835+
#endif
10836+
e2->op == TOKtilde || e2->op == TOKneg))
10837+
{
10838+
const char* e1str = e1->toChars();
10839+
const char* e2str = e2->toChars();
10840+
warning("explicit element-wise assignment %s = (%s)[] is better than %s = %s",
10841+
e1str, e2str, e1str, e2str);
10842+
return new ErrorExp();
10843+
}
1081210844
if (op == TOKconstruct)
1081310845
e2 = e2->castTo(sc, e1->type->constOf());
1081410846
else
1081510847
e2 = e2->implicitCastTo(sc, e1->type->constOf());
1081610848
}
1081710849
else
1081810850
{
10851+
if (global.params.warnings && !global.gag && op == TOKassign &&
10852+
t1->ty == Tarray && t2->ty == Tsarray &&
10853+
e2->op != TOKslice && //e2->op != TOKarrayliteral &&
10854+
t2->implicitConvTo(t1))
10855+
{ // Disallow ar[] = sa (Converted to ar[] = sa[])
10856+
// Disallow da = sa (Converted to da = sa[])
10857+
const char* e1str = e1->toChars();
10858+
const char* e2str = e2->toChars();
10859+
warning("explicit %s assignment %s = (%s)[] is better than %s = %s",
10860+
e1->op == TOKslice ? "element-wise" : "slice",
10861+
e1str, e2str, e1str, e2str);
10862+
return new ErrorExp();
10863+
}
1081910864
e2 = e2->implicitCastTo(sc, e1->type);
1082010865
}
1082110866
if (e2->op == TOKerror)

test/fail_compilation/warn7444.d

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// REQUIRED_ARGS: -w
2+
// PERMUTE_ARGS:
3+
4+
/*
5+
TEST_OUTPUT:
6+
---
7+
fail_compilation/warn7444.d(30): Warning: explicit element-wise assignment (sa)[] = e is better than sa = e
8+
fail_compilation/warn7444.d(32): Error: cannot implicitly convert expression (e) of type int to int[]
9+
fail_compilation/warn7444.d(37): Warning: explicit element-wise assignment (sa)[] = sa[] is better than sa = sa[]
10+
fail_compilation/warn7444.d(38): Warning: explicit element-wise assignment sa[] = (sa)[] is better than sa[] = sa
11+
fail_compilation/warn7444.d(41): Warning: explicit element-wise assignment (sa)[] = (da)[] is better than sa = da
12+
fail_compilation/warn7444.d(42): Warning: explicit element-wise assignment (sa)[] = da[] is better than sa = da[]
13+
fail_compilation/warn7444.d(43): Warning: explicit element-wise assignment sa[] = (da)[] is better than sa[] = da
14+
fail_compilation/warn7444.d(47): Warning: explicit slice assignment da = (sa)[] is better than da = sa
15+
fail_compilation/warn7444.d(49): Warning: explicit element-wise assignment da[] = (sa)[] is better than da[] = sa
16+
fail_compilation/warn7444.d(54): Warning: explicit element-wise assignment da[] = (da)[] is better than da[] = da
17+
---
18+
*/
19+
20+
void test7444()
21+
{
22+
int[2] sa;
23+
int[] da;
24+
int e;
25+
26+
{
27+
// X: Changed accepts-invalid to rejects-invalid by this issue
28+
// a: slice assginment
29+
// b: element-wise assignment
30+
sa = e; // X
31+
sa[] = e; // b
32+
da = e;
33+
da[] = e; // b
34+
35+
// lhs is static array
36+
sa = sa; // b == identity assign
37+
sa = sa[]; // X
38+
sa[] = sa; // X
39+
sa[] = sa[]; // b
40+
41+
sa = da; // X
42+
sa = da[]; // X
43+
sa[] = da; // X
44+
sa[] = da[]; // b
45+
46+
// lhs is dynamic array
47+
da = sa; // X
48+
da = sa[]; // a
49+
da[] = sa; // X
50+
da[] = sa[]; // b
51+
52+
da = da; // a == identity assign
53+
da = da[]; // a
54+
da[] = da; // X
55+
da[] = da[]; // b
56+
}
57+
}

0 commit comments

Comments
 (0)