<div dir="ltr"><div class="gmail_extra">Nico,</div><div class="gmail_extra"><br></div><div class="gmail_extra">With this warning, I was attempting to catch different cases of floating to bool conversion:</div><div class="gmail_extra"> bool x = 5.0; // Wrong type</div><div class="gmail_extra"> void test(bool, float);</div><div class="gmail_extra"> test(5.0, true); // Switched arguments.</div><div class="gmail_extra"><br></div><div class="gmail_extra">I did not see anything like your example come up. See as there are many edge cases in with floating point to bool conversions, I will be reverting the bool portions of this change and following up with a different thread to discuss how to handle the bool conversions.</div><div class="gmail_extra"><br></div><div class="gmail_extra">-Wfloat-* are subgroups of -Wfloat-conversion which is a subgroup of -Wconversion.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Richard</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Apr 22, 2016 at 7:41 AM, Nico Weber <span dir="ltr"><<a href="mailto:thakis@chromium.org" target="_blank">thakis@chromium.org</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">Hi Richard,<div><br></div><div>1.) Are these new warnings in -Wconversion? If not, they probably should be, right?</div><div><br></div><div>2.) It looks like -Wfloat-bool-constant-conversion is on by default and warns on things like</div><div><br></div><div><div> if (kHotspotRadius)</div></div><div><br></div><div>if kHotspotRadius is a float. Do you have data that suggests that this is a common buggy pattern? Omitting `!= 0` is extremely common in practice, and it's even dictated in some style guides (e.g. <a href="https://webkit.org/code-style-guidelines/#null-false-and-zero" target="_blank">https://webkit.org/code-style-guidelines/#null-false-and-zero</a> ("Tests for [...] zero/non-zero should all be done without equality comparisons."). So making this a warning for floats but not for others seems weird to me.</div><span><font color="#888888"><div><br></div><div>Nico</div><div><br></div></font></span></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 21, 2016 at 5: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>
<br>
-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;<br>
<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>
<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><br></div>
</div></div></blockquote></div><br></div></div>