Skip to content

Commit 55908be

Browse files
committed
fix #20339 Constant folding differs between Windows and linux builds
1 parent c0f9613 commit 55908be

File tree

5 files changed

+64
-7
lines changed

5 files changed

+64
-7
lines changed

compiler/src/dmd/constfold.d

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import dmd.expressionsem;
2929
import dmd.globals;
3030
import dmd.location;
3131
import dmd.mtype;
32+
import dmd.printast;
3233
import dmd.root.complex;
3334
import dmd.root.ctfloat;
3435
import dmd.root.port;
@@ -223,6 +224,9 @@ UnionExp Min(Loc loc, Type type, Expression e1, Expression e2)
223224

224225
UnionExp Mul(Loc loc, Type type, Expression e1, Expression e2)
225226
{
227+
//printf("Mul() type: %s\n", type.toChars());
228+
//printAST(e1);
229+
//printAST(e2);
226230
UnionExp ue = void;
227231
if (type.isFloating())
228232
{

compiler/src/dmd/expressionsem.d

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,44 @@ real_t toImaginary(Expression _this)
138138
{
139139
if (auto ie = _this.isIntegerExp())
140140
return CTFloat.zero;
141-
else if (auto re = _this.isRealExp)
142-
return re.type.isReal() ? CTFloat.zero : re.value;
141+
else if (auto rexp = _this.isRealExp)
142+
{
143+
real_t result = rexp.value;
144+
145+
if (!rexp.type.isReal()) // the ! is the only difference from toReal()
146+
{
147+
const sz = size(rexp.type);
148+
if (sz == 4)
149+
{
150+
float f = cast(float)result; // force round to float with x87 instructions
151+
result = f;
152+
}
153+
else if (sz == 8)
154+
{
155+
double d = cast(double)result;
156+
result = d;
157+
}
158+
rexp.value = result; // in case of further casting
159+
}
160+
else
161+
result = CTFloat.zero;
162+
return result;
163+
}
143164
else if (auto ce = _this.isComplexExp())
144165
return cimagl(ce.value);
145166

146167
error(_this.loc, "floating point constant expression expected instead of `%s`", _this.toChars());
147168
return CTFloat.zero;
148169
}
149170

171+
/***********************************
172+
* Interpret the value from IntegerExp, RealExp, or ComplexExp
173+
* as a correctly typed floating point number.
174+
* Params:
175+
* _this = Expression
176+
* Returns:
177+
* floating point value, zero on error
178+
*/
150179
real_t toReal(Expression _this)
151180
{
152181
if (auto iexp = _this.isIntegerExp())
@@ -161,7 +190,29 @@ real_t toReal(Expression _this)
161190
}
162191
else if (auto rexp = _this.isRealExp())
163192
{
164-
return rexp.type.isReal() ? rexp.value : CTFloat.zero;
193+
/* Conversions are handled here instead of in RealExp's constructor
194+
* because the type sent to the constructor is not semantically known yet
195+
*/
196+
real_t result = rexp.value;
197+
198+
if (rexp.type.isReal())
199+
{
200+
const sz = size(rexp.type);
201+
if (sz == 4)
202+
{
203+
float f = cast(float)result; // force round to float with x87 instructions
204+
result = f;
205+
}
206+
else if (sz == 8)
207+
{
208+
double d = cast(double)result;
209+
result = d;
210+
}
211+
rexp.value = result; // in case of further casting
212+
}
213+
else
214+
result = CTFloat.zero;
215+
return result;
165216
}
166217
else if (auto cexp = _this.isComplexExp())
167218
{

compiler/test/compilable/interpret3.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4494,11 +4494,11 @@ auto classtest1(int n)
44944494
d = new TheBase;
44954495
SomeInterface fc = c;
44964496
SomeOtherInterface ot = c;
4497-
assert(fc.bar('x') == 2.6);
4497+
assert(fc.bar('x') == 2.6f);
44984498
assert(ot.xxx() == 762);
44994499
fc = d;
45004500
ot = d;
4501-
assert(fc.bar('x') == 3.6);
4501+
assert(fc.bar('x') == 3.6f);
45024502
assert(ot.xxx() == 762);
45034503

45044504
Unrelated u2 = new Unrelated(7);

compiler/test/runnable/ctorpowtests.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ enum B = StructWithCtor(7, 2.3);
159159
static assert(A.n == 1);
160160
static assert(A.x == 5.0);
161161
static assert(B.n == 7);
162-
static assert(B.x == 2.3);
162+
static assert(B.x == 2.3f);
163163

164164
int bazra(int x)
165165
{

compiler/test/runnable/test34.d

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,9 @@ ulong foo32()
576576

577577
void test32()
578578
{
579-
assert(foo32()==1176576510);
579+
assert(/*foo32()==1176576510 ||*/ // previous version held floats internally at higher precision
580+
foo32()==1176576512); // newer version has float precision
581+
// https://github.com/dlang/dmd/pull/22270
580582
}
581583

582584
/************************************************/

0 commit comments

Comments
 (0)