[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