Bug 3173 – ICE(mtype.c) on wrong code (double to long to int conversion)
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
All
Creation time
2009-07-13T13:04:00Z
Last change time
2015-06-09T01:28:08Z
Keywords
ice-on-invalid-code, patch
Assigned to
nobody
Creator
ace17
Comments
Comment #0 by ace17 — 2009-07-13T13:04:39Z
void f1()
{
double d;
int c = cast(long)(d);
}
produces :
dmd: mtype.c:1554: uinteger_t Type::sizemask(): Assertion `0' failed.
Comment #1 by clugdbug — 2009-08-31T08:16:52Z
This is a regression. It worked in 2.022.
Comment #2 by clugdbug — 2009-08-31T23:56:38Z
Cause: default case for getIntRange() assumes it's an integer, which isn't true
if there's casting.
Solution: if not an integer, assume it could contain anything.
PATCH: cast.c, line 1902 (in Walter's private beta of DMD2.032):
IntRange Expression::getIntRange()
{
IntRange ir;
ir.imin = 0;
if (type->isintegral())
ir.imax = type->sizemask();
else
ir.imax = 0xFFFFFFFFFFFFFFFFULL; // assume the worst
return ir;
}
===========
TEST CASES FOR TEST SUITE
===========
struct S3173{
double z;
}
int bug3173(int x) { return x; }
S3173 s3173;
double e3173 = 4;
const double d3173 = 4;
// invalid, but should not ICE
static assert(!is(typeof(bug3173(cast(long)e3173))));
static assert(!is(typeof(bug3173(cast(long)s3173))));
static assert(!is(typeof(bug3173(cast(long)3.256679e30))));
// And two valid cases:
static assert(is(typeof(bug3173(cast(long)d3173))));
static assert(is(typeof(bug3173(cast(long)3.256679e4))));
Comment #3 by clugdbug — 2009-09-01T04:25:11Z
Patch was incomplete, fails for the test case below. Need to also add this code to the end of CastExp::getIntRange()
+ if (type->isintegral()) {
ir.imin &= type->sizemask();
ir.imax &= type->sizemask();
+ }
return ir;
}
====
Test case:
ubyte b = 6;
short c5 = cast(int)(b + 6.1);
====
This is arguably an ice-on-valid-code.