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

Reply via email to