[Issue 3139] compiler dies "Error: out of memory" with case range
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Wed May 12 12:38:59 PDT 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3139
Don <clugdbug at yahoo.com.au> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |patch, wrong-code
--- Comment #1 from Don <clugdbug at yahoo.com.au> 2010-05-12 12:38:56 PDT ---
It goes into an infinite loop because the loop termination condition in
CaseRangeStatement::semantic() uses <=.
This fails whenever the last case is -1 or ulong.max.
x <= -1u is true for all uint x. Worse, if the range goes from negative to
positive, wrong code is generated.
In my patch, I've also added an error message to detect wrongly-ordered ranges.
eg, case 3:..case 2:
currently produces "more than 256 cases in case range" which is
a bit silly. This also fixes a related accepts-invalid test case.
--
TEST CASES FOR TEST SUITE
--
void hang3139(int x)
{
switch(x) {
case -9: .. case -1:
default:
}
}
int wrongcode3139(int x)
{
switch(x) {
case -9: .. case 2: return 3;
default:
return 4;
}
}
static assert(wrongcode3139(-5)==3);
// bug 3139, accepts-invalid in DMD2.045.
static assert(!is(typeof(
(long x) { switch(x) { case long.max: .. case -long.max:
default:} return 4; }(3)
)));
---
PATCH
Index: statement.c
===================================================================
--- statement.c (revision 484)
+++ statement.c (working copy)
@@ -3033,6 +3033,14 @@
last = last->optimize(WANTvalue | WANTinterpret);
dinteger_t lval = last->toInteger();
+ if ( (first->type->isunsigned() && fval > lval) ||
+ (!first->type->isunsigned() && (sinteger_t)fval > (sinteger_t)lval))
+ {
+ error ("first case %s must be less than last case %s",
+ first->toChars(), last->toChars());
+ lval = fval;
+ }
+
if (lval - fval > 256)
{ error("more than 256 cases in case range");
lval = fval + 256;
@@ -3049,7 +3057,7 @@
*/
Statements *statements = new Statements();
- for (dinteger_t i = fval; i <= lval; i++)
+ for (dinteger_t i = fval; i != lval + 1; i++)
{
Statement *s = statement;
if (i != lval)
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list