[cfe-commits] r129243 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaChecking.cpp test/Sema/knr-def-call.c test/SemaCXX/warn-literal-conversion.cpp

Chandler Carruth chandlerc at gmail.com
Sun Apr 10 01:36:24 PDT 2011


Author: chandlerc
Date: Sun Apr 10 03:36:24 2011
New Revision: 129243

URL: http://llvm.org/viewvc/llvm-project?rev=129243&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/Sema/knr-def-call.c
    cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=129243&r1=129242&r2=129243&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Apr 10 03:36:24 2011
@@ -1194,6 +1194,8 @@
   "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">>;

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=129243&r1=129242&r2=129243&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Sun Apr 10 03:36:24 2011
@@ -2763,6 +2763,38 @@
   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 @@
   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 @@
         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);
       }

Modified: cfe/trunk/test/Sema/knr-def-call.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/knr-def-call.c?rev=129243&r1=129242&r2=129243&view=diff
==============================================================================
--- cfe/trunk/test/Sema/knr-def-call.c (original)
+++ cfe/trunk/test/Sema/knr-def-call.c Sun Apr 10 03:36:24 2011
@@ -36,6 +36,8 @@
 }
 
 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}}
 }

Modified: cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp?rev=129243&r1=129242&r2=129243&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-literal-conversion.cpp Sun Apr 10 03:36:24 2011
@@ -8,13 +8,18 @@
   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}}





More information about the cfe-commits mailing list