mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-01 01:31:26 +00:00
Enhance the diagnostic for literal float -> int conversions to suggest
rewriting the literal when the value is integral. It is not uncommon to see code written as: const int kBigNumber = 42e5; Without any real awareness that this is no longer an ICE. The note helps automate and ease the process of fixing code that violates the warning. llvm-svn: 129243
This commit is contained in:
parent
8cb243a78f
commit
016ef400c4
@ -1194,6 +1194,8 @@ def warn_impcast_literal_float_to_integer : Warning<
|
||||
"implicit conversion turns literal floating-point number into integer: "
|
||||
"%0 to %1">,
|
||||
InGroup<DiagGroup<"literal-conversion">>, DefaultIgnore;
|
||||
def note_fix_integral_float_as_integer : Note<
|
||||
"this can be rewritten as an integer literal with the exact same value">;
|
||||
def warn_impcast_different_enum_types : Warning<
|
||||
"implicit conversion from enumeration type %0 to different enumeration type "
|
||||
"%1">, InGroup<DiagGroup<"conversion">>;
|
||||
|
@ -2763,6 +2763,38 @@ void DiagnoseImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext,
|
||||
DiagnoseImpCast(S, E, E->getType(), T, CContext, diag);
|
||||
}
|
||||
|
||||
/// Diagnose an implicit cast from a literal expression. Also attemps to supply
|
||||
/// fixit hints when the cast wouldn't lose information to simply write the
|
||||
/// expression with the expected type.
|
||||
void DiagnoseFloatingLiteralImpCast(Sema &S, FloatingLiteral *FL, QualType T,
|
||||
SourceLocation CContext) {
|
||||
// Emit the primary warning first, then try to emit a fixit hint note if
|
||||
// reasonable.
|
||||
S.Diag(FL->getExprLoc(), diag::warn_impcast_literal_float_to_integer)
|
||||
<< FL->getType() << T << FL->getSourceRange() << SourceRange(CContext);
|
||||
|
||||
const llvm::APFloat &Value = FL->getValue();
|
||||
|
||||
// Don't attempt to fix PPC double double literals.
|
||||
if (&Value.getSemantics() == &llvm::APFloat::PPCDoubleDouble)
|
||||
return;
|
||||
|
||||
// Try to convert this exactly to an 64-bit integer. FIXME: It would be
|
||||
// nice to support arbitrarily large integers here.
|
||||
bool isExact = false;
|
||||
uint64_t IntegerPart;
|
||||
if (Value.convertToInteger(&IntegerPart, 64, /*isSigned=*/true,
|
||||
llvm::APFloat::rmTowardZero, &isExact)
|
||||
!= llvm::APFloat::opOK || !isExact)
|
||||
return;
|
||||
|
||||
llvm::APInt IntegerValue(64, IntegerPart, /*isSigned=*/true);
|
||||
|
||||
std::string LiteralValue = IntegerValue.toString(10, /*isSigned=*/true);
|
||||
S.Diag(FL->getExprLoc(), diag::note_fix_integral_float_as_integer)
|
||||
<< FixItHint::CreateReplacement(FL->getSourceRange(), LiteralValue);
|
||||
}
|
||||
|
||||
std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) {
|
||||
if (!Range.Width) return "0";
|
||||
|
||||
@ -2776,7 +2808,7 @@ static bool isFromSystemMacro(Sema &S, SourceLocation loc) {
|
||||
SourceManager &smgr = S.Context.getSourceManager();
|
||||
return loc.isMacroID() && smgr.isInSystemHeader(smgr.getSpellingLoc(loc));
|
||||
}
|
||||
|
||||
|
||||
void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
||||
SourceLocation CC, bool *ICContext = 0) {
|
||||
if (E->isTypeDependent() || E->isValueDependent()) return;
|
||||
@ -2859,9 +2891,8 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
||||
return;
|
||||
|
||||
Expr *InnerE = E->IgnoreParenImpCasts();
|
||||
if (FloatingLiteral *LiteralExpr = dyn_cast<FloatingLiteral>(InnerE)) {
|
||||
DiagnoseImpCast(S, LiteralExpr, T, CC,
|
||||
diag::warn_impcast_literal_float_to_integer);
|
||||
if (FloatingLiteral *FL = dyn_cast<FloatingLiteral>(InnerE)) {
|
||||
DiagnoseFloatingLiteralImpCast(S, FL, T, CC);
|
||||
} else {
|
||||
DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_integer);
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ void proto(x)
|
||||
}
|
||||
|
||||
void use_proto() {
|
||||
proto(42.0); // expected-warning{{implicit conversion turns literal floating-point number into integer}}
|
||||
(&proto)(42.0); // expected-warning{{implicit conversion turns literal floating-point number into integer}}
|
||||
proto(42.0); // expected-warning{{implicit conversion turns literal floating-point number into integer}} \
|
||||
// expected-note {{this can be rewritten as an integer literal with the exact same value}}
|
||||
(&proto)(42.0); // expected-warning{{implicit conversion turns literal floating-point number into integer}} \
|
||||
// expected-note {{this can be rewritten as an integer literal with the exact same value}}
|
||||
}
|
||||
|
@ -8,13 +8,18 @@ void test0() {
|
||||
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 = 12E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
|
||||
int y4 = 1.2E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
|
||||
int y3 = 12E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
|
||||
// expected-note {{this can be rewritten as an integer literal with the exact same value}}
|
||||
int y4 = 1.2E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
|
||||
// expected-note {{this can be rewritten as an integer literal with the exact same value}}
|
||||
// Double
|
||||
int y5 = 1.2222; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
|
||||
int y6 = 12E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
|
||||
int y7 = 1.2E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
|
||||
int y8 = (1.2E1); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
|
||||
int y6 = 12E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
|
||||
// expected-note {{this can be rewritten as an integer literal with the exact same value}}
|
||||
int y7 = 1.2E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
|
||||
// expected-note {{this can be rewritten as an integer literal with the exact same value}}
|
||||
int y8 = (1.2E1); // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
|
||||
// expected-note {{this can be rewritten as an integer literal with the exact same value}}
|
||||
|
||||
// Test assignment to an existing variable.
|
||||
y8 = 2.22F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
|
||||
|
Loading…
Reference in New Issue
Block a user