diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1088,7 +1088,7 @@ if (IntTy->isComplexType() || IntTy->isRealFloatingType()) return true; if (SkipCast) return false; if (IntTy->isIntegerType()) { - QualType fpTy = cast(ComplexTy)->getElementType(); + QualType fpTy = ComplexTy->castAs()->getElementType(); IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating); IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy, CK_FloatingRealToComplex); @@ -1108,10 +1108,10 @@ bool IsCompAssign) { // if we have an integer operand, the result is the complex type. if (!handleIntegerToComplexFloatConversion(S, RHS, LHS, RHSType, LHSType, - /*skipCast*/false)) + /*SkipCast=*/false)) return LHSType; if (!handleIntegerToComplexFloatConversion(S, LHS, RHS, LHSType, RHSType, - /*skipCast*/IsCompAssign)) + /*SkipCast=*/IsCompAssign)) return RHSType; // This handles complex/complex, complex/float, or float/complex. @@ -1125,20 +1125,17 @@ // when combining a "long double" with a "double _Complex", the // "double _Complex" is promoted to "long double _Complex". + auto *LHSComplexType = LHSType->getAs(); + auto *RHSComplexType = RHSType->getAs(); + // Compute the rank of the two types, regardless of whether they are complex. int Order = S.Context.getFloatingTypeOrder(LHSType, RHSType); - - auto *LHSComplexType = dyn_cast(LHSType); - auto *RHSComplexType = dyn_cast(RHSType); - QualType LHSElementType = - LHSComplexType ? LHSComplexType->getElementType() : LHSType; - QualType RHSElementType = - RHSComplexType ? RHSComplexType->getElementType() : RHSType; - - QualType ResultType = S.Context.getComplexType(LHSElementType); if (Order < 0) { + QualType RHSElementType = + RHSComplexType ? RHSComplexType->getElementType() : RHSType; + QualType ResultType = + RHSComplexType ? RHSType : S.Context.getComplexType(RHSElementType); // Promote the precision of the LHS if not an assignment. - ResultType = S.Context.getComplexType(RHSElementType); if (!IsCompAssign) { if (LHSComplexType) LHS = @@ -1146,7 +1143,13 @@ else LHS = S.ImpCastExprToType(LHS.get(), RHSElementType, CK_FloatingCast); } - } else if (Order > 0) { + return ResultType; + } + QualType LHSElementType = + LHSComplexType ? LHSComplexType->getElementType() : LHSType; + QualType ResultType = + LHSComplexType ? LHSType : S.Context.getComplexType(LHSElementType); + if (Order > 0) { // Promote the precision of the RHS. if (RHSComplexType) RHS = S.ImpCastExprToType(RHS.get(), ResultType, CK_FloatingComplexCast); diff --git a/clang/test/Sema/complex-int.c b/clang/test/Sema/complex-int.c --- a/clang/test/Sema/complex-int.c +++ b/clang/test/Sema/complex-int.c @@ -11,6 +11,9 @@ int bb = 0; bb += 1i; +typedef __complex__ float ComplexFloat; +int cc = 1 + (ComplexFloat)(1.0iF); + result = arr*ii; result = ii*brr; diff --git a/clang/test/SemaCXX/complex-conversion.cpp b/clang/test/SemaCXX/complex-conversion.cpp --- a/clang/test/SemaCXX/complex-conversion.cpp +++ b/clang/test/SemaCXX/complex-conversion.cpp @@ -15,4 +15,8 @@ // Conversion to bool doesn't actually discard the imaginary part. take(Complex); + + using B = _Complex double; + B c; + c *= double(); }