Skip to content

Commit

Permalink
Merge pull request #361 from donc/ctfebreak
Browse files Browse the repository at this point in the history
CTFE: wrong-code bug 6558: out-by-1 error in UTF foreach
  • Loading branch information
WalterBright committed Sep 1, 2011
2 parents 8945eae + d0e2e78 commit 34f2b4d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
6 changes: 4 additions & 2 deletions src/interpret.c
Expand Up @@ -5154,6 +5154,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del

const char *errmsg = NULL; // Used for reporting decoding errors
dchar_t rawvalue; // Holds the decoded dchar
size_t currentIndex = indx; // The index of the decoded character

if (ale)
{ // If it is an array literal, copy the code points into the buffer
Expand Down Expand Up @@ -5296,13 +5297,14 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del
default:
assert(0);
}

if (rvs)
currentIndex = indx;

// Step 3: call the delegate once for each code point

// The index only needs to be set once
if (numParams == 2)
args.tdata()[0] = new IntegerExp(deleg->loc, indx, indexType);
args.tdata()[0] = new IntegerExp(deleg->loc, currentIndex, indexType);

Expression *val = NULL;

Expand Down
29 changes: 22 additions & 7 deletions test/compilable/interpret3.d
Expand Up @@ -2295,6 +2295,7 @@ static assert(bug4021());

/**************************************************
3512 foreach(dchar; string)
6558 foreach(int, dchar; string)
**************************************************/

bool test3512()
Expand All @@ -2308,16 +2309,24 @@ bool test3512()
assert(q==4);
foreach (dchar c; s) { ++q; if (c=='h') break; } // _aApplycd1
assert(q == 6);
foreach (int i, wchar c; s) {} // _aApplycw2
foreach (int i, dchar c; s) {} // _aApplycd2
foreach (int i, wchar c; s) {
assert(i >= 0 && i < s.length);
} // _aApplycw2
foreach (int i, dchar c; s) {
assert(i >= 0 && i < s.length);
} // _aApplycd2

wstring w = "xüm";
foreach (char c; w) {++q; } // _aApplywc1
assert(q == 10);
foreach (dchar c; w) { ++q; } // _aApplywd1
assert(q == 13);
foreach (int i, char c; w) {} // _aApplywc2
foreach (int i, dchar c; w) {} // _aApplywd2
foreach (int i, char c; w) {
assert(i >= 0 && i < w.length);
} // _aApplywc2
foreach (int i, dchar c; w) {
assert(i >= 0 && i < w.length);
} // _aApplywd2

dstring d = "yäq";
q = 0;
Expand All @@ -2326,15 +2335,21 @@ bool test3512()
q = 0;
foreach (wchar c; d) { ++q; } // _aApplydw1
assert(q == 3);
foreach (int i, char c; d) {} // _aApplydc2
foreach (int i, wchar c; d) {} // _aApplydw2
foreach (int i, char c; d) {
assert(i >= 0 && i < d.length);
} // _aApplydc2
foreach (int i, wchar c; d) {
assert(i >= 0 && i < d.length);
} // _aApplydw2

dchar[] dr = "squop"d.dup;
foreach(int n, char c; dr) { if (n==2) break; assert(c!='o'); }
foreach_reverse (char c; dr) {} // _aApplyRdc1
foreach_reverse (wchar c; dr) {} // _aApplyRdw1
foreach_reverse (int n, char c; dr) { if (n==4) break; assert(c!='o');} // _aApplyRdc2
foreach_reverse (int i, wchar c; dr) {} // _aApplyRdw2
foreach_reverse (int i, wchar c; dr) {
assert(i >= 0 && i < dr.length);
} // _aApplyRdw2
q = 0;
wstring w2 = ['x', 'ü', 'm']; // foreach over array literals
foreach_reverse (int n, char c; w2)
Expand Down

0 comments on commit 34f2b4d

Please sign in to comment.