Author: epilk Date: Fri Feb 15 17:11:47 2019 New Revision: 354190 URL: http://llvm.org/viewvc/llvm-project?rev=354190&view=rev Log: [Sema] Diagnose floating point conversions based on target semantics
...instead of just comparing rank. Also, fix a bad warning about _Float16, since its declared out of order in BuiltinTypes.def, meaning comparing rank using BuiltinType::getKind() is incorrect. Differential revision: https://reviews.llvm.org/D58254 Added: cfe/trunk/test/Sema/conversion-target-dep.c Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/Sema/SemaChecking.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=354190&r1=354189&r2=354190&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Fri Feb 15 17:11:47 2019 @@ -2501,6 +2501,11 @@ public: /// \p LHS < \p RHS, return -1. int getFloatingTypeOrder(QualType LHS, QualType RHS) const; + /// Compare the rank of two floating point types as above, but compare equal + /// if both types have the same floating-point semantics on the target (i.e. + /// long double and double on AArch64 will return 0). + int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const; + /// Return a real floating point or a complex type (based on /// \p typeDomain/\p typeSize). /// Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=354190&r1=354189&r2=354190&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Fri Feb 15 17:11:47 2019 @@ -5608,6 +5608,12 @@ int ASTContext::getFloatingTypeOrder(Qua return -1; } +int ASTContext::getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const { + if (&getFloatTypeSemantics(LHS) == &getFloatTypeSemantics(RHS)) + return 0; + return getFloatingTypeOrder(LHS, RHS); +} + /// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This /// routine will assert if passed a built-in type that isn't an integer or enum, /// or if it is not canonicalized. Modified: cfe/trunk/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=354190&r1=354189&r2=354190&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaChecking.cpp (original) +++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Feb 15 17:11:47 2019 @@ -10626,14 +10626,16 @@ static void AnalyzeCompoundAssignment(Se // If source is floating point but target is an integer. if (ResultBT->isInteger()) - DiagnoseImpCast(S, E, E->getRHS()->getType(), E->getLHS()->getType(), - E->getExprLoc(), diag::warn_impcast_float_integer); - // If both source and target are floating points. Builtin FP kinds are ordered - // by increasing FP rank. FIXME: except _Float16, we currently emit a bogus - // warning. - else if (ResultBT->isFloatingPoint() && ResultBT->getKind() < RBT->getKind() && - // We don't want to warn for system macro. - !S.SourceMgr.isInSystemMacro(E->getOperatorLoc())) + return DiagnoseImpCast(S, E, E->getRHS()->getType(), E->getLHS()->getType(), + E->getExprLoc(), diag::warn_impcast_float_integer); + + if (!ResultBT->isFloatingPoint()) + return; + + // If both source and target are floating points, warn about losing precision. + int Order = S.getASTContext().getFloatingTypeSemanticOrder( + QualType(ResultBT, 0), QualType(RBT, 0)); + if (Order < 0 && !S.SourceMgr.isInSystemMacro(E->getOperatorLoc())) // warn about dropping FP rank. DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), E->getOperatorLoc(), diag::warn_impcast_float_result_precision); @@ -10952,8 +10954,9 @@ CheckImplicitConversion(Sema &S, Expr *E if (TargetBT && TargetBT->isFloatingPoint()) { // ...then warn if we're dropping FP rank. - // Builtin FP kinds are ordered by increasing FP rank. - if (SourceBT->getKind() > TargetBT->getKind()) { + int Order = S.getASTContext().getFloatingTypeSemanticOrder( + QualType(SourceBT, 0), QualType(TargetBT, 0)); + if (Order > 0) { // Don't warn about float constants that are precisely // representable in the target type. Expr::EvalResult result; @@ -10971,7 +10974,7 @@ CheckImplicitConversion(Sema &S, Expr *E DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_precision); } // ... or possibly if we're increasing rank, too - else if (TargetBT->getKind() > SourceBT->getKind()) { + else if (Order < 0) { if (S.SourceMgr.isInSystemMacro(CC)) return; Added: cfe/trunk/test/Sema/conversion-target-dep.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/conversion-target-dep.c?rev=354190&view=auto ============================================================================== --- cfe/trunk/test/Sema/conversion-target-dep.c (added) +++ cfe/trunk/test/Sema/conversion-target-dep.c Fri Feb 15 17:11:47 2019 @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -Wdouble-promotion -Wimplicit-float-conversion %s -triple x86_64-apple-macosx10.12 -verify=x86,expected +// RUN: %clang_cc1 -Wdouble-promotion -Wimplicit-float-conversion %s -triple armv7-apple-ios9.0 -verify=arm,expected + +// On ARM, long double and double both map to double precision 754s, so there +// isn't any reason to warn on conversions back and forth. + +long double ld; +double d; +_Float16 f16; // x86-error {{_Float16 is not supported on this target}} + +int main() { + ld = d; // x86-warning {{implicit conversion increases floating-point precision: 'double' to 'long double'}} + d = ld; // x86-warning {{implicit conversion loses floating-point precision: 'long double' to 'double'}} + + ld += d; // x86-warning {{implicit conversion increases floating-point precision: 'double' to 'long double'}} + d += ld; // x86-warning {{implicit conversion when assigning computation result loses floating-point precision: 'long double' to 'double'}} + + f16 = ld; // expected-warning {{implicit conversion loses floating-point precision: 'long double' to '_Float16'}} + ld = f16; // expected-warning {{implicit conversion increases floating-point precision: '_Float16' to 'long double'}} + + f16 += ld; // expected-warning {{implicit conversion when assigning computation result loses floating-point precision: 'long double' to '_Float16'}} + ld += f16; // expected-warning {{implicit conversion increases floating-point precision: '_Float16' to 'long double'}} +} + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits