[cfe-commits] r39400 - in /cfe/cfe/trunk: Lex/PPExpressions.cpp include/clang/Basic/DiagnosticKinds.def

clattner at cs.uiuc.edu clattner at cs.uiuc.edu
Wed Jul 11 09:43:59 PDT 2007


Author: clattner
Date: Wed Jul 11 11:43:59 2007
New Revision: 39400

URL: http://llvm.org/viewvc/llvm-project?rev=39400&view=rev
Log:
Track overflow of shift amounts, allowing diagnostics like:

t.c:6:7: warning: integer overflow in preprocessor expression
#if 1 << 63
      ^
t.c:8:7: warning: integer overflow in preprocessor expression
#if 4 << 62
      ^
t.c:10:7: warning: integer overflow in preprocessor expression
#if 4 << 66
      ^

but no diagnostic on:
#if 1U << 63

Modified:
    cfe/cfe/trunk/Lex/PPExpressions.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/cfe/trunk/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/PPExpressions.cpp?rev=39400&r1=39399&r2=39400&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/PPExpressions.cpp (original)
+++ cfe/cfe/trunk/Lex/PPExpressions.cpp Wed Jul 11 11:43:59 2007
@@ -421,6 +421,7 @@
     }
     
     // FIXME: All of these should detect and report overflow??
+    bool Overflow = false;
     switch (Operator) {
     default: assert(0 && "Unknown operator token!");
     case tok::percent:
@@ -440,16 +441,29 @@
     case tok::star:
       LHS *= RHS;
       break;
-    case tok::lessless:
-      // FIXME: shift amt overflow?
-      // FIXME: Don't use getZExtValue.
-      LHS <<= RHS.getZExtValue();
-      break;
-    case tok::greatergreater:
-      // FIXME: signed vs unsigned
-      // FIXME: Don't use getZExtValue.
-      LHS >>= RHS.getZExtValue();
+    case tok::lessless: {
+      // Determine whether overflow is about to happen.
+      unsigned ShAmt = RHS.getLimitedValue();
+      if (ShAmt >= LHS.getBitWidth())
+        Overflow = true, ShAmt = LHS.getBitWidth()-1;
+      else if (LHS.isUnsigned())
+        Overflow = ShAmt > LHS.countLeadingZeros();
+      else if (LHS.isPositive())
+        Overflow = ShAmt >= LHS.countLeadingZeros(); // Don't allow sign change.
+      else
+        Overflow = ShAmt >= LHS.countLeadingOnes();
+      
+      LHS <<= ShAmt;
+      break;
+    }
+    case tok::greatergreater: {
+      // Determine whether overflow is about to happen.
+      unsigned ShAmt = RHS.getLimitedValue();
+      if (ShAmt >= LHS.getBitWidth())
+        Overflow = true, ShAmt = LHS.getBitWidth()-1;
+      LHS >>= ShAmt;
       break;
+    }
     case tok::plus:
       LHS += RHS;
       break;
@@ -532,6 +546,10 @@
       PP.Diag(OpToken, diag::err_pp_colon_without_question);
       return true;
     }
+
+    // If this operator is live and overflowed, report the issue.
+    if (Overflow && ValueLive)
+      PP.Diag(OpToken, diag::warn_pp_expr_overflow);
   }
   
   return false;

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39400&r1=39399&r2=39400&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:59 2007
@@ -114,6 +114,8 @@
      "macro is not used")
 DIAG(pp_invalid_string_literal, WARNING,
      "invalid string literal, ignoring final '\\'")
+DIAG(warn_pp_expr_overflow, WARNING,
+     "integer overflow in preprocessor expression")
 
 DIAG(ext_pp_import_directive, EXTENSION,
      "#import is a language extension")





More information about the cfe-commits mailing list