diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d7490b68a6f7..23b3a0ccebf8 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1092,13 +1092,12 @@ static bool unsupportedTypeConversion(const Sema &S, QualType LHSType, Float128AndLongDouble |= (LHSElemType == S.Context.LongDoubleTy && RHSElemType == S.Context.Float128Ty); - /* We've handled the situation where __float128 and long double have the same - representation. The only other allowable conversion is if long double is - really just double. - */ + // We've handled the situation where __float128 and long double have the same + // representation. We allow all conversions for all possible long double types + // except PPC's double double. return Float128AndLongDouble && - (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) != - &llvm::APFloat::IEEEdouble()); + (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == + &llvm::APFloat::PPCDoubleDouble()); } typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e7eb309c40b4..b80f14d24225 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1764,8 +1764,8 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, (FromType == S.Context.LongDoubleTy && ToType == S.Context.Float128Ty)); if (Float128AndLongDouble && - (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) != - &llvm::APFloat::IEEEdouble())) + (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) == + &llvm::APFloat::PPCDoubleDouble())) return false; } // Floating point conversions (C++ 4.8). diff --git a/clang/test/Sema/float128-ld-incompatibility.cpp b/clang/test/Sema/float128-ld-incompatibility.cpp index d993ed7b081c..13f5b6d5d10e 100644 --- a/clang/test/Sema/float128-ld-incompatibility.cpp +++ b/clang/test/Sema/float128-ld-incompatibility.cpp @@ -1,10 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 \ // RUN: -triple powerpc64le-unknown-linux-gnu -target-cpu pwr8 \ // RUN: -target-feature +float128 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -Wno-parentheses %s __float128 qf(); long double ldf(); +#ifdef __PPC__ // FIXME: once operations between long double and __float128 are implemented for // targets where the types are different, these next two will change long double ld{qf()}; // expected-error {{cannot initialize a variable of type 'long double' with an rvalue of type '__float128'}} @@ -17,6 +19,7 @@ auto test1(__float128 q, long double ld) -> decltype(q + ld) { // expected-error auto test2(long double a, __float128 b) -> decltype(a + b) { // expected-error {{invalid operands to binary expression ('long double' and '__float128')}} return a + b; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}} } +#endif void test3(bool b) { long double ld;