Skip to content

Commit 9b8ebda

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

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
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: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,38 @@ 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+
result = cast(float)result;
150+
else if (sz == 8)
151+
result = cast(double)result;
152+
rexp.value = result; // in case of further casting
153+
}
154+
else
155+
result = CTFloat.zero;
156+
return result;
157+
}
143158
else if (auto ce = _this.isComplexExp())
144159
return cimagl(ce.value);
145160

146161
error(_this.loc, "floating point constant expression expected instead of `%s`", _this.toChars());
147162
return CTFloat.zero;
148163
}
149164

165+
/***********************************
166+
* Interpret the value from IntegerExp, RealExp, or ComplexExp
167+
* as a correctly typed floating point number.
168+
* Params:
169+
* _this = Expression
170+
* Returns:
171+
* floating point value, zero on error
172+
*/
150173
real_t toReal(Expression _this)
151174
{
152175
if (auto iexp = _this.isIntegerExp())
@@ -161,7 +184,23 @@ real_t toReal(Expression _this)
161184
}
162185
else if (auto rexp = _this.isRealExp())
163186
{
164-
return rexp.type.isReal() ? rexp.value : CTFloat.zero;
187+
/* Conversions are handled here instead of in RealExp's constructor
188+
* because the type sent to the constructor is not semantically known yet
189+
*/
190+
real_t result = rexp.value;
191+
192+
if (rexp.type.isReal())
193+
{
194+
const sz = size(rexp.type);
195+
if (sz == 4)
196+
result = cast(float)result;
197+
else if (sz == 8)
198+
result = cast(double)result;
199+
rexp.value = result; // in case of further casting
200+
}
201+
else
202+
result = CTFloat.zero;
203+
return result;
165204
}
166205
else if (auto cexp = _this.isComplexExp())
167206
{

0 commit comments

Comments
 (0)