ziangwan updated this revision to Diff 209611.
ziangwan added a comment.

Fix spelling / comment / naming issues.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64666/new/

https://reviews.llvm.org/D64666

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Driver/ToolChains/Arch/AArch64.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/conversion.c
  clang/test/Sema/ext_vector_casts.c
  clang/test/Sema/implicit-float-conversion.c

Index: clang/test/Sema/implicit-float-conversion.c
===================================================================
--- /dev/null
+++ clang/test/Sema/implicit-float-conversion.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -verify -Wno-conversion -Wimplicit-float-conversion
+
+
+long testReturn(long a, float b) {
+  return a + b; // expected-warning {{implicit conversion from 'long' to 'float' may loses integer precision}}
+}
+
+
+void testAssignment() {
+  float f = 222222;
+  double b = 222222222222L;
+  
+  float ff = 222222222222L; // expected-warning {{implicit conversion from 'long' to 'float' changes value}}
+  
+  long l = 222222222222L;
+  float fff = l; // expected-warning {{implicit conversion from 'long' to 'float' may loses integer precision}}
+}
+
+
+void testExpression() {
+  float a = 0.0f;
+  float b = 222222222222L + a; // expected-warning {{implicit conversion from 'long' to 'float' changes value}}
+  float c = 22222222 + 22222223; // expected-warning {{implicit conversion from 'int' to 'float' changes value}}
+
+  int i = 0;
+  float d = i + a; // expected-warning {{implicit conversion from 'int' to 'float' may loses integer precision}}
+  
+  double e = 0.0;
+  double f = i + e;
+}
Index: clang/test/Sema/ext_vector_casts.c
===================================================================
--- clang/test/Sema/ext_vector_casts.c
+++ clang/test/Sema/ext_vector_casts.c
@@ -115,12 +115,12 @@
   vl = vl + t; // expected-warning {{implicit conversion loses integer precision}}
   
   vf = 1 + vf;
-  vf = l + vf;
+  vf = l + vf; // expected-warning {{implicit conversion from 'long' to 'float2' (vector of 2 'float' values) may loses integer precision}}
   vf = 2.0 + vf;
   vf = d + vf; // expected-warning {{implicit conversion loses floating-point precision}}
-  vf = vf + 0xffffffff;
+  vf = vf + 0xffffffff; // expected-warning {{implicit conversion from 'unsigned int' to 'float2' (vector of 2 'float' values) changes value}}
   vf = vf + 2.1; // expected-warning {{implicit conversion loses floating-point precision}}
   
-  vd = l + vd;
-  vd = vd + t;
+  vd = l + vd; // expected-warning {{implicit conversion from 'long' to 'double2' (vector of 2 'double' values) may loses integer precision}}
+  vd = vd + t; // expected-warning {{implicit conversion from '__uint128_t' (aka 'unsigned __int128') to 'double2' (vector of 2 'double' values) may loses integer precision}}
 }
Index: clang/test/Sema/conversion.c
===================================================================
--- clang/test/Sema/conversion.c
+++ clang/test/Sema/conversion.c
@@ -233,7 +233,7 @@
   takes_int(v);
   takes_long(v);
   takes_longlong(v);
-  takes_float(v);
+  takes_float(v); // expected-warning {{implicit conversion from 'int' to 'float' may loses integer precision}}
   takes_double(v);
   takes_longdouble(v);
 }
@@ -244,8 +244,8 @@
   takes_int(v); // expected-warning {{implicit conversion loses integer precision}}
   takes_long(v);
   takes_longlong(v);
-  takes_float(v);
-  takes_double(v);
+  takes_float(v); // expected-warning {{implicit conversion from 'long' to 'float' may loses integer precision}}
+  takes_double(v); // expected-warning {{implicit conversion from 'long' to 'double' may loses integer precision}}
   takes_longdouble(v);
 }
 
@@ -255,8 +255,8 @@
   takes_int(v); // expected-warning {{implicit conversion loses integer precision}}
   takes_long(v);
   takes_longlong(v);
-  takes_float(v);
-  takes_double(v);
+  takes_float(v); // expected-warning {{implicit conversion from 'long long' to 'float' may loses integer precision}}
+  takes_double(v); // expected-warning {{implicit conversion from 'long long' to 'double' may loses integer precision}}
   takes_longdouble(v);
 }
 
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -11400,6 +11400,49 @@
     }
   }
 
+  // If we are casting an integer type to a floating point type, we might
+  // lose accuracy if the floating point type has a narrower significand
+  // than the floating point type. Issue warnings for that accuracy loss. 
+  if (SourceBT && TargetBT &&
+      SourceBT->isIntegerType() && TargetBT->isFloatingType()) {
+    // Determine the number of precision bits in the source integer type.
+    IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated());
+    unsigned int SourcePrecision = SourceRange.Width;
+
+    // Determine the number of precision bits in the target floating point type
+    // Also create a APFloat object to represent the converted value.
+    unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
+      S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)));
+    llvm::APFloat TargetFloatValue(
+      S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)));
+
+    if (SourcePrecision > 0 && TargetPrecision > 0 &&
+        SourcePrecision > TargetPrecision) {
+      // If the source integer is a constant, then the implicit conversion
+      // definitely lose precision. Otherwise, the implicit conversion
+      // *may* lose precision.
+      llvm::APSInt SourceInt;
+      if (E->isIntegerConstantExpr(SourceInt, S.Context)) {
+        std::string PrettySourceValue = SourceInt.toString(10);
+        TargetFloatValue.convertFromAPInt(SourceInt,
+          SourceBT->isSignedInteger(), llvm::APFloat::rmTowardZero);
+        SmallString<32> PrettyTargetValue;
+        TargetFloatValue.toString(PrettyTargetValue,
+          TargetPrecision);
+        
+        S.DiagRuntimeBehavior(
+          E->getExprLoc(), E,
+          S.PDiag(diag::warn_impcast_integer_float_precision_constant)
+            << PrettySourceValue << PrettyTargetValue
+            << E->getType() << T
+            << E->getSourceRange() << clang::SourceRange(CC));
+      } else {
+        DiagnoseImpCast(S, E, T, CC,
+          diag::warn_impcast_integer_float_precision);
+      }
+    }
+  }
+
   DiagnoseNullConversion(S, E, T, CC);
 
   S.DiscardMisalignedMemberAddress(Target, E);
Index: clang/lib/Driver/ToolChains/Arch/AArch64.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -88,7 +88,7 @@
     unsigned Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
     if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
       return false;
-   }
+  }
 
   if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
     return false;
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3241,6 +3241,13 @@
   "the only well defined values for BOOL are YES and NO">,
   InGroup<ObjCBoolConstantConversion>;
 
+def warn_impcast_integer_float_precision : Warning<
+  "implicit conversion from %0 to %1 may loses integer precision">,
+  InGroup<ImplicitFloatConversion>, DefaultIgnore;
+def warn_impcast_integer_float_precision_constant : Warning<
+  "implicit conversion from %2 to %3 changes value from %0 to %1">,
+  InGroup<ImplicitFloatConversion>, DefaultIgnore;
+
 def warn_impcast_fixed_point_range : Warning<
   "implicit conversion from %0 cannot fit within the range of values for %1">,
   InGroup<ImplicitFixedPointConversion>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to