<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Apr 22, 2016 at 10:50 AM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span>On Thu, Apr 21, 2016 at 2:04 PM, Richard Trieu via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rtrieu<br>
Date: Thu Apr 21 16:04:55 2016<br>
New Revision: 267054<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=267054&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=267054&view=rev</a><br>
Log:<br>
Split interesting warnings off from -Wfloat-conversion<br>
<br>
Restructure the implict floating point to integer conversions so that<br>
interesting sub-groups are under different flags.  Breakdown of warnings:<br>
<br>
No warning:<br>
Exact conversions from floating point to integer:<br>
int x = 10.0;<br>
int x = 1e10;<br>
<br>
-Wliteral-conversion - Floating point literal to integer with rounding:<br>
int x = 5.5;<br>
int x = -3.4;<br>
<br>
-Wfloat-conversion - All conversions not covered by the above two:<br>
int x = GetFloat();<br>
int x = 5.5 + 3.5;<br>
<br>
-Wfloat-zero-conversion - The expression converted has a non-zero floating<br>
point value that gets converted to a zero integer value, excluded the cases<br>
falling under -Wliteral-conversion.  Subset of -Wfloat-conversion.<br>
int x = 1.0 / 2.0;<br></blockquote><div><br></div></span><div>This ^ seems like a slightly odd special case. Why is it particularly beneficial to have that slice separate from, say, 3.0/2.0 ?</div></div></div></div></blockquote><div><br></div><div>I was seeing things such as sleep(.5), where sleep takes an int of seconds, or error_rate = .001 where the intention was for a small non-zero value to be used and there was a large jump between meanings of non-zero value and zero values.   For non-zero to non-zero conversion, the change in meaning is smaller, and usually intentional.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">-Wfloat-overflow-conversion - The floating point value is outside the range<br>
of the integer type, exluding cases from -Wliteral conversion.  Subset of<br>
-Wfloat-conversion.<br>
char x = 500;<br>
char x = -1000;<br>
<br>
-Wfloat-bool-conversion - Any conversion of a floating point type to bool.<br>
Subset of -Wfloat-conversion.<br>
if (GetFloat()) {}<br>
bool x = 5.0; </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
-Wfloat-bool-constant-conversion - Conversion of a compile time evaluatable<br>
floating point value to bool.  Subset of -Wfloat-bool-conversion.<br>
bool x = 1.0;<br>
bool x = 4.0 / 20.0;<br></blockquote><div><br></div></span><div>Why this particular slice? Are there cases where literal floats converted to bool are desirable that you're carving out by having this (& the float-overflow-conversion, float-zero-conversion, etc) split out?</div></div></div></div></blockquote><div>Float to bool conversion is being reverted for the time being. </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Also add EvaluateAsFloat to Sema, which is similar to EvaluateAsInt, but for<br>
floating point values.<br>
<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/Expr.h<br>
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/AST/ExprConstant.cpp<br>
    cfe/trunk/lib/Sema/SemaChecking.cpp<br>
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp<br>
    cfe/trunk/test/SemaCXX/warn-float-conversion.cpp<br>
    cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/Expr.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=267054&r1=267053&r2=267054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=267054&r1=267053&r2=267054&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/Expr.h (original)<br>
+++ cfe/trunk/include/clang/AST/Expr.h Thu Apr 21 16:04:55 2016<br>
@@ -594,6 +594,13 @@ public:<br>
   bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,<br>
                      SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;<br>
<br>
+  /// EvaluateAsFloat - Return true if this is a constant which we can fold and<br>
+  /// convert to a floating point value, using any crazy technique that we<br>
+  /// want to.<br>
+  bool<br>
+  EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx,<br>
+                  SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;<br>
+<br>
   /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be<br>
   /// constant folded without side-effects, but discard the result.<br>
   bool isEvaluatable(const ASTContext &Ctx,<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=267054&r1=267053&r2=267054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=267054&r1=267053&r2=267054&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Thu Apr 21 16:04:55 2016<br>
@@ -46,7 +46,17 @@ def BoolConversion : DiagGroup<"bool-con<br>
                                                    UndefinedBoolConversion]>;<br>
 def IntConversion : DiagGroup<"int-conversion">;<br>
 def EnumConversion : DiagGroup<"enum-conversion">;<br>
-def FloatConversion : DiagGroup<"float-conversion">;<br>
+<br>
+def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">;<br>
+def FloatZeroConversion : DiagGroup<"float-zero-conversion">;<br>
+def FloatBoolConstantConversion : DiagGroup<"float-bool-constant-conversion">;<br>
+def FloatBoolConversion :<br>
+  DiagGroup<"float-bool-conversion", [FloatBoolConstantConversion]>;<br>
+def FloatConversion :<br>
+  DiagGroup<"float-conversion", [FloatBoolConversion,<br>
+                                 FloatOverflowConversion,<br>
+                                 FloatZeroConversion]>;<br>
+<br>
 def DoublePromotion : DiagGroup<"double-promotion">;<br>
 def EnumTooLarge : DiagGroup<"enum-too-large">;<br>
 def UnsupportedNan : DiagGroup<"unsupported-nan">;<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=267054&r1=267053&r2=267054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=267054&r1=267053&r2=267054&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Apr 21 16:04:55 2016<br>
@@ -2742,9 +2742,6 @@ def warn_impcast_float_precision : Warni<br>
 def warn_impcast_double_promotion : Warning<<br>
   "implicit conversion increases floating-point precision: %0 to %1">,<br>
   InGroup<DoublePromotion>, DefaultIgnore;<br>
-def warn_impcast_float_integer : Warning<<br>
-  "implicit conversion turns floating-point number into integer: %0 to %1">,<br>
-  InGroup<FloatConversion>, DefaultIgnore;<br>
 def warn_impcast_integer_sign : Warning<<br>
   "implicit conversion changes signedness: %0 to %1">,<br>
   InGroup<SignConversion>, DefaultIgnore;<br>
@@ -2763,9 +2760,29 @@ def warn_impcast_integer_precision_const<br>
 def warn_impcast_bitfield_precision_constant : Warning<<br>
   "implicit truncation from %2 to bitfield changes value from %0 to %1">,<br>
   InGroup<BitFieldConstantConversion>;<br>
+<br>
 def warn_impcast_literal_float_to_integer : Warning<<br>
   "implicit conversion from %0 to %1 changes value from %2 to %3">,<br>
   InGroup<LiteralConversion>;<br>
+def warn_impcast_float_integer : Warning<<br>
+  "implicit conversion turns floating-point number into integer: %0 to %1">,<br>
+  InGroup<FloatConversion>, DefaultIgnore;<br>
+<br>
+def warn_impcast_float_bool : Warning<<br>
+  "implicit conversion turns floating-point number into boolean: %0 to %1">,<br>
+  InGroup<FloatBoolConversion>, DefaultIgnore;<br>
+def warn_impcast_float_to_bool : Warning<<br>
+  "implicit conversion from %0 to %1 changes value from %2 to %3">,<br>
+  InGroup<FloatBoolConstantConversion>;<br>
+<br>
+def warn_impcast_float_to_integer : Warning<<br>
+  "implicit conversion of out of range value from %0 to %1 changes value "<br>
+  "from %2 to %3">,<br>
+  InGroup<FloatOverflowConversion>, DefaultIgnore;<br>
+def warn_impcast_float_to_integer_zero : Warning<<br>
+  "implicit conversion from %0 to %1 changes non-zero value from %2 to %3">,<br>
+  InGroup<FloatZeroConversion>, DefaultIgnore;<br>
+<br>
 def warn_impcast_string_literal_to_bool : Warning<<br>
   "implicit conversion turns string literal into bool: %0 to %1">,<br>
   InGroup<StringConversion>, DefaultIgnore;<br>
<br>
Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=267054&r1=267053&r2=267054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=267054&r1=267053&r2=267054&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Apr 21 16:04:55 2016<br>
@@ -9027,6 +9027,20 @@ bool Expr::EvaluateAsInt(APSInt &Result,<br>
   return true;<br>
 }<br>
<br>
+bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx,<br>
+                           SideEffectsKind AllowSideEffects) const {<br>
+  if (!getType()->isRealFloatingType())<br>
+    return false;<br>
+<br>
+  EvalResult ExprResult;<br>
+  if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isFloat() ||<br>
+      hasUnacceptableSideEffect(ExprResult, AllowSideEffects))<br>
+    return false;<br>
+<br>
+  Result = ExprResult.Val.getFloat();<br>
+  return true;<br>
+}<br>
+<br>
 bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const {<br>
   EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=267054&r1=267053&r2=267054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=267054&r1=267053&r2=267054&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Thu Apr 21 16:04:55 2016<br>
@@ -7382,19 +7382,78 @@ void DiagnoseImpCast(Sema &S, Expr *E, Q<br>
   DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow);<br>
 }<br>
<br>
-/// Diagnose an implicit cast from a literal expression. Does not warn when the<br>
-/// cast wouldn't lose information.<br>
-void DiagnoseFloatingLiteralImpCast(Sema &S, FloatingLiteral *FL, QualType T,<br>
-                                    SourceLocation CContext) {<br>
-  // Try to convert the literal exactly to an integer. If we can, don't warn.<br>
+<br>
+/// Diagnose an implicit cast from a floating point value to an integer value.<br>
+void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,<br>
+<br>
+                             SourceLocation CContext) {<br>
+  const bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);<br>
+  const bool PruneWarnings = !S.ActiveTemplateInstantiations.empty();<br>
+<br>
+  Expr *InnerE = E->IgnoreParenImpCasts();<br>
+  // We also want to warn on, e.g., "int i = -1.234"<br>
+  if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(InnerE))<br>
+    if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)<br>
+      InnerE = UOp->getSubExpr()->IgnoreParenImpCasts();<br>
+<br>
+  const bool IsLiteral =<br>
+      isa<FloatingLiteral>(E) || isa<FloatingLiteral>(InnerE);<br>
+<br>
+  llvm::APFloat Value(0.0);<br>
+  bool IsConstant =<br>
+    E->EvaluateAsFloat(Value, S.Context, Expr::SE_AllowSideEffects);<br>
+  if (!IsConstant) {<br>
+    if (IsBool) {<br>
+      return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_bool,<br>
+                             PruneWarnings);<br>
+    } else {<br>
+      return DiagnoseImpCast(S, E, T, CContext,<br>
+                             diag::warn_impcast_float_integer, PruneWarnings);<br>
+    }<br>
+  }<br>
+<br>
   bool isExact = false;<br>
-  const llvm::APFloat &Value = FL->getValue();<br>
+<br>
   llvm::APSInt IntegerValue(S.Context.getIntWidth(T),<br>
                             T->hasUnsignedIntegerRepresentation());<br>
-  if (Value.convertToInteger(IntegerValue,<br>
-                             llvm::APFloat::rmTowardZero, &isExact)<br>
-      == llvm::APFloat::opOK && isExact)<br>
-    return;<br>
+  if (Value.convertToInteger(IntegerValue, llvm::APFloat::rmTowardZero,<br>
+                             &isExact) == llvm::APFloat::opOK &&<br>
+      isExact && !IsBool) {<br>
+    if (IsLiteral) return;<br>
+    return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,<br>
+                           PruneWarnings);<br>
+  }<br>
+<br>
+  unsigned DiagID = 0;<br>
+  if (IsBool) {<br>
+    // Warn on all floating point to bool conversions<br>
+    DiagID = diag::warn_impcast_float_to_bool;<br>
+  } else if (IsLiteral) {<br>
+    // Warn on floating point literal to integer.<br>
+    DiagID = diag::warn_impcast_literal_float_to_integer;<br>
+  } else if (IntegerValue == 0) {<br>
+    if (Value.isZero()) {  // Skip -0.0 to 0 conversion.<br>
+      return DiagnoseImpCast(S, E, T, CContext,<br>
+                             diag::warn_impcast_float_integer, PruneWarnings);<br>
+    }<br>
+    // Warn on non-zero to zero conversion.<br>
+    DiagID = diag::warn_impcast_float_to_integer_zero;<br>
+  } else {<br>
+    if (IntegerValue.isUnsigned()) {<br>
+      if (!IntegerValue.isMaxValue()) {<br>
+        return DiagnoseImpCast(S, E, T, CContext,<br>
+                               diag::warn_impcast_float_integer, PruneWarnings);<br>
+      }<br>
+    } else {  // IntegerValue.isSigned()<br>
+      if (!IntegerValue.isMaxSignedValue() &&<br>
+          !IntegerValue.isMinSignedValue()) {<br>
+        return DiagnoseImpCast(S, E, T, CContext,<br>
+                               diag::warn_impcast_float_integer, PruneWarnings);<br>
+      }<br>
+    }<br>
+    // Warn on evaluatable floating point expression to integer conversion.<br>
+    DiagID = diag::warn_impcast_float_to_integer;<br>
+  }<br>
<br>
   // FIXME: Force the precision of the source value down so we don't print<br>
   // digits which are usually useless (we don't really care here if we<br>
@@ -7407,14 +7466,22 @@ void DiagnoseFloatingLiteralImpCast(Sema<br>
   Value.toString(PrettySourceValue, precision);<br>
<br>
   SmallString<16> PrettyTargetValue;<br>
-  if (T->isSpecificBuiltinType(BuiltinType::Bool))<br>
+  if (IsBool)<br>
     PrettyTargetValue = Value.isZero() ? "false" : "true";<br>
   else<br>
     IntegerValue.toString(PrettyTargetValue);<br>
<br>
-  S.Diag(FL->getExprLoc(), diag::warn_impcast_literal_float_to_integer)<br>
-    << FL->getType() << T.getUnqualifiedType() << PrettySourceValue<br>
-    << PrettyTargetValue << FL->getSourceRange() << SourceRange(CContext);<br>
+  if (PruneWarnings) {<br>
+    S.DiagRuntimeBehavior(E->getExprLoc(), E,<br>
+                          S.PDiag(DiagID)<br>
+                              << E->getType() << T.getUnqualifiedType()<br>
+                              << PrettySourceValue << PrettyTargetValue<br>
+                              << E->getSourceRange() << SourceRange(CContext));<br>
+  } else {<br>
+    S.Diag(E->getExprLoc(), DiagID)<br>
+        << E->getType() << T.getUnqualifiedType() << PrettySourceValue<br>
+        << PrettyTargetValue << E->getSourceRange() << SourceRange(CContext);<br>
+  }<br>
 }<br>
<br>
 std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) {<br>
@@ -7748,22 +7815,12 @@ void CheckImplicitConversion(Sema &S, Ex<br>
       return;<br>
     }<br>
<br>
-    // If the target is integral, always warn.<br>
+    // If the target is integral, always warn.<br>
     if (TargetBT && TargetBT->isInteger()) {<br>
       if (S.SourceMgr.isInSystemMacro(CC))<br>
         return;<br>
-<br>
-      Expr *InnerE = E->IgnoreParenImpCasts();<br>
-      // We also want to warn on, e.g., "int i = -1.234"<br>
-      if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(InnerE))<br>
-        if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)<br>
-          InnerE = UOp->getSubExpr()->IgnoreParenImpCasts();<br>
-<br>
-      if (FloatingLiteral *FL = dyn_cast<FloatingLiteral>(InnerE)) {<br>
-        DiagnoseFloatingLiteralImpCast(S, FL, T, CC);<br>
-      } else {<br>
-        DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_integer);<br>
-      }<br>
+<br>
+      DiagnoseFloatingImpCast(S, E, T, CC);<br>
     }<br>
<br>
     // Detect the case where a call result is converted from floating-point to<br>
<br>
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp?rev=267054&r1=267053&r2=267054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp?rev=267054&r1=267053&r2=267054&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp (original)<br>
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp Thu Apr 21 16:04:55 2016<br>
@@ -58,8 +58,8 @@ void float_to_int() {<br>
   Agg<char> ce1 = { Convert<float>(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}}<br>
   Agg<char> ce2 = { ConvertVar<double>() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{silence}}<br>
<br>
-  bool b{1.0}; // expected-error {{type 'double' cannot be narrowed to 'bool'}} expected-note {{silence}}<br>
-  Agg<bool> ab = {0.0}; // expected-error {{type 'double' cannot be narrowed to 'bool'}} expected-note {{silence}}<br>
+  bool b{1.0}; // expected-error {{type 'double' cannot be narrowed to 'bool'}} expected-note {{silence}} expected-warning {{changes value}}<br>
+  Agg<bool> ab = {0.0}; // expected-error {{type 'double' cannot be narrowed to 'bool'}} expected-note {{silence}} expected-warning {{changes value}}<br>
 }<br>
<br>
 // * from long double to double or float, or from double to float, except where<br>
<br>
Modified: cfe/trunk/test/SemaCXX/warn-float-conversion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-float-conversion.cpp?rev=267054&r1=267053&r2=267054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-float-conversion.cpp?rev=267054&r1=267053&r2=267054&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/warn-float-conversion.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/warn-float-conversion.cpp Thu Apr 21 16:04:55 2016<br>
@@ -1,5 +1,12 @@<br>
-// RUN: %clang_cc1 -verify -fsyntax-only %s -Wfloat-conversion<br>
+// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-literal-conversion -Wfloat-conversion -DFLOAT_CONVERSION -DZERO -DBOOL -DCONSTANT_BOOL -DOVERFLOW<br>
+// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-conversion -Wfloat-overflow-conversion -DOVERFLOW<br>
+// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-conversion -Wfloat-zero-conversion -DZERO<br>
+// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-conversion -Wfloat-bool-constant-conversion -DCONSTANT_BOOL<br>
+// RUN: %clang_cc1 -verify -fsyntax-only -triple x86_64-pc-linux-gnu %s -Wno-conversion -Wfloat-bool-conversion -DCONSTANT_BOOL -DBOOL<br>
<br>
+float ReturnFloat();<br>
+<br>
+#ifdef FLOAT_CONVERSION<br>
 bool ReturnBool(float f) {<br>
   return f;  //expected-warning{{conversion}}<br>
 }<br>
@@ -36,3 +43,80 @@ void Convert(float f, double d, long dou<br>
   l = ld;  //expected-warning{{conversion}}<br>
 }<br>
<br>
+void Test() {<br>
+  int a1 = 10.0/2.0;  //expected-warning{{conversion}}<br>
+  int a2 = 1.0/2.0;  //expected-warning{{conversion}}<br>
+  bool a3 = ReturnFloat();  //expected-warning{{conversion}}<br>
+  int a4 = 1e30 + 1;  //expected-warning{{conversion}}<br>
+}<br>
+<br>
+void TestConstantFloat() {<br>
+  // Don't warn on exact floating literals.<br>
+  int a1 = 5.0;<br>
+  int a2 = 1e3;<br>
+<br>
+  int a3 = 5.5;  // caught by -Wliteral-conversion<br>
+  int a4 = 500.44;  // caught by -Wliteral-convserion<br>
+<br>
+  int b1 = 5.0 / 1.0;  //expected-warning{{conversion}}<br>
+  int b2 = 5.0 / 2.0;  //expected-warning{{conversion}}<br>
+<br>
+  const float five = 5.0;<br>
+<br>
+  int b3 = five / 1.0;  //expected-warning{{conversion}}<br>
+  int b4 = five / 2.0;  //expected-warning{{conversion}}<br>
+}<br>
+#endif  // FLOAT_CONVERSION<br>
+<br>
+#ifdef CONSTANT_BOOL<br>
+const float pi = 3.1415;<br>
+<br>
+void TestConstantBool() {<br>
+  bool b1 = 0.99f; // expected-warning {{implicit conversion from 'float' to 'bool' changes value from 0.99 to true}}<br>
+  bool b2 = 0.99; // expected-warning {{implicit conversion from 'double' to 'bool' changes value from 0.99 to true}}<br>
+  bool b3 = 0.0f; // expected-warning {{implicit conversion from 'float' to 'bool' changes value from 0 to false}}<br>
+  bool b4 = 0.0; // expected-warning {{implicit conversion from 'double' to 'bool' changes value from 0 to false}}<br>
+  bool b5 = 1.0f; // expected-warning {{implicit conversion from 'float' to 'bool' changes value from 1 to true}}<br>
+  bool b6 = 1.0; // expected-warning {{implicit conversion from 'double' to 'bool' changes value from 1 to true}}<br>
+  bool b7 = pi; // expected-warning {{implicit conversion from 'const float' to 'bool' changes value from 3.1415 to true}}<br>
+  bool b8 = pi - pi; // expected-warning {{implicit conversion from 'float' to 'bool' changes value from 0 to false}}<br>
+}<br>
+#endif  // CONSTANT_BOOL<br>
+<br>
+#ifdef BOOL<br>
+const float E = 2.718;<br>
+<br>
+float GetFloat();<br>
+double GetDouble();<br>
+<br>
+void TestBool() {<br>
+  bool b1 = GetFloat(); // expected-warning {{implicit conversion turns floating-point number into boolean: 'float' to 'bool'}}<br>
+  bool b2 = GetDouble(); // expected-warning {{implicit conversion turns floating-point number into boolean: 'double' to 'bool'}}<br>
+  bool b3 = 0.0 * GetDouble(); // expected-warning {{implicit conversion turns floating-point number into boolean: 'double' to 'bool'}}<br>
+  bool b4 = GetFloat() + GetDouble(); // expected-warning {{implicit conversion turns floating-point number into boolean: 'double' to 'bool'}}<br>
+  bool b5 = E + GetFloat(); // expected-warning {{implicit conversion turns floating-point number into boolean: 'float' to 'bool'}}<br>
+}<br>
+<br>
+#endif  // BOOL<br>
+<br>
+#ifdef ZERO<br>
+void TestZero() {<br>
+  const float half = .5;<br>
+  int a1 = half;  // expected-warning{{implicit conversion from 'const float' to 'int' changes non-zero value from 0.5 to 0}}<br>
+  int a2 = 1.0 / 2.0;  // expected-warning{{implicit conversion from 'double' to 'int' changes non-zero value from 0.5 to 0}}<br>
+  int a3 = 5;<br>
+}<br>
+#endif  // ZERO<br>
+<br>
+#ifdef OVERFLOW<br>
+void TestOverflow() {<br>
+  char a = 500.0;  // caught by -Wliteral-conversion<br>
+  char b = -500.0;  // caught by -Wliteral-conversion<br>
+<br>
+  const float LargeNumber = 1024;<br>
+  char c = LargeNumber;  // expected-warning{{implicit conversion of out of range value from 'const float' to 'char' changes value from 1024 to 127}}<br>
+  char d = 400.0 + 400.0;  // expected-warning{{implicit conversion of out of range value from 'double' to 'char' changes value from 800 to 127}}<br>
+<br>
+  char e = 1.0 / 0.0;  // expected-warning{{implicit conversion of out of range value from 'double' to 'char' changes value from +Inf to 127}}<br>
+}<br>
+#endif  // OVERFLOW<br>
<br>
Modified: cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp?rev=267054&r1=267053&r2=267054&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp?rev=267054&r1=267053&r2=267054&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp Thu Apr 21 16:04:55 2016<br>
@@ -25,7 +25,7 @@ void test0() {<br>
   // Test passing a literal floating-point value to a function that takes an integer.<br>
   foo(1.2F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}}<br>
<br>
-  int y10 = -1.2F;  // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}}<br>
+  int y10 = -1.2F;  // expected-warning {{implicit conversion from 'float' to 'int' changes value from -1.2 to -1}}<br>
<br>
   // -Wliteral-conversion does NOT catch const values.<br>
   // (-Wconversion DOES catch them.)<br>
@@ -38,14 +38,3 @@ void test0() {<br>
   int y = (24*60*60) * 0.25;<br>
   int pennies = 123.45 * 100;<br>
 }<br>
-<br>
-// Similarly, test floating point conversion to bool. Only float values of zero<br>
-// are converted to false; everything else is converted to true.<br>
-void test1() {<br>
-  bool b1 = 0.99f; // expected-warning {{implicit conversion from 'float' to 'bool' changes value from 0.99 to true}}<br>
-  bool b2 = 0.99; // expected-warning {{implicit conversion from 'double' to 'bool' changes value from 0.99 to true}}<br>
-  // These do not warn because they can be directly converted to integral<br>
-  // values.<br>
-  bool b3 = 0.0f;<br>
-  bool b4 = 0.0;<br>
-}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>