Improve some of the conversion warnings to fire on conversion to bool.
Moves the bool bail-out down a little in SemaChecking - so now
-Wnull-conversion and -Wliteral-conversion can fire when the target type is
bool.
Also improve the wording/details in the -Wliteral-conversion warning to match
the -Wconstant-conversion.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156826 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 2a34b53..cd2bd27 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1781,8 +1781,7 @@
"implicit truncation from %2 to bitfield changes value from %0 to %1">,
InGroup<ConstantConversion>;
def warn_impcast_literal_float_to_integer : Warning<
- "implicit conversion turns literal floating-point number into integer: "
- "%0 to %1">,
+ "implicit conversion from %0 to %1 changes value from %2 to %3">,
InGroup<LiteralConversion>;
def warn_impcast_string_literal_to_bool : Warning<
"implicit conversion turns string literal into bool: %0 to %1">,
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index eddb612..9c637b8 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/EvaluatedExprVisitor.h"
@@ -4081,8 +4082,17 @@
== llvm::APFloat::opOK && isExact)
return;
+ SmallString<16> PrettySourceValue;
+ Value.toString(PrettySourceValue);
+ std::string PrettyTargetValue;
+ if (T->isSpecificBuiltinType(BuiltinType::Bool))
+ PrettyTargetValue = IntegerValue == 0 ? "false" : "true";
+ else
+ PrettyTargetValue = IntegerValue.toString(10);
+
S.Diag(FL->getExprLoc(), diag::warn_impcast_literal_float_to_integer)
- << FL->getType() << T << FL->getSourceRange() << SourceRange(CContext);
+ << FL->getType() << T.getUnqualifiedType() << PrettySourceValue
+ << PrettyTargetValue << FL->getSourceRange() << SourceRange(CContext);
}
std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) {
@@ -4149,7 +4159,6 @@
}
}
}
- return; // Other casts to bool are not checked.
}
// Strip vector types.
@@ -4213,7 +4222,7 @@
}
// If the target is integral, always warn.
- if ((TargetBT && TargetBT->isInteger())) {
+ if (TargetBT && TargetBT->isInteger()) {
if (S.SourceMgr.isInSystemMacro(CC))
return;
@@ -4247,6 +4256,11 @@
return;
}
+ // TODO: remove this early return once the false positives for constant->bool
+ // in templates, macros, etc, are reduced or removed.
+ if (Target->isSpecificBuiltinType(BuiltinType::Bool))
+ return;
+
IntRange SourceRange = GetExprRange(S.Context, E);
IntRange TargetRange = IntRange::forTargetOfCanonicalType(S.Context, Target);
diff --git a/test/Analysis/array-struct-region.c b/test/Analysis/array-struct-region.c
index 8be8688..18d5b2a 100644
--- a/test/Analysis/array-struct-region.c
+++ b/test/Analysis/array-struct-region.c
@@ -25,8 +25,8 @@
}
void nested_compound_literals(int rad) {
- int vec[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, // expected-warning 6 {{implicit conversion turns literal floating-point number into integer}}
- {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; // expected-warning 6 {{implicit conversion turns literal floating-point number into integer}}
+ int vec[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, // expected-warning 6 {{implicit conversion from 'double' to 'int' changes value from}}
+ {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; // expected-warning 6 {{implicit conversion from 'double' to 'int' changes value from}}
int a;
for (a = 0; a < 6; ++a) {
diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
index ac11940..2646264 100644
--- a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
+++ b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
@@ -4,7 +4,7 @@
bool b = !0;
-bool b2 = !1.2;
+bool b2 = !1.2; //expected-warning{{implicit conversion from 'double' to 'bool' changes value from 1.2 to true}}
bool b3 = !4;
diff --git a/test/CXX/temp/temp.spec/p5.cpp b/test/CXX/temp/temp.spec/p5.cpp
index 0e69a26..ba92d41 100644
--- a/test/CXX/temp/temp.spec/p5.cpp
+++ b/test/CXX/temp/temp.spec/p5.cpp
@@ -14,7 +14,7 @@
};
template<typename T>
-T X0<T>::value = 3.14; // expected-warning{{implicit conversion turns literal floating-point number into integer}}
+T X0<T>::value = 3.14; // expected-warning{{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}}
template struct X0<int>; // expected-note{{previous explicit instantiation}} \
expected-note{{requested here}}
diff --git a/test/PCH/exprs.h b/test/PCH/exprs.h
index 09a5013..d08b1f6 100644
--- a/test/PCH/exprs.h
+++ b/test/PCH/exprs.h
@@ -87,7 +87,7 @@
int x;
float y;
} designated_inits[3] = { [0].y = 17,
- [2].x = 12.3, // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ [2].x = 12.3, // expected-warning {{implicit conversion from 'double' to 'int' changes value from 12.3 to 12}}
3.5 };
// TypesCompatibleExpr
diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c
index 26c0b24..cfdf8e2 100644
--- a/test/Sema/array-init.c
+++ b/test/Sema/array-init.c
@@ -50,7 +50,7 @@
static long x2[3] = { 1.0,
"abc", // expected-warning{{incompatible pointer to integer conversion initializing 'long' with an expression of type 'char [4]'}}
- 5.8 }; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ 5.8 }; // expected-warning {{implicit conversion from 'double' to 'long' changes value from 5.8 to 5}}
}
void test() {
diff --git a/test/Sema/knr-def-call.c b/test/Sema/knr-def-call.c
index f41275d..80ad0d8 100644
--- a/test/Sema/knr-def-call.c
+++ b/test/Sema/knr-def-call.c
@@ -36,6 +36,6 @@
}
void use_proto() {
- proto(42.1); // expected-warning{{implicit conversion turns literal floating-point number into integer}}
- (&proto)(42.1); // expected-warning{{implicit conversion turns literal floating-point number into integer}}
+ proto(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}}
+ (&proto)(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}}
}
diff --git a/test/SemaCXX/bool.cpp b/test/SemaCXX/bool.cpp
index 2b3ab68..f027186 100644
--- a/test/SemaCXX/bool.cpp
+++ b/test/SemaCXX/bool.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-constant-conversion %s
// Bool literals can be enum values.
enum {
diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp
index b019536..4b44bed 100644
--- a/test/SemaCXX/conversion.cpp
+++ b/test/SemaCXX/conversion.cpp
@@ -65,7 +65,7 @@
int c = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
int d;
d = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
- bool bl = NULL; // FIXME: this should warn but we currently suppress a bunch of conversion-to-bool warnings including this one
+ bool bl = NULL; // expected-warning {{implicit conversion of NULL constant to 'bool'}}
char ch = NULL; // expected-warning {{implicit conversion of NULL constant to 'char'}}
unsigned char uch = NULL; // expected-warning {{implicit conversion of NULL constant to 'unsigned char'}}
short sh = NULL; // expected-warning {{implicit conversion of NULL constant to 'short'}}
@@ -104,3 +104,12 @@
tmpl2<int*>();
}
}
+
+namespace test5 {
+ template<int I>
+ void func() {
+ bool b = I;
+ }
+
+ template void func<3>();
+}
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index 355833e..2635fb8 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-constant-conversion %s
void choice(int);
int choice(bool);
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 09eb71d..2b5ebb9 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -233,7 +233,7 @@
void intref_test() {
float* ir1 = intref(5);
- float* ir2 = intref(5.5); // expected-warning{{implicit conversion turns literal floating-point number into integer}}
+ float* ir2 = intref(5.5); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 5.5 to 5}}
}
void derived5(C&); // expected-note{{candidate function not viable: cannot bind base class object of type 'A' to derived class reference 'C &' for 1st argument}}
diff --git a/test/SemaCXX/warn-literal-conversion.cpp b/test/SemaCXX/warn-literal-conversion.cpp
index 5fcae5d..d7bec4c 100644
--- a/test/SemaCXX/warn-literal-conversion.cpp
+++ b/test/SemaCXX/warn-literal-conversion.cpp
@@ -5,29 +5,29 @@
// Warn when a literal float or double is assigned or bound to an integer.
void test0() {
// Float
- int y0 = 1.2222F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y1 = (1.2222F); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y2 = (((1.2222F))); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y3 = 12E-1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y4 = 1.23E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int y0 = 1.2222F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}}
+ int y1 = (1.2222F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}}
+ int y2 = (((1.2222F))); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}}
+ int y3 = 12E-1F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}}
+ int y4 = 1.23E1F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 12.3 to 12}}
// Double
- int y5 = 1.2222; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y6 = 12E-1; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y7 = 1.23E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y8 = (1.23E1); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int y5 = 1.2222; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 1.2222 to 1}}
+ int y6 = 12E-1; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 1.2 to 1}}
+ int y7 = 1.23E1; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 12.3 to 12}}
+ int y8 = (1.23E1); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 12.3 to 12}}
// Test assignment to an existing variable.
- y8 = 2.22F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ y8 = 2.22F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 2.22 to 2}}
// Test direct initialization.
- int y9(1.23F); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int y9(1.23F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.23 to 1}}
// Test passing a literal floating-point value to a function that takes an integer.
- foo(1.2F); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ foo(1.2F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}}
- int y10 = -1.2F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int y10 = -1.2F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}}
- // -Wconversion-literal does NOT catch const values.
+ // -Wliteral-conversion does NOT catch const values.
// (-Wconversion DOES catch them.)
static const float sales_tax_rate = .095F;
int z = sales_tax_rate;
diff --git a/test/SemaTemplate/member-template-access-expr.cpp b/test/SemaTemplate/member-template-access-expr.cpp
index c95b57d..f105ba8 100644
--- a/test/SemaTemplate/member-template-access-expr.cpp
+++ b/test/SemaTemplate/member-template-access-expr.cpp
@@ -60,7 +60,7 @@
void test_X1(X1 x1) {
float *fp1 = x1.f1<>(17);
- float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}}
int *ip1 = x1.f1(17);
float *ip2 = x1.f1(3.14);