More 64 fixes for semantic errors that only show up when templates are instantiated via unittests. Now I'm actually serious about Phobos passing semantic analysis, except for a few modules due to weird druntime issues.

This commit is contained in:
David Simcha 2010-11-10 05:25:50 +00:00
parent 5b123f9d18
commit 8331c70969
9 changed files with 89 additions and 74 deletions

View file

@ -1172,7 +1172,7 @@ private:
static if(isBidirectionalRange!Range) static if(isBidirectionalRange!Range)
{ {
static int lastIndexOf(Range haystack, Separator needle) static sizediff_t lastIndexOf(Range haystack, Separator needle)
{ {
immutable index = indexOf(retro(haystack), needle); immutable index = indexOf(retro(haystack), needle);
return (index == -1) ? -1 : haystack.length - 1 - index; return (index == -1) ? -1 : haystack.length - 1 - index;
@ -2431,7 +2431,7 @@ if (Ranges.length > 1 && allSatisfy!(isForwardRange, Ranges))
{ {
for (;; haystack.popFront) for (;; haystack.popFront)
{ {
auto r = startsWith!pred(haystack, needles); size_t r = startsWith!pred(haystack, needles);
if (r || haystack.empty) if (r || haystack.empty)
{ {
return tuple(haystack, r); return tuple(haystack, r);
@ -2515,10 +2515,10 @@ struct BoyerMooreFinder(alias pred, Range)
{ {
private: private:
size_t skip[]; size_t skip[];
int[ElementType!(Range)] occ; sizediff_t[ElementType!(Range)] occ;
Range needle; Range needle;
int occurrence(ElementType!(Range) c) sizediff_t occurrence(ElementType!(Range) c)
{ {
auto p = c in occ; auto p = c in occ;
return p ? *p : -1; return p ? *p : -1;
@ -2535,8 +2535,8 @@ is ignored.
static bool needlematch(R)(R needle, static bool needlematch(R)(R needle,
size_t portion, size_t offset) size_t portion, size_t offset)
{ {
int virtual_begin = needle.length - offset - portion; sizediff_t virtual_begin = needle.length - offset - portion;
int ignore = 0; sizediff_t ignore = 0;
if (virtual_begin < 0) { if (virtual_begin < 0) {
ignore = -virtual_begin; ignore = -virtual_begin;
virtual_begin = 0; virtual_begin = 0;
@ -3815,7 +3815,7 @@ struct Levenshtein(Range, alias equals, CostType = size_t)
EditOp[] path() EditOp[] path()
{ {
EditOp[] result; EditOp[] result;
uint i = rows - 1, j = cols - 1; size_t i = rows - 1, j = cols - 1;
// restore the path // restore the path
while (i || j) { while (i || j) {
auto cIns = j == 0 ? CostType.max : _matrix[i][j - 1]; auto cIns = j == 0 ? CostType.max : _matrix[i][j - 1];
@ -3850,9 +3850,9 @@ private:
_insertionIncrement = 1, _insertionIncrement = 1,
_substitutionIncrement = 1; _substitutionIncrement = 1;
CostType[][] _matrix; CostType[][] _matrix;
uint rows, cols; size_t rows, cols;
void AllocMatrix(uint r, uint c) { void AllocMatrix(size_t r, size_t c) {
rows = r; rows = r;
cols = c; cols = c;
if (!_matrix || _matrix.length < r || _matrix[0].length < c) { if (!_matrix || _matrix.length < r || _matrix[0].length < c) {
@ -3906,7 +3906,7 @@ size_t levenshteinDistance(alias equals = "a == b", Range1, Range2)
(Range1 s, Range2 t) (Range1 s, Range2 t)
if (isForwardRange!(Range1) && isForwardRange!(Range2)) if (isForwardRange!(Range1) && isForwardRange!(Range2))
{ {
Levenshtein!(Range1, binaryFun!(equals), uint) lev; Levenshtein!(Range1, binaryFun!(equals), size_t) lev;
return lev.distance(s, t); return lev.distance(s, t);
} }
@ -5036,7 +5036,7 @@ unittest
//scope(failure) writeln(stderr, "Failure testing algorithm"); //scope(failure) writeln(stderr, "Failure testing algorithm");
//auto v = ([ 25, 7, 9, 2, 0, 5, 21 ]).dup; //auto v = ([ 25, 7, 9, 2, 0, 5, 21 ]).dup;
int[] v = [ 7, 6, 5, 4, 3, 2, 1, 0 ]; int[] v = [ 7, 6, 5, 4, 3, 2, 1, 0 ];
auto n = 3; sizediff_t n = 3;
topN!("a < b")(v, n); topN!("a < b")(v, n);
assert(reduce!max(v[0 .. n]) <= v[n]); assert(reduce!max(v[0 .. n]) <= v[n]);
assert(reduce!min(v[n + 1 .. $]) >= v[n]); assert(reduce!min(v[n + 1 .. $]) >= v[n]);
@ -6224,11 +6224,11 @@ unittest
debug(std_algorithm) scope(success) debug(std_algorithm) scope(success)
writeln("unittest @", __FILE__, ":", __LINE__, " done."); writeln("unittest @", __FILE__, ":", __LINE__, " done.");
auto r = Random(unpredictableSeed); auto r = Random(unpredictableSeed);
int[] a = new int[uniform(1, 1000, r)]; sizediff_t[] a = new sizediff_t[uniform(1, 1000, r)];
foreach (i, ref e; a) e = i; foreach (i, ref e; a) e = i;
randomShuffle(a, r); randomShuffle(a, r);
auto n = uniform(0, a.length, r); auto n = uniform(0, a.length, r);
int[] b = new int[n]; sizediff_t[] b = new sizediff_t[n];
topNCopy!(binaryFun!("a < b"))(a, b, SortOutput.yes); topNCopy!(binaryFun!("a < b"))(a, b, SortOutput.yes);
assert(isSorted!(binaryFun!("a < b"))(b)); assert(isSorted!(binaryFun!("a < b"))(b));
} }

View file

@ -314,7 +314,7 @@ Generally a container may define several types of ranges.
assert(0); assert(0);
} }
/// Ditto /// Ditto
void opIndexAssign(T value, uint i) void opIndexAssign(T value, size_t i)
{ {
assert(0); assert(0);
} }
@ -2775,7 +2775,7 @@ struct Array(T) if (is(T == bool))
return _outer[_a + i]; return _outer[_a + i];
} }
/// Ditto /// Ditto
void opIndexAssign(T value, uint i) void opIndexAssign(T value, size_t i)
{ {
_outer[_a + i] = value; _outer[_a + i] = value;
} }

View file

@ -1835,7 +1835,7 @@ time and computes all matches of length 1.
size_t iMin = size_t.max, jMin = size_t.max, size_t iMin = size_t.max, jMin = size_t.max,
iMax = 0, jMax = 0; iMax = 0, jMax = 0;
/* initialize */ /* initialize */
Tuple!(uint, uint) * k0; Tuple!(size_t, size_t) * k0;
size_t k0len; size_t k0len;
scope(exit) free(k0); scope(exit) free(k0);
currentValue = 0; currentValue = 0;

View file

@ -952,7 +952,7 @@ struct RandomCover(Range, Random)
++_alreadyChosen; // means we're done ++_alreadyChosen; // means we're done
return; return;
} }
uint k = _input.length - _alreadyChosen; size_t k = _input.length - _alreadyChosen;
uint i; uint i;
foreach (e; _input) foreach (e; _input)
{ {

View file

@ -2407,7 +2407,7 @@ struct Repeat(T)
/// Ditto /// Ditto
@property Repeat!(T) save() { return this; } @property Repeat!(T) save() { return this; }
/// Ditto /// Ditto
ref T opIndex(uint) { return _value; } ref T opIndex(size_t) { return _value; }
} }
/// Ditto /// Ditto
@ -3481,7 +3481,10 @@ struct Recurrence(alias fun, StateType, size_t stateSize)
void popFront() void popFront()
{ {
_state[_n % stateSize] = binaryFun!(fun, "a", "n")( // The cast here is reasonable because fun may cause integer
// promotion, but needs to return a StateType to make its operation
// closed. Therefore, we have no other choice.
_state[_n % stateSize] = cast(StateType) binaryFun!(fun, "a", "n")(
cycle(_state), _n + stateSize); cycle(_state), _n + stateSize);
++_n; ++_n;
} }
@ -3555,7 +3558,7 @@ struct Sequence(alias fun, State)
{ {
private: private:
alias binaryFun!(fun, "a", "n") compute; alias binaryFun!(fun, "a", "n") compute;
alias typeof(compute(State.init, 1u)) ElementType; alias typeof(compute(State.init, cast(size_t) 1)) ElementType;
State _state; State _state;
size_t _n; size_t _n;
ElementType _cache; ElementType _cache;
@ -3725,7 +3728,9 @@ struct Iota(N, S) if ((isIntegral!N || isPointer!N) && isIntegral!S) {
/// Ditto /// Ditto
N opIndex(size_t n) N opIndex(size_t n)
{ {
return current + step * n; // Just cast to N here because doing so gives overflow behavior
// consistent with calling popFront() n times.
return cast(N) (current + step * n);
} }
/// Ditto /// Ditto
typeof(this) opSlice() typeof(this) opSlice()
@ -5254,7 +5259,7 @@ Releases the controlled range and returns it.
*/ */
typeof(this) lowerBound(V)(V value) typeof(this) lowerBound(V)(V value)
{ {
auto first = 0, count = this._input.length; size_t first = 0, count = this._input.length;
while (count > 0) while (count > 0)
{ {
immutable step = count / 2; immutable step = count / 2;
@ -5300,7 +5305,7 @@ Releases the controlled range and returns it.
*/ */
typeof(this) upperBound(V)(V value) typeof(this) upperBound(V)(V value)
{ {
auto first = 0; size_t first = 0;
size_t count = length; size_t count = length;
while (count > 0) while (count > 0)
{ {

View file

@ -181,7 +181,7 @@ auto s = regex(r"p[1-5]\s*"w, "g");
struct Regex(E) if (is(E == Unqual!E)) struct Regex(E) if (is(E == Unqual!E))
{ {
private: private:
alias Tuple!(uint, "startIdx", uint, "endIdx") regmatch_t; alias Tuple!(size_t, "startIdx", size_t, "endIdx") regmatch_t;
enum REA enum REA
{ {
global = 1, // has the g attribute global = 1, // has the g attribute
@ -388,7 +388,7 @@ Returns the number of parenthesized captures
{ {
auto bitbuf = new OutBuffer; auto bitbuf = new OutBuffer;
auto r = new Range(bitbuf); auto r = new Range(bitbuf);
uint offset = i; size_t offset = i;
if (starrchars(r, prog[i .. prog.length])) if (starrchars(r, prog[i .. prog.length]))
{ {
debug(regex) printf("\tfilter built\n"); debug(regex) printf("\tfilter built\n");
@ -432,11 +432,12 @@ Returns the number of parenthesized captures
auto gotooffset = buf.offset; auto gotooffset = buf.offset;
buf.write(REgoto); buf.write(REgoto);
buf.write(cast(uint)0); buf.write(cast(uint)0);
immutable len1 = buf.offset - offset; immutable uint len1 = cast(uint) (buf.offset - offset);
buf.spread(offset, 1 + uint.sizeof); buf.spread(offset, 1 + uint.sizeof);
gotooffset += 1 + uint.sizeof; gotooffset += 1 + uint.sizeof;
parseRegex(pattern, p, buf); parseRegex(pattern, p, buf);
immutable len2 = buf.offset - (gotooffset + 1 + uint.sizeof); immutable len2 = cast(uint)
(buf.offset - (gotooffset + 1 + uint.sizeof));
buf.data[offset] = REor; buf.data[offset] = REor;
(cast(uint *)&buf.data[offset + 1])[0] = len1; (cast(uint *)&buf.data[offset + 1])[0] = len1;
(cast(uint *)&buf.data[gotooffset + 1])[0] = len2; (cast(uint *)&buf.data[gotooffset + 1])[0] = len2;
@ -456,7 +457,7 @@ Returns the number of parenthesized captures
uint n; uint n;
uint m; uint m;
ubyte op; ubyte op;
int plength = pattern.length; sizediff_t plength = pattern.length;
//printf("parsePiece() '%.*s'\n", pattern[p .. pattern.length]); //printf("parsePiece() '%.*s'\n", pattern[p .. pattern.length]);
offset = buf.offset; offset = buf.offset;
@ -585,7 +586,7 @@ Returns the number of parenthesized captures
re_nsub++; re_nsub++;
parseRegex(pattern, p, buf); parseRegex(pattern, p, buf);
*cast(uint *)&buf.data[offset] = *cast(uint *)&buf.data[offset] =
buf.offset - (offset + uint.sizeof * 2); cast(uint) (buf.offset - (offset + uint.sizeof * 2));
if (p == pattern.length || pattern[p] != ')') if (p == pattern.length || pattern[p] != ')')
{ {
error("')' expected"); error("')' expected");
@ -686,8 +687,8 @@ Returns the number of parenthesized captures
{ {
// Look ahead and see if we can make this into // Look ahead and see if we can make this into
// an REstring // an REstring
int q = p; sizediff_t q = p;
int len; sizediff_t len;
for (; q < pattern.length; ++q) for (; q < pattern.length; ++q)
{ auto qc = pattern[q]; { auto qc = pattern[q];
@ -777,7 +778,7 @@ Returns the number of parenthesized captures
maxc = u; maxc = u;
uint b = u / 8; uint b = u / 8;
if (b >= maxb) if (b >= maxb)
{ uint u2; { size_t u2;
u2 = base ? base - &buf.data[0] : 0; u2 = base ? base - &buf.data[0] : 0;
buf.fill0(b - maxb + 1); buf.fill0(b - maxb + 1);
@ -1807,8 +1808,8 @@ Returns $(D hit) (converted to $(D string) if necessary).
private Range replaceAll(String)(String format) private Range replaceAll(String)(String format)
{ {
auto result = input; auto result = input;
uint lastindex = 0; size_t lastindex = 0;
uint offset = 0; size_t offset = 0;
for (;;) for (;;)
{ {
if (!test(lastindex)) if (!test(lastindex))
@ -1936,7 +1937,7 @@ Returns $(D hit) (converted to $(D string) if necessary).
*/ */
//alias test opEquals; //alias test opEquals;
private bool chr(ref uint si, E c) private bool chr(ref size_t si, E c)
{ {
for (; si < input.length; si++) for (; si < input.length; si++)
{ {
@ -1946,7 +1947,7 @@ Returns $(D hit) (converted to $(D string) if necessary).
return 0; return 0;
} }
private static int icmp(E[] a, E[] b) private static sizediff_t icmp(E[] a, E[] b)
{ {
static if (is(Unqual!(E) == char)) static if (is(Unqual!(E) == char))
{ {
@ -1984,16 +1985,16 @@ Returns $(D hit) (converted to $(D string) if necessary).
* 0 no match * 0 no match
*/ */
private bool trymatch(uint pc, uint pcend) private bool trymatch(size_t pc, size_t pcend)
{ {
uint len; size_t len;
uint n; size_t n;
uint m; size_t m;
uint count; size_t count;
uint pop; size_t pop;
uint ss; size_t ss;
uint c1; size_t c1;
uint c2; size_t c2;
ushort* pu; ushort* pu;
uint* puint; uint* puint;
@ -2231,7 +2232,7 @@ Returns $(D hit) (converted to $(D string) if necessary).
if (trymatch(pop, pcend)) if (trymatch(pop, pcend))
{ {
if (pcend != engine.program.length) if (pcend != engine.program.length)
{ int s; { sizediff_t s;
s = src; s = src;
if (trymatch(pcend, engine.program.length)) if (trymatch(pcend, engine.program.length))
@ -2322,7 +2323,7 @@ Returns $(D hit) (converted to $(D string) if necessary).
if (engine.program[pc] == engine.REnmq) // if minimal munch if (engine.program[pc] == engine.REnmq) // if minimal munch
{ {
for (; count < m; count++) for (; count < m; count++)
{ int s1; { sizediff_t s1;
memcpy(psave, pmatch.ptr, memcpy(psave, pmatch.ptr,
(engine.re_nsub + 1) * regmatch_t.sizeof); (engine.re_nsub + 1) * regmatch_t.sizeof);
@ -2551,8 +2552,8 @@ and, using the format string, generate and return a new string.
{ {
string result; string result;
uint c2; uint c2;
int startIdx; sizediff_t startIdx;
int endIdx; sizediff_t endIdx;
int i; int i;
result.length = format.length; result.length = format.length;
@ -2881,8 +2882,8 @@ Range replace(alias fun, Range, Regex)
auto r = match(s, rx); auto r = match(s, rx);
auto result = s; auto result = s;
auto lastindex = 0; size_t lastindex = 0;
auto offset = 0; size_t offset = 0;
// @@@BUG@@@ workaround for bug 5003 // @@@BUG@@@ workaround for bug 5003
while (_dummyTest(r, lastindex)) while (_dummyTest(r, lastindex))
{ {
@ -3319,10 +3320,10 @@ unittest
]; ];
int i; int i;
int a; sizediff_t a;
uint c; uint c;
int start; sizediff_t start;
int end; sizediff_t end;
TestVectors tvd; TestVectors tvd;
foreach (Char; TypeTuple!(char, wchar, dchar)) foreach (Char; TypeTuple!(char, wchar, dchar))

View file

@ -402,7 +402,7 @@ sizediff_t rfind(string s, RegExp pattern)
unittest unittest
{ {
int i; sizediff_t i;
debug(regexp) printf("regexp.rfind.unittest\n"); debug(regexp) printf("regexp.rfind.unittest\n");
i = rfind("abcdefcdef", RegExp("c")); i = rfind("abcdefcdef", RegExp("c"));
@ -451,7 +451,7 @@ rfind(string s, string pattern, string attributes = null)
unittest unittest
{ {
int i; sizediff_t i;
debug(regexp) printf("regexp.rfind.unittest\n"); debug(regexp) printf("regexp.rfind.unittest\n");
i = rfind("abcdefcdef", "c"); i = rfind("abcdefcdef", "c");

View file

@ -89,6 +89,13 @@ $(TR $(TD > 0) $(TD $(D s1 > s2)))
int cmp(C1, C2)(in C1[] s1, in C2[] s2) int cmp(C1, C2)(in C1[] s1, in C2[] s2)
{ {
static int toZeroOne(sizediff_t num)
{
if(num > 0) return 1;
if(num < 0) return -1;
return 0;
}
static if (C1.sizeof == C2.sizeof) static if (C1.sizeof == C2.sizeof)
{ {
immutable len = min(s1.length, s2.length); immutable len = min(s1.length, s2.length);
@ -109,8 +116,8 @@ int cmp(C1, C2)(in C1[] s1, in C2[] s2)
size_t i1, i2; size_t i1, i2;
for (;;) for (;;)
{ {
if (i1 == s1.length) return i2 - s2.length; if (i1 == s1.length) return toZeroOne(i2 - s2.length);
if (i2 == s2.length) return s1.length - i1; if (i2 == s2.length) return toZeroOne(s1.length - i1);
immutable c1 = std.utf.decode(s1, i1), immutable c1 = std.utf.decode(s1, i1),
c2 = std.utf.decode(s2, i2); c2 = std.utf.decode(s2, i2);
if (c1 != c2) return cast(int) c1 - cast(int) c2; if (c1 != c2) return cast(int) c1 - cast(int) c2;
@ -169,7 +176,7 @@ icmp(C1, C2)(in C1[] s1, in C2[] s2)
unittest unittest
{ {
int result; sizediff_t result;
debug(string) printf("string.icmp.unittest\n"); debug(string) printf("string.icmp.unittest\n");
result = icmp("abc", "abc"); result = icmp("abc", "abc");
@ -371,7 +378,7 @@ unittest
{ {
debug(string) printf("string.find.unittest\n"); debug(string) printf("string.find.unittest\n");
int i; sizediff_t i;
foreach (S; TypeTuple!(string, wstring, dstring)) foreach (S; TypeTuple!(string, wstring, dstring))
{ {
@ -399,7 +406,7 @@ unittest
{ {
debug(string) printf("string.indexOf.unittest\n"); debug(string) printf("string.indexOf.unittest\n");
int i; sizediff_t i;
foreach (S; TypeTuple!(string, wstring, dstring)) foreach (S; TypeTuple!(string, wstring, dstring))
{ {
@ -497,7 +504,7 @@ unittest
{ {
debug(string) printf("string.rfind.unittest\n"); debug(string) printf("string.rfind.unittest\n");
int i; sizediff_t i;
i = lastIndexOf(null, cast(dchar)'a'); i = lastIndexOf(null, cast(dchar)'a');
assert(i == -1); assert(i == -1);
@ -513,7 +520,7 @@ unittest
{ {
debug(string) printf("string.irfind.unittest\n"); debug(string) printf("string.irfind.unittest\n");
int i; sizediff_t i;
i = lastIndexOf(null, cast(dchar)'a', CaseSensitive.no); i = lastIndexOf(null, cast(dchar)'a', CaseSensitive.no);
assert(i == -1); assert(i == -1);
@ -597,7 +604,7 @@ unittest
{ {
debug(string) printf("string.find.unittest\n"); debug(string) printf("string.find.unittest\n");
int i; sizediff_t i;
foreach (S; TypeTuple!(string, wstring, dstring)) foreach (S; TypeTuple!(string, wstring, dstring))
{ {
@ -621,7 +628,7 @@ unittest
{ {
debug(string) printf("string.ifind.unittest\n"); debug(string) printf("string.ifind.unittest\n");
int i; sizediff_t i;
foreach (S; TypeTuple!(string, wstring, dstring)) foreach (S; TypeTuple!(string, wstring, dstring))
{ {
@ -726,7 +733,7 @@ ptrdiff_t lastIndexOf(in char[] s, in char[] sub,
unittest unittest
{ {
int i; sizediff_t i;
debug(string) printf("string.lastIndexOf.unittest\n"); debug(string) printf("string.lastIndexOf.unittest\n");
i = lastIndexOf("abcdefcdef", "c"); i = lastIndexOf("abcdefcdef", "c");
@ -748,7 +755,7 @@ unittest
unittest unittest
{ {
int i; sizediff_t i;
debug(string) printf("string.lastIndexOf.unittest\n"); debug(string) printf("string.lastIndexOf.unittest\n");
i = lastIndexOf("abcdefCdef", "c", CaseSensitive.no); i = lastIndexOf("abcdefCdef", "c", CaseSensitive.no);
@ -2088,7 +2095,7 @@ unittest
string s = "This is a fofofof list"; string s = "This is a fofofof list";
string sub = "fof"; string sub = "fof";
int i; size_t i;
i = count(s, sub); i = count(s, sub);
assert(i == 2); assert(i == 2);

View file

@ -184,7 +184,7 @@ private:
apply } apply }
// state // state
int function(OpID selector, ubyte[size]* store, void* data) fptr sizediff_t function(OpID selector, ubyte[size]* store, void* data) fptr
= &handler!(void); = &handler!(void);
union union
{ {
@ -196,7 +196,7 @@ private:
// internals // internals
// Handler for an uninitialized value // Handler for an uninitialized value
static int handler(A : void)(OpID selector, ubyte[size]*, void* parm) static sizediff_t handler(A : void)(OpID selector, ubyte[size]*, void* parm)
{ {
switch (selector) switch (selector)
{ {
@ -231,7 +231,7 @@ private:
} }
// Handler for all of a type's operations // Handler for all of a type's operations
static int handler(A)(OpID selector, ubyte[size]* pStore, void* parm) static sizediff_t handler(A)(OpID selector, ubyte[size]* pStore, void* parm)
{ {
static A* getPtr(void* untyped) static A* getPtr(void* untyped)
{ {
@ -751,11 +751,13 @@ public:
else else
auto temp = Variant(rhs); auto temp = Variant(rhs);
auto result = fptr(OpID.compare, &store, &temp); auto result = fptr(OpID.compare, &store, &temp);
if (result == int.min) if (result == sizediff_t.min)
{ {
throw new VariantException(type, temp.type); throw new VariantException(type, temp.type);
} }
return result;
assert(result >= -1 && result <= 1); // Should be true for opCmp.
return cast(int) result;
} }
/** /**