diff --git a/compiler/src/dmd/dcast.d b/compiler/src/dmd/dcast.d index 8ab49b3c470f..55aa781f758a 100644 --- a/compiler/src/dmd/dcast.d +++ b/compiler/src/dmd/dcast.d @@ -1603,7 +1603,6 @@ MATCH implicitConvTo(Type from, Type to) // Disallow implicit conversion from complex to non-complex if (from.flags & TFlags.complex && !(tob.flags & TFlags.complex)) return MATCH.nomatch; - // Disallow implicit conversion of real or imaginary to complex if (from.flags & (TFlags.real_ | TFlags.imaginary) && tob.flags & TFlags.complex) return MATCH.nomatch; @@ -1611,6 +1610,12 @@ MATCH implicitConvTo(Type from, Type to) // Disallow implicit conversion to-from real and imaginary if ((from.flags & (TFlags.real_ | TFlags.imaginary)) != (tob.flags & (TFlags.real_ | TFlags.imaginary))) return MATCH.nomatch; + // Allow complex float to complex double promotion + if ((from.flags & TFlags.complex) && (tob.flags & TFlags.complex)) + { + if (from.size(Loc.initial) < tob.size(Loc.initial)) + return MATCH.convert; + } } return MATCH.convert; diff --git a/compiler/test/compilable/importc_complex_promotion.c b/compiler/test/compilable/importc_complex_promotion.c new file mode 100644 index 000000000000..3271aa23a519 --- /dev/null +++ b/compiler/test/compilable/importc_complex_promotion.c @@ -0,0 +1,25 @@ +// Ensure complex float can be implicitly promoted to complex double +// Fixes issue #22259 +#include + +void testComplexPromotion() +{ + _Complex float yf = 1.0if; + _Complex double x = yf; // promotion: _Complex float -> _Complex double +} + +void testComplexPreservation() +{ + // These should still work (no change) + _Complex float f1 = 1.0f + 1.0if; + _Complex float f2 = 1.0if + 2.0if; + _Complex double d1 = 1.0 + 2.0i; + _Complex double d2 = 2.0 + 3.0i; +} + +int main() +{ + testComplexPromotion(); + testComplexPreservation(); + return 0; +}