mirror of https://github.com/microsoft/clang.git
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
This commit is contained in:
parent
8f674a8052
commit
be0ee875d8
|
@ -1781,8 +1781,7 @@ def warn_impcast_bitfield_precision_constant : Warning<
|
|||
"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">,
|
||||
|
|
|
@ -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 @@ void DiagnoseFloatingLiteralImpCast(Sema &S, FloatingLiteral *FL, QualType T,
|
|||
== 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 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
|||
}
|
||||
}
|
||||
}
|
||||
return; // Other casts to bool are not checked.
|
||||
}
|
||||
|
||||
// Strip vector types.
|
||||
|
@ -4213,7 +4222,7 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
|||
}
|
||||
|
||||
// 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 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
|||
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);
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ int string_literal_init() {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ struct X0 {
|
|||
};
|
||||
|
||||
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}}
|
||||
|
|
|
@ -87,7 +87,7 @@ struct {
|
|||
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
|
||||
|
|
|
@ -50,7 +50,7 @@ void func() {
|
|||
|
||||
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() {
|
||||
|
|
|
@ -36,6 +36,6 @@ void proto(x)
|
|||
}
|
||||
|
||||
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}}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -65,7 +65,7 @@ void test3() {
|
|||
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 @@ namespace test4 {
|
|||
tmpl2<int*>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace test5 {
|
||||
template<int I>
|
||||
void func() {
|
||||
bool b = I;
|
||||
}
|
||||
|
||||
template void func<3>();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -233,7 +233,7 @@ float* intref(const int&);
|
|||
|
||||
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}}
|
||||
|
|
|
@ -5,29 +5,29 @@ void foo(int y);
|
|||
// 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;
|
||||
|
|
|
@ -60,7 +60,7 @@ struct X1 {
|
|||
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue