@@ -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+ */
150173real_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